class Laksa::Crypto::KeyStore
Constants
- T_PBKDF2
- T_SCRYPT
Public Class Methods
new()
click to toggle source
# File lib/laksa/crypto/key_store.rb, line 13 def initialize end
Public Instance Methods
decrypt_private_key(encrypt_json, password)
click to toggle source
Recovers the private key from a keystore file using the given passphrase.
@param {KeystoreV3} encrypt_json @param {string} password
# File lib/laksa/crypto/key_store.rb, line 75 def decrypt_private_key(encrypt_json, password) datas = JSON.parse(encrypt_json) ciphertext = Util.decode_hex(datas['crypto']['ciphertext']) iv = Util.decode_hex(datas['crypto']['cipherparams']['iv']) kdfparams = datas['crypto']['kdfparams'] kdf_type = datas['crypto']['kdf'] case kdf_type when T_PBKDF2 derived_key = PBKDF2.new(password: password, salt: kdfparams['salt'].pack('c*'), key_length: kdfparams['dklen'], iterations: kdfparams['c']).value when T_SCRYPT derived_key = SCrypt::Engine.scrypt(password, kdfparams['salt'].pack('c*'), kdfparams['n'], kdfparams['r'], kdfparams['p'], kdfparams['dklen']) end encrypt_key = derived_key[0..15] mac = generate_mac(derived_key, ciphertext) raise 'Failed to decrypt.' if mac.casecmp(datas['crypto']['mac']) != 0 cipher = OpenSSL::Cipher.new(datas['crypto']['cipher']) cipher.decrypt cipher.iv = iv cipher.key = encrypt_key cipher.padding = 0 private_key = cipher.update(ciphertext) + cipher.final return Util.encode_hex private_key end
encrypt_private_key(private_key, password, kdf_type)
click to toggle source
encryptPrivateKey
Encodes and encrypts an account in the format specified by github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition. However, note that, in keeping with the hash function used by Zilliqa's core protocol, the MAC is generated using sha256 instead of keccak.
NOTE: only scrypt and pbkdf2 are supported.
@param {string} private_key - hex-encoded private key @param {string} password - a password used for encryption @param {KDF} kdf_type - the key derivation function to be used
# File lib/laksa/crypto/key_store.rb, line 28 def encrypt_private_key(private_key, password, kdf_type) address = KeyTool.get_address_from_private_key(private_key) iv = KeyTool.generate_random_bytes(16) salt = KeyTool.generate_random_bytes(32) case kdf_type when T_PBKDF2 derived_key = PBKDF2.new(password: password, salt: salt, key_length: 32, iterations: 262144).value when T_SCRYPT derived_key = SCrypt::Engine.scrypt(password, salt, 8192, 8, 1, 32) end encrypt_key = derived_key[0..15] cipher = OpenSSL::Cipher.new('aes-128-ctr') cipher.encrypt cipher.iv = iv cipher.key = encrypt_key cipher.padding = 0 ciphertext = cipher.update(Util.decode_hex(private_key)) + cipher.final mac = generate_mac(derived_key, ciphertext) datas = {address: address, crypto: { cipher: 'aes-128-ctr', cipherparams: {'iv': Util.encode_hex(iv)}, ciphertext: Util.encode_hex(ciphertext), kdf: kdf_type, kdfparams: {n: 8192, c:262144, r:8, p:1, dklen: 32, salt: salt.bytes}, mac: mac }, id: SecureRandom.uuid, version: 3 } datas.to_json end
Private Instance Methods
generate_mac(derived_key, ciphertext)
click to toggle source
# File lib/laksa/crypto/key_store.rb, line 108 def generate_mac(derived_key, ciphertext) Digest::SHA256.hexdigest(derived_key[16..32] + ciphertext) end