-
Notifications
You must be signed in to change notification settings - Fork 635
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
V2 SHA and MD5 crypto providers #698
Conversation
…iginal SHA512 crypto provider by digesting bytes instead of hex string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great start, thanks Andrew.
My only major question at this point is about naming, because we only get one chance to get it right. CryptoProviders::MD5::V2
is a possible alternative.
- Having the version number after the name is closer to normal thought. For example, no one says "v6 rails", we say "rails v6".
- Also, what if we need a
MD5::V3
in the future, but don't need aV3
of anything else? It feels awkward to have aV3
folder with only one thing in it.
Neither of these points is very strong on their own. What do you think?
I think we should also discuss having the V2
classes inherit from V1
.
class MD5
class V2 < MD5
def encrypt
By drastically reducing duplication, we make it much easier for someone reading the code to compare v1 and v2.
lib/authlogic/crypto_providers.rb
Outdated
@@ -30,6 +30,15 @@ module CryptoProviders | |||
autoload :BCrypt, "authlogic/crypto_providers/bcrypt" | |||
autoload :SCrypt, "authlogic/crypto_providers/scrypt" | |||
|
|||
# V2 crypto providers fix their predecessors' encryption schemes by | |||
# hashing byte strings instead of the ehx strings output by `hexdigest` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# hashing byte strings instead of the ehx strings output by `hexdigest` | |
# hashing byte strings instead of the hex strings output by `hexdigest` |
Authlogic::CryptoProviders::V2::SHA256 | ||
] | ||
transition_password_to(providers[0], ben) | ||
providers.each_cons(2) do |old_provider, new_provider| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow each_cons
is perfect for this. Nice!
digest = "51563330eb60e0eeb89759b01f08e872" | ||
Authlogic::CryptoProviders::V2::MD5.stretches = 1 | ||
assert Authlogic::CryptoProviders::V2::MD5.matches?(digest, nil, salt, password, nil) | ||
Authlogic::CryptoProviders::V2::MD5.stretches = 10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming the stretches = 10
is restoring previous config, please move it to a teardown
method, to ensure it happens.
password = "test" | ||
salt = "7e3041ebc2fc05a40c60028e2c4901a81035d3cd" | ||
digest = "51563330eb60e0eeb89759b01f08e872" | ||
Authlogic::CryptoProviders::V2::MD5.stretches = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like how this test asserts a specific digest. Should we (also?) test with more than one stretch? If we only test one stretch, we're not testing the purpose of V2
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well that's a very good point. I copied this pattern from the V1 tests, which didn't include a test for MD5
, without quite enough thought.
Really I think a better thing to do is to (1) test encrypt
twice with two appropriately named methods that indicate they are testing different values of stretches
, both with specific digests, and (2) only test matches?
once now that stretches
has been covered by (1). What do you think?
Now I'm just trying to look into MiniTest doubles to see if it's worth asserting the number of calls made on the encryption methods or to just assert values of the different hashes they produce.
I can also make the corresponding changes to the V1 tests, including adding a test for MD5, in a separate commit. Would it be better to do so in a separate PR entirely?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. to (1) test encrypt twice with .. different values of stretches, both with specific digests ..
Sounds good.
.. MiniTest doubles .. or to just assert values of the different hashes they produce(?)
I'd just assert the hashes.
I can also make the corresponding changes to the V1 tests, including adding a test for MD5, in a separate commit. Would it be better to do so in a separate PR entirely?
It's up to you. Either way is fine with me.
Incidentally, as a result of this PR, I ordered a copy of "Cryptography Engineering" (Ferguson, Schneier, Kohno, 2010) and there's a nice overview of Salting and Stretching starting on p. 304. It doesn't tell us, explicitly, to hash the bytes instead of the hex-encoded string, but (to me) it is implied. (I was already convinced anyway from our research in #697) It also doesn't explicitly say whether to prepend or append the salt, probably because it doesn't matter, and also perhaps because there is no standard? |
I agree on the name being nicer. I don't like the class
I don't actually feel awkward at all about a I'll make the naming change. |
Personally I'm a pretty big stickler on "subclassing should be an is_a relationship". I have always found that violating that for benefit of reusing code has led to more confusion in the long run. Here, an This is expanding the scope here a bit, but what we could do is define a module for the common
To be honest I'm not sure it's enough duplication to justify the additional redirection, but I don't have a super strong opinion here and am happy to take this in either direction. |
That's fine, let's not worry about it for now. We can always come back and address the duplication later if we change our minds. |
… V2::MD5. Requires using the old-cased class names, such as Sha1::V2, instead of SHA1.
Ok, this has been updated with the discussed changes. Note:
|
Merged, thanks Andrew. I might think some more on 1) capitalization of acronyms, and 2) reducing duplication. If I change either, I'll @ you in a PR. Looking at the changelog, I guess our next release will be 6.0.0. |
Fixes #697