I'm a Ruby newbie and I need to implement a Geth-compatible key import/export in Ruby. I was looking at the Geth implementation in Go, as well as keythereum. This is what I have: require "eth" require 'fileutils' require 'json' require 'openssl' require 'securerandom' require 'test/unit' class SimpleTest < Test::Unit::TestCase def test_create_keys # hardcoded password password = "password" # create new keypair using https://github.com/se3000/ruby-eth keypair = Eth::Key.new # key version version = 3 # Generate key uuid v4 uuid = SecureRandom.uuid # address address = keypair.to_address # more on aes-128-ctr: # https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29 cipher_name = "aes-128-ctr" cipher = OpenSSL::Cipher.new cipher_name # iv "Initialization Vector" iv = SecureRandom.random_bytes(16) #store this with the generated value # Derive encryption key from password # kdf = key derivation function, for password-based keys digest_name = "sha256" prf = "hmac-" + digest_name digest = OpenSSL::Digest.new digest_name key_length = 32 salt_length = 32 iterations = 65536 salt = SecureRandom.random_bytes(salt_length) #store this with the generated value derived_key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, key_length, digest) # Encrypt private key with key derived from password cipher.encrypt cipher.iv = iv iv = cipher.random_iv cipher.key = derived_key encrypted = cipher.update([keypair.private_key.to_hex].pack("H*")) + cipher.final # Generate mac derived_key_hex = derived_key.unpack("H*")[0] encrypted_hex = encrypted.unpack("H*")[0] mac = Eth::Utils.keccak256(derived_key_hex[32, 64] + encrypted) json = { "address" => address, "crypto" => { "cipher" => cipher_name, "ciphertext" => encrypted_hex, "cipherparams" => { "iv" => iv.unpack("H*")[0] }, "mac" => mac.unpack("H*")[0], "kdf" => "pbkdf2", "kdfparams" => { "c" => iterations, "dklen" => key_length, "prf" => prf, "salt" => salt.unpack("H*")[0], } }, "id": uuid, "version": version } file_name = "UTC--" + Time.now.utc.strftime("%Y-%m-%dT%H:%M:%S.%LZ") + "--" + address FileUtils.mkdir_p 'keystore' File.open("keystore/" + file_name,"w") do |f| f.write(json.to_json) end end end In Geth, I see my generated address, but I can't unlock the account with the password I have used. > personal.listAccounts ["0xf31081983dcf4984304c14563f82ab29a630144d"] > personal.unlockAccount("0xf31081983dcf4984304c14563f82ab29a630144d") Unlock account 0xf31081983dcf4984304c14563f82ab29a630144d Passphrase: could not decrypt key with given passphrase Something wrong in my implementation, but I can't find the issue.