Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SHIRO-290] Implement BCrypt (and possibly other unix crypt formats like scrypt) #273

Closed
wants to merge 11 commits into from
Closed

Conversation

bmarwell
Copy link
Contributor

@bmarwell bmarwell commented Dec 31, 2020

  • Create AbstractCryptClass for Unix-Crypt-based algorithms (e.g. bcrypt, script, argon2)
  • Move some of the password matching logic into the Hash classes
    Reviwers: Review method placement and HAsh class description.
  • removed hashrequest
  • API change: made salt not-nullable.
    Additional constructor is supplied for hashing without or with
    default salt, the former and other methods/fields using
    SimpleByteSource.empty().
    Reviewers: Pay attention to method logic, so no empty salt is
    being used where a former null value would have created a
    new, random salt.
  • Modified tests to not expect exceptions in certain cases.
  • Modified tests to not expect passwordService calls when supplying an
    existing hash.
  • Fix Javadocs
  • Fix Hasher utility
  • Add Argon2 algorithms
  • Deprecate old non-KDF hash classes
  • Also print warnings when encountering the old hashes
  • What should getBytes() return? There is no overridden Javadoc. Currently, only the hashed data is returned, but maybe it was meant to also return the hash here? If not, why even implement CodecSupport? This needs to be clarified before merging.
    => This is more important if we want to retain Hex and Base64 formats. They need all parameters encoded.
  • BCrypt iterations vs cost: What do we return for getIterations()? Currently I return the cost. But we could also return the real iterations (which is 2^cost) it that made sense.
  • How to store argon2 parameters in Shiro1CryptFormat? Maybe create a Shiro2 CryptFormat?
    Argon2 outputs this: $argon2i$v=19$m=65536,t=2,p=4$c29tZXNhbHQ$RdescudvJCsgt3ub+b+dWRWJTmaaJObG.
    The Shiro1 crypt format only has: prefix(shiro1), algo, iterationcount, salt, hash.
    We would also need version and parameters or so, which could be empty for others.
    The current working copy uses a comma separated list for the iterationCount field, but I am not happy with that.
  • Shiro2CryptFormat (see comment above)?
  • revert Shiro1CryptFormat modifications?
  • Can we drop Hex and Base64 Formats? => Can be done in another PR.
  • Add more tests for bcrypt and argon2.
  • Tune Argon2 default parameters. Target computation time on servers: ~ 0.1s as per RFC recommendation.
  • Add scrypt. It is better than bcrypt. => Another PR.
  • What does DefaultPasswordService.testStringComparisonWhenNotUsingAParsableHashFormat actually test? It only works if specific parameters are set.

API Changes

  • Changed default DefaultPasswordService.java algorithm to "Argon2id".
  • PasswordService.encryptPassword(Object plaintext) will now throw
    a NullPointerException on null parameter. It was never specified how this method would behave.
  • made salt not-nullable.

Following this checklist to help us incorporate your contribution quickly and easily:

  • Make sure there is a JIRA issue filed
    for the change (usually before you start working on it). Trivial changes like typos do not
    require a JIRA issue. Your pull request should address just this issue, without pulling in other changes.
  • Each commit in the pull request should have a meaningful subject line and body.
  • Format the pull request title like [SHIRO-XXX] - Fixes bug in SessionManager,
    where you replace SHIRO-XXX with the appropriate JIRA issue. Best practice
    is to use the JIRA issue title in the pull request title and in the first line of the commit message.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Run mvn clean install apache-rat:check to make sure basic checks pass. A more thorough check will be performed on your pull request automatically.
  • If you have a group of commits related to the same change, please squash your commits into one and force push your branch using git rebase -i.

Trivial changes like typos do not require a JIRA issue (javadoc, comments...).
In this case, just format the pull request title like (DOC) - Add javadoc in SessionManager.

If this is your first contribution, you have to read the Contribution Guidelines

If your pull request is about ~20 lines of code you don't need to sign an Individual Contributor License Agreement
if you are unsure please ask on the developers list.

To make clear that you license your contribution under the Apache License Version 2.0, January 2004
you have to acknowledge this by using the following check-box.

Copy link
Member

@fpapon fpapon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bmarwell we could add @SInCE 2.0 to the new classes.

@bmarwell
Copy link
Contributor Author

bmarwell commented Jan 7, 2021

About HexFormat and Base64Format:

HexFormat.java
HashFormat that outputs only The hash's digest bytes in hex format. It does not print out anything else (salt, iterations, etc). This implementation is mostly provided as a convenience for command-line hashing.

and

Base64Format.java
HashFormat that outputs only the hash's digest bytes in Base64 format. It does not print out anything else (salt, iterations, etc). This implementation is mostly provided as a convenience for command-line hashing.

my +1 for dropping them:

  1. for 2.0.0 mark them as deprecated and log warnings when being used.
  2. for 2.1.0 throw exceptions when being used
  3. for 2.2.0 complete removal

core/pom.xml Outdated Show resolved Hide resolved
crypto/support/pom.xml Outdated Show resolved Hide resolved
  - TBD: HashRequest
  - TBD: PasswortMatcher doesn’t know about the new hash format yet
  - Hashes can now compare themselves to a given password.
    Reviwers: Review method placement and HAsh class description.
  - removed hashrequest
  - removed UnixCryptFormat
  - API change: made salt not-nullable.
    Additional constructor is supplied for hashing without or with
    default salt, the former and other methods/fields using
    SimpleByteSource.empty().
    Reviewers: Pay attention to method logic, so no empty salt is
    being used where a former `null` value would have created a
    new, random salt.
  - Modified tests to not expect exceptions in certain cases.
  - Modified tests to not expect passwordService calls when supplying an
    existing hash.
  - TBD: Fix Javadocs
  - TBD: Fix Hasher utility
  - TBD: Deprecate old non-KDF hash classes
 - BCrypt iterations vs cost: make iterations return iterations
 - add validate methods
 - expand iterations field to take a comma separated list. Maybe just create a Shiro2CryptFormat instead?
 - Hex and Base64 formats are not fixed. Maybe we can drop them?
 - Fixed parameter "algorithm name" not taken into account for bcrypt.
 - Allow Hasher to read from stdin
 - Added a short test for Hasher.java.
 - Changed default DefaultPasswordService.java algorithm to "Argon2id".
 - Only fields 1 and two are defined, rest is defined by the hash implementation
 - Therefore fully backwards-compatible to Shiro1CryptFormat.java.
 - Loads formats from ProvidedKdfHashes.java.
   We could also think of a pluggable mechanism, like using service loaders to hide classes
   like OpenBSDBase64.
 - In AbstractCryptHash.java, renamed `version` to `algorithmName`.
 - Removed iterations from AbstractCryptHash.java, they are possibly an implementation detail not
   present in other implementations (like bcrypt).
 - Signature change: `PasswordService.encryptPassword(Object plaintext)` will now throw
   a NullPointerException on `null` parameter. It was never specified how this method would behave.
 - fix invalid cost factor for bcrypt when input is 0.
 - output Hasher messages using slf4j.
  - Move BCrypt and Argon2 into their own modules
  - Add a SPI
  - Remove hardcoded parameters, replace with ParameterMap for the hashRequest
 - remove at least MD2, MD5 and Sha1
 - Remove unused support-hashes module
 - changed group and artifact-ids for new modules
 - fixed compilation issue in Hasher (needs more work though)
 - add "since 2.0" comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants