-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
397 additions
and
15 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
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,18 @@ | ||
module Mifiel | ||
module Crypto | ||
autoload :PBE, 'mifiel/crypto/pbe' | ||
autoload :Response, 'mifiel/crypto/response' | ||
autoload :AES, 'mifiel/crypto/aes' | ||
autoload :ECIES, 'mifiel/crypto/ecies' | ||
end | ||
end | ||
|
||
class String | ||
def bth | ||
unpack('H*').first | ||
end | ||
|
||
def htb | ||
Array(self).pack('H*') | ||
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 @@ | ||
require 'openssl' | ||
module Mifiel | ||
module Crypto | ||
class AES | ||
CIPHER = 256 | ||
SIZE = 16 | ||
|
||
def self.random_iv(size = SIZE) | ||
OpenSSL::Random.random_bytes(size) | ||
end | ||
|
||
def self.encrypt(cipher: CIPHER, key: nil, iv: nil, data: nil) | ||
aes = Mifiel::Crypto::AES.new(cipher) | ||
args = { cipher: cipher, key: key, iv: iv, data: data } | ||
aes.encrypt(args) | ||
end | ||
|
||
def self.decrypt(cipher: CIPHER, key: nil, iv: nil, data: nil) | ||
aes = Mifiel::Crypto::AES.new(cipher) | ||
args = { cipher: cipher, key: key, iv: iv, data: data } | ||
aes.decrypt(args) | ||
end | ||
|
||
attr_accessor :cipher, :require_args | ||
|
||
def initialize(cipher_type = CIPHER) | ||
@require_args = [:key, :iv, :data] | ||
@cipher = OpenSSL::Cipher::AES.new(cipher_type, :CBC) | ||
end | ||
|
||
def random_iv(size = SIZE) | ||
Mifiel::Crypto::AES.random_iv(size) | ||
end | ||
|
||
def encrypt(key: nil, iv: nil, data: nil) | ||
iv ||= random_iv | ||
Encrypted.new(cipher_final(key, iv, data, action: :encrypt)) | ||
end | ||
|
||
def decrypt(key: nil, iv: nil, data: nil) | ||
cipher_final(key, iv, data, action: :decrypt) | ||
end | ||
|
||
def cipher_final(key, iv, message, action: :encrypt) | ||
@cipher.send(action) | ||
@cipher.iv = iv | ||
@cipher.key = key | ||
@cipher.update(message) + @cipher.final | ||
end | ||
end | ||
|
||
class Encrypted < Mifiel::Crypto::Response | ||
def to_str | ||
data | ||
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,52 @@ | ||
require 'openssl' | ||
require 'securerandom' | ||
|
||
module Mifiel | ||
module Crypto | ||
class PBE | ||
ALPHA_NUM = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a | ||
SPECIALS = ['-', '_', '+', '=', '#', '&', '*', '.'].freeze | ||
CHARS = ALPHA_NUM + SPECIALS | ||
|
||
def self.generate | ||
pbe = Crypto::PBE.new | ||
password = pbe.random_password | ||
salt = pbe.random_salt | ||
pbe.derived_key(password, salt) | ||
end | ||
|
||
def initialize(i = 1000) | ||
@iterations = i | ||
@digest = OpenSSL::Digest::SHA256.new | ||
end | ||
|
||
def random_password(length = 32) | ||
CHARS.sort_by { SecureRandom.random_number }.join[0...length] | ||
end | ||
|
||
def random_salt(size = 16) | ||
SecureRandom.random_bytes(size) | ||
end | ||
|
||
def derived_key(password, salt, sizeKey = 24) | ||
args = { | ||
password: password, | ||
salt: salt, | ||
iterations: @iterations, | ||
sizeKey: sizeKey, | ||
digest: @digest | ||
} | ||
PKCS5.new(args) | ||
end | ||
end | ||
|
||
class PKCS5 < Mifiel::Crypto::Response | ||
attr_reader :key | ||
|
||
def initialize(args) | ||
@key = OpenSSL::PKCS5.pbkdf2_hmac(*args.values) | ||
@data = key # key attribute is syntax sugar | ||
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,19 @@ | ||
module Mifiel | ||
module Crypto | ||
class Response | ||
attr_reader :data | ||
|
||
def ==(other) | ||
data == other.data | ||
end | ||
|
||
def initialize(data) | ||
@data = data | ||
end | ||
|
||
def to_hex | ||
data.unpack('H*').first | ||
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,68 @@ | ||
{ | ||
"valid": [ | ||
{ | ||
"algorithm":128, | ||
"key": "1234567890123456", | ||
"dataToEncrypt": "cifrado de Prueba", | ||
"iv": "6976207465737469", | ||
"encrypted": "e69522e578832e378221b541431e64e6e704c17d8b2bdda598ebd3c716836d03" | ||
}, | ||
{ | ||
"algorithm":128, | ||
"key": "derivedKEY234556", | ||
"dataToEncrypt": "test de cifrado", | ||
"iv": "3436353837383837", | ||
"encrypted": "2b27f69570049490f5fee3bed8c045d9" | ||
}, | ||
{ | ||
"algorithm":128, | ||
"key": "a9r82*9rn5Flp3/o", | ||
"dataToEncrypt": "test de cifrado", | ||
"iv": "1353837383861646", | ||
"encrypted": "1b6a81b3ce5eb6ae3a239d0ee51e2699" | ||
}, | ||
|
||
{ | ||
"algorithm":192, | ||
"key": "123456789012345678901234", | ||
"dataToEncrypt": "cifrado de Prueba AES-192", | ||
"iv": "6466736438373435", | ||
"encrypted": "0cf4ea5765b42b9088c901064c07ba7a6eec3030609673830fcbd8ac5cc77edd" | ||
}, | ||
{ | ||
"algorithm":192, | ||
"key": "derivedKEY234556iksRtryr", | ||
"dataToEncrypt": "test de cifrado AES-192", | ||
"iv": "7266736438373435", | ||
"encrypted": "fd0fec1268dbb111babc5b8a15397ad946af61561eb6d40c36068c04ddf5d008" | ||
}, | ||
{ | ||
"algorithm":192, | ||
"key": "*854FrGTH/hgf_4f6h9v4dfg", | ||
"dataToEncrypt": "encrypted decrypted data", | ||
"iv": "2e39746438373435", | ||
"encrypted": "43e7e6f7a56a73a60d5b619e590b91de3c79e765a37f893f122a6b3e9497f8f6" | ||
}, | ||
{ | ||
"algorithm": 256, | ||
"key": "12345678901234567890123456789012", | ||
"dataToEncrypt": "cifrado de Prueba AES-256", | ||
"iv": "39382e2e2d6438rf", | ||
"encrypted": "60ea45d407514d4e67ef0eb12b2df8e5ea02f156cdea71eeafda0b0b54092d63" | ||
}, | ||
{ | ||
"algorithm":256, | ||
"key": "derivedKEY234556iksRtryrtg578hfr", | ||
"dataToEncrypt": "test de cifrado AES-256", | ||
"iv": "7266736438373435", | ||
"encrypted": "6d2e185278b5a87da86941b390ac7baffee5e87ae86d877350edbe9a6077e396" | ||
}, | ||
{ | ||
"algorithm":256, | ||
"key": "*854FrGTH/hgf_4f6h9v4dfg*&jr-jew", | ||
"dataToEncrypt": "test de cifrado", | ||
"iv": "2e39746438373435", | ||
"encrypted": "3c3dc5a978f756a576a952b4eb3ca868" | ||
} | ||
] | ||
} |
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,68 @@ | ||
{ | ||
"valid": [ | ||
{ | ||
"key": "passwd", | ||
"salt": "salt", | ||
"iterations": 1, | ||
"keylen": 64, | ||
"result": "55ac046e56e3089fec1691c22544b605f94185216dde0465e68b9d57c20dacbc49ca9cccf179b645991664b39d77ef317c71b845b1e30bd509112041d3a19783" }, | ||
{ | ||
"key": "Password", | ||
"salt": "NaCl", | ||
"iterations": 80000, | ||
"keylen": 64, | ||
"result": "4ddcd8f60b98be21830cee5ef22701f9641a4418d04c0414aeff08876b34ab56a1d425a1225833549adb841b51c9b3176a272bdebba1d078478f62b397f33c8d" }, | ||
{ | ||
"key": "password", | ||
"salt": "salt", | ||
"iterations": 1, | ||
"keylen": 32, | ||
"result": "120fb6cffcf8b32c43e7225256c4f837a86548c92ccc35480805987cb70be17b" }, | ||
{ | ||
"key": "password", | ||
"salt": "salt", | ||
"iterations": 2, | ||
"keylen": 32, | ||
"result": "ae4d0c95af6b46d32d0adff928f06dd02a303f8ef3c251dfd6e2d85a95474c43" }, | ||
{ | ||
"key": "password", | ||
"salt": "salt", | ||
"iterations": 4096, | ||
"keylen": 32, | ||
"result": "c5e478d59288c841aa530db6845c4c8d962893a001ce4e11a4963873aa98134a" | ||
}, | ||
{ | ||
"key": "passwordPASSWORDpassword", | ||
"salt": "saltSALTsaltSALTsaltSALTsaltSALTsalt", | ||
"iterations": 4096, | ||
"keylen": 40, | ||
"result": "348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9" | ||
}, | ||
{ | ||
"key": "", | ||
"salt": "salt", | ||
"iterations": 1024, | ||
"keylen": 32, | ||
"result": "9e83f279c040f2a11aa4a02b24c418f2d3cb39560c9627fa4f47e3bcc2897c3d" | ||
|
||
}, | ||
{ | ||
"key": "password", | ||
"salt": "", | ||
"iterations": 1024, | ||
"keylen": 32, | ||
"result": "ea5808411eb0c7e830deab55096cee582761e22a9bc034e3ece925225b07bf46" | ||
|
||
} | ||
], | ||
"invalid": [ | ||
{ | ||
"key": "password", | ||
"salt": "afas", | ||
"iterations": 1024, | ||
"keylen": 35184372088832, | ||
"result": "", | ||
"description": "key length too long" | ||
} | ||
] | ||
} |
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,46 @@ | ||
describe Mifiel::Crypto::AES do | ||
aes_fixture = JSON.parse(File.read('spec/fixtures/aes.json'), symbolize_names: true) | ||
|
||
describe '#AES good' do | ||
aes_fixture[:valid].each do |v| | ||
describe v.slice(:algorithm, :key, :dataToEncrypt).to_s do | ||
e_args = { data: v[:dataToEncrypt], key: v[:key], iv: v[:iv], cipher: v[:algorithm] } | ||
d_args = e_args.clone | ||
let(:aes) { Mifiel::Crypto::AES.new(e_args[:cipher]) } | ||
let(:encrypted) { aes.encrypt(e_args) } | ||
it 'should return Encrypted instance' do | ||
expect(encrypted).to be_a Mifiel::Crypto::Encrypted | ||
end | ||
it 'should return encrypted hex' do | ||
expect(encrypted.to_hex).to eq(v[:encrypted]) | ||
end | ||
it 'should receive binary data and return decipher text' do | ||
d_args[:data] = encrypted.data | ||
expect(aes.decrypt(d_args)).to eq(v[:dataToEncrypt]) | ||
end | ||
it 'should receive Encrypted instance & return decipher text' do | ||
d_args[:data] = encrypted | ||
expect(aes.decrypt(d_args)).to eq(v[:dataToEncrypt]) | ||
end | ||
it 'should encrypt & decrypt with static method' do | ||
encrypted_data = Mifiel::Crypto::AES.encrypt(e_args) | ||
expect(encrypted_data == encrypted).to be true | ||
expect(encrypted_data.to_hex).to eq(v[:encrypted]) | ||
d_args[:data] = encrypted_data | ||
expect(Mifiel::Crypto::AES.decrypt(d_args)).to eq(v[:dataToEncrypt]) | ||
end | ||
end | ||
end | ||
|
||
describe 'Generate random iv' do | ||
let(:ivs) { Set.new } | ||
5.times do | ||
iv = Mifiel::Crypto::AES.random_iv.unpack('H*').first | ||
it "should be unique #{iv}" do | ||
expect(ivs.include?(iv)).to be false | ||
ivs.add(iv) | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.