class Eth::Key::Encrypter
The Eth::Key::Encrypter class to handle PBKDF2-SHA-256 encryption.
def self.perform(key, password, options = {})
-
(JSON)
- formatted with encrypted key (cyphertext) and [other identifying data](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition#pbkdf2-sha-256)
Options Hash:
(**options)
-
:block_size
(Integer
) -- for scrypt, defaults to 1 -
:parallelization
(Integer
) -- parallelization factor for scrypt, defaults to 8 -
:iv
(String
) -- 128-bit initialisation vector for the cipher -
:salt
(String
) -- passed to PBKDF -
:iterations
(String
) -- number of iterations for the hash function -
:id
(String
) -- uuid given to the secret key -
:kdf
(String
) -- key derivation function defaults to pbkdf2
Parameters:
-
options
(Hash
) -- the options to encrypt with -
key
(Eth::Key
) -- representing a secret key-pair used for encryption
def self.perform(key, password, options = {}) new(key, options).perform(password) end
def block_size
def block_size options[:block_size] || 1 end
def cipher
def cipher @cipher ||= OpenSSL::Cipher.new(cipher_name).tap do |cipher| cipher.encrypt cipher.iv = iv cipher.key = derived_key[0, (key_length / 2)] end end
def cipher_name
def cipher_name "aes-128-ctr" end
def data
-
(Hash)
- the encrypted keystore data.
def data # default to pbkdf2 kdfparams = if kdf == "scrypt" { dklen: 32, n: iterations, p: parallelization, r: block_size, salt: Util.bin_to_hex(salt), } else { c: iterations, dklen: 32, prf: prf, salt: Util.bin_to_hex(salt), } end { crypto: { cipher: cipher_name, cipherparams: { iv: Util.bin_to_hex(iv), }, ciphertext: Util.bin_to_hex(encrypted_key), kdf: kdf, kdfparams: kdfparams, mac: Util.bin_to_hex(mac), }, id: id, version: 3, } end
def derive_key(password)
def derive_key(password) if kdf == "scrypt" @derived_key = SCrypt::Engine.scrypt(password, salt, iterations, block_size, parallelization, key_length) else @derived_key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, key_length, digest) end end
def digest
def digest @digest ||= OpenSSL::Digest.new digest_name end
def digest_name
def digest_name "sha256" end
def encrypt
def encrypt @encrypted_key = cipher.update(Util.hex_to_bin key.private_hex) + cipher.final end
def id
def id @id ||= options[:id] || SecureRandom.uuid end
def initialize(key, options = {})
(**options)
-
:block_size
(Integer
) -- for scrypt, defaults to 1 -
:parallelization
(Integer
) -- parallelization factor for scrypt, defaults to 8 -
:iv
(String
) -- 128-bit initialisation vector for the cipher -
:salt
(String
) -- passed to PBKDF -
:iterations
(String
) -- number of iterations for the hash function -
:id
(String
) -- uuid given to the secret key -
:kdf
(String
) -- key derivation function defaults to pbkdf2
Parameters:
-
options
(Hash
) -- the options to encrypt with -
key
(Eth::Key
) -- representing a secret key-pair used for encryption
def initialize(key, options = {}) @key = key @options = options # the key derivation functions default to pbkdf2 if no option is specified # however, if an option is given then it must be either pbkdf2 or scrypt if kdf != "scrypt" && kdf != "pbkdf2" raise EncrypterError, "Unsupported key derivation function: #{kdf}!" end end
def iterations
def iterations options[:iterations] || 262_144 end
def iv
def iv @iv ||= if options[:iv] Util.hex_to_bin options[:iv] else SecureRandom.random_bytes(iv_length) end end
def iv_length
def iv_length 16 end
def kdf
def kdf options[:kdf] || "pbkdf2" end
def key_length
def key_length 32 end
def mac
def mac Util.keccak256(derived_key[(key_length / 2), key_length] + encrypted_key) end
def parallelization
def parallelization options[:parallelization] || 8 end
def perform(password)
-
(String)
- a json-formatted keystore string.
Parameters:
-
password
(String
) -- a secret key used for encryption
def perform(password) derive_key password encrypt data.to_json end
def prf
def prf "hmac-#{digest_name}" end
def salt
def salt @salt ||= if options[:salt] Util.hex_to_bin options[:salt] else SecureRandom.random_bytes(salt_length) end end
def salt_length
def salt_length 32 end