I'm running into issues with data I'm trying to store encrypted in my Rails 4 app. I've been looking at lots of questions related to this and there are many hints, feels like I'm almost there, but somehow it just won't decrypt the data. These are the two methods involved:
def encrypt( val, pwd_name )
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.encrypt
iv = cipher.random_iv
pwd = encryptor_pwds[ pwd_name ]
salt = OpenSSL::Random.random_bytes 16
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key
encrypted = cipher.update val
encrypted << cipher.final
encrypted = Base64.encode64( encrypted ).encode('utf-8')
iv = Base64.encode64( iv ).encode('utf-8')
salt = Base64.encode64( salt ).encode('utf-8')
return { str: encrypted, iv: iv, salt: salt }
end
def decrypt( str, iv, salt, pwd_name )
cipher = OpenSSL::Cipher.new 'AES-128-CBC'
cipher.decrypt
str = Base64.decode64( str )
iv = Base64.decode64( iv )
salt = Base64.decode64( salt )
cipher.iv = iv
pwd = encryptor_pwds[ pwd_name ]
salt = salt
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest::SHA256.new
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key
decrypted = cipher.update str
decrypted << cipher.final
return decrypted
end
And the I modified the read/writes to for example this:
def email=(email)
unless email.nil?
set = encrypt(email, :email)
write_attribute( :email, set[:str] )
write_attribute( :email_iv, set[:iv] )
write_attribute( :email_salt, set[:salt] )
else
write_attribute( :email, nil )
end
end
def email
if read_attribute( :email ).nil? then read_attribute( :email ) else decrypt( read_attribute( :email ), read_attribute( :email_iv ), read_attribute( :email_salt ), :email ) end
end
But when I try to read from it, it throws this OpenSSL::Cipher::CipherError: bad decrypt
that more people seem to run into.
Any help would be much appreciated!
bad decrypt
could mean anything. Wrong key, wrong data, wrong encoding, wrong salt, wrong passwrod and possibly even wrong IV. – Bureaucracycase_insensitive_keys
, but that triggers when saving, so when I encoded the ASCII string into UTF-8 a case sensitive string was generated, but upon save that was always lowercased, and of course if you encode that to ASCII again the result string is not going to be the same as the original one. – Polymorphonuclear