-
Notifications
You must be signed in to change notification settings - Fork 635
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add V2 crypto providers for SHA* and MD5 encryption methods. Fixes or…
…iginal SHA512 crypto provider by digesting bytes instead of hex string.
- Loading branch information
Showing
10 changed files
with
311 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# frozen_string_literal: true | ||
|
||
require "digest/md5" | ||
|
||
module Authlogic | ||
module CryptoProviders | ||
module V2 | ||
# A poor choice. There are known attacks against this algorithm. | ||
class MD5 | ||
class << self | ||
attr_accessor :join_token | ||
|
||
# The number of times to loop through the encryption. | ||
def stretches | ||
@stretches ||= 1 | ||
end | ||
attr_writer :stretches | ||
|
||
# Turns your raw password into a MD5 hash. | ||
def encrypt(*tokens) | ||
digest = tokens.flatten.join(join_token) | ||
stretches.times { digest = Digest::MD5.digest(digest) } | ||
digest.unpack("H*")[0] | ||
end | ||
|
||
# Does the crypted password match the tokens? Uses the same tokens that | ||
# were used to encrypt. | ||
def matches?(crypted, *tokens) | ||
encrypt(*tokens) == crypted | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# frozen_string_literal: true | ||
|
||
require "digest/sha1" | ||
|
||
module Authlogic | ||
module CryptoProviders | ||
module V2 | ||
# A poor choice. There are known attacks against this algorithm. | ||
class SHA1 | ||
class << self | ||
def join_token | ||
@join_token ||= "--" | ||
end | ||
attr_writer :join_token | ||
|
||
# The number of times to loop through the encryption. | ||
def stretches | ||
@stretches ||= 10 | ||
end | ||
attr_writer :stretches | ||
|
||
# Turns your raw password into a Sha1 hash. | ||
def encrypt(*tokens) | ||
tokens = tokens.flatten | ||
digest = tokens.shift | ||
stretches.times do | ||
digest = Digest::SHA1.digest([digest, *tokens].join(join_token)) | ||
end | ||
digest.unpack("H*")[0] | ||
end | ||
|
||
# Does the crypted password match the tokens? Uses the same tokens that | ||
# were used to encrypt. | ||
def matches?(crypted, *tokens) | ||
encrypt(*tokens) == crypted | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# frozen_string_literal: true | ||
|
||
require "digest/sha2" | ||
|
||
module Authlogic | ||
# The acts_as_authentic method has a crypto_provider option. This allows you | ||
# to use any type of encryption you like. Just create a class with a class | ||
# level encrypt and matches? method. See example below. | ||
# | ||
# === Example | ||
# | ||
# class MyAwesomeEncryptionMethod | ||
# def self.encrypt(*tokens) | ||
# # the tokens passed will be an array of objects, what type of object | ||
# # is irrelevant, just do what you need to do with them and return a | ||
# # single encrypted string. for example, you will most likely join all | ||
# # of the objects into a single string and then encrypt that string | ||
# end | ||
# | ||
# def self.matches?(crypted, *tokens) | ||
# # return true if the crypted string matches the tokens. Depending on | ||
# # your algorithm you might decrypt the string then compare it to the | ||
# # token, or you might encrypt the tokens and make sure it matches the | ||
# # crypted string, its up to you. | ||
# end | ||
# end | ||
module CryptoProviders | ||
module V2 | ||
# = Sha256 | ||
# | ||
# Uses the Sha256 hash algorithm to encrypt passwords. | ||
class SHA256 | ||
class << self | ||
attr_accessor :join_token | ||
|
||
# The number of times to loop through the encryption. | ||
def stretches | ||
@stretches ||= 20 | ||
end | ||
attr_writer :stretches | ||
|
||
# Turns your raw password into a Sha256 hash. | ||
def encrypt(*tokens) | ||
digest = tokens.flatten.join(join_token) | ||
stretches.times { digest = Digest::SHA256.digest(digest) } | ||
digest.unpack("H*")[0] | ||
end | ||
|
||
# Does the crypted password match the tokens? Uses the same tokens that | ||
# were used to encrypt. | ||
def matches?(crypted, *tokens) | ||
encrypt(*tokens) == crypted | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# frozen_string_literal: true | ||
|
||
require "digest/sha2" | ||
|
||
module Authlogic | ||
module CryptoProviders | ||
module V2 | ||
# SHA-512 does not have any practical known attacks against it. However, | ||
# there are better choices. We recommend transitioning to a more secure, | ||
# adaptive hashing algorithm, like scrypt. | ||
class SHA512 | ||
class << self | ||
attr_accessor :join_token | ||
|
||
# The number of times to loop through the encryption. | ||
def stretches | ||
@stretches ||= 20 | ||
end | ||
attr_writer :stretches | ||
|
||
# Turns your raw password into a Sha512 hash. | ||
def encrypt(*tokens) | ||
digest = tokens.flatten.join(join_token) | ||
stretches.times do | ||
digest = Digest::SHA512.digest(digest) | ||
end | ||
digest.unpack("H*")[0] | ||
end | ||
|
||
# Does the crypted password match the tokens? Uses the same tokens that | ||
# were used to encrypt. | ||
def matches?(crypted, *tokens) | ||
encrypt(*tokens) == crypted | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
module CryptoProviderTest | ||
module V2 | ||
class MD5Test < ActiveSupport::TestCase | ||
def test_encrypt | ||
assert Authlogic::CryptoProviders::V2::MD5.encrypt("mypass") | ||
end | ||
|
||
def test_matches | ||
hash = Authlogic::CryptoProviders::V2::MD5.encrypt("mypass") | ||
assert Authlogic::CryptoProviders::V2::MD5.matches?(hash, "mypass") | ||
end | ||
|
||
def test_matches_2 | ||
password = "test" | ||
salt = "7e3041ebc2fc05a40c60028e2c4901a81035d3cd" | ||
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 | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
module CryptoProviderTest | ||
module V2 | ||
class SHA1Test < ActiveSupport::TestCase | ||
def test_encrypt | ||
assert Authlogic::CryptoProviders::V2::SHA1.encrypt("mypass") | ||
end | ||
|
||
def test_matches | ||
hash = Authlogic::CryptoProviders::V2::SHA1.encrypt("mypass") | ||
assert Authlogic::CryptoProviders::V2::SHA1.matches?(hash, "mypass") | ||
end | ||
|
||
def test_matches_2 | ||
password = "test" | ||
salt = "abc" | ||
digest = "2d578fb3ab6bdab725080f00d5689f79b7d1df51" | ||
Authlogic::CryptoProviders::V2::SHA1.stretches = 1 | ||
assert Authlogic::CryptoProviders::V2::SHA1.matches?(digest, nil, salt, password, nil) | ||
Authlogic::CryptoProviders::V2::SHA1.stretches = 10 | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
module CryptoProviderTest | ||
module V2 | ||
class SHA256Test < ActiveSupport::TestCase | ||
def test_encrypt | ||
assert Authlogic::CryptoProviders::V2::SHA256.encrypt("mypass") | ||
end | ||
|
||
def test_matches | ||
hash = Authlogic::CryptoProviders::V2::SHA256.encrypt("mypass") | ||
assert Authlogic::CryptoProviders::V2::SHA256.matches?(hash, "mypass") | ||
end | ||
|
||
def test_matches_2 | ||
password = "test" | ||
salt = "abc" | ||
digest = "70e0f1ade11debb6732029c267095e092b5b43ff271d4f8d9158cb004322f38b" | ||
Authlogic::CryptoProviders::V2::SHA256.stretches = 1 | ||
assert Authlogic::CryptoProviders::V2::SHA256.matches?(digest, nil, salt, password, nil) | ||
Authlogic::CryptoProviders::V2::SHA256.stretches = 10 | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
module CryptoProviderTest | ||
module V2 | ||
class SHA512Test < ActiveSupport::TestCase | ||
def test_encrypt | ||
assert Authlogic::CryptoProviders::V2::SHA512.encrypt("mypass") | ||
end | ||
|
||
def test_matches | ||
hash = Authlogic::CryptoProviders::V2::SHA512.encrypt("mypass") | ||
assert Authlogic::CryptoProviders::V2::SHA512.matches?(hash, "mypass") | ||
end | ||
|
||
def test_matches_2 | ||
password = "test" | ||
salt = "abc" | ||
# rubocop:disable Metrics/LineLength | ||
digest = "c7cb2b81ccbb686eaefafbfbcf61334fb75f8e5dcb3de8b86fec53ad1a5dd013c0c4c9cc3af7c59aed2afab59dd463f6a84d9531f46e2efeb3681bd79bf57a37" | ||
# rubocop:enable Metrics/LineLength | ||
Authlogic::CryptoProviders::V2::SHA512.stretches = 1 | ||
assert Authlogic::CryptoProviders::V2::SHA512.matches?(digest, nil, salt, password, nil) | ||
Authlogic::CryptoProviders::V2::SHA512.stretches = 10 | ||
end | ||
end | ||
end | ||
end |