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:
我正在尝试在我的Rails 4应用程序中加密存储的数据问题。我一直在寻找与此相关的许多问题,并且有许多提示,感觉就像我几乎在那里,但不知何故它只是不会解密数据。这些是涉及的两种方法:
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.
但是,当我尝试从它读取时,它抛出了这个OpenSSL :: Cipher :: CipherError:更糟糕的解密,更多的人似乎遇到了。
Any help would be much appreciated!
任何帮助将非常感激!
1 个解决方案
#1
3
This was a bit tricky to figure out, but the problem was not with my encryption logic but with a filter in the Devise gem. Devise lowercases email addresses before save by default, but because I'm encrypting and encoding them, I'm saving case sensitive UTF8 strings to the db. Lowercased, decoding the strings back to ASCII resulted in different results than the thing before the save, and that made decryption impossible.
要弄清楚这有点棘手,但问题不在于我的加密逻辑,而在Devise gem中有一个过滤器。在默认保存之前设计小写电子邮件地址,但因为我正在加密和编码它们,我将区分大小写的UTF8字符串保存到数据库。小写,将字符串解码回ASCII导致与保存之前的结果不同,这使得解密成为不可能。
Now if anyone runs into this, look for the case_insensitive_keys
setting in config/initializers/devise.rb
, and make sure it doesn't contain the keys you are saving encrypted. Keep in mind that if you do that you'd better either lowercase the emails yourself or validate and make uppercase characters in emails prohibited, something like that.
现在,如果有人遇到此问题,请在config / initializers / devise.rb中查找case_insensitive_keys设置,并确保它不包含您保存加密的密钥。请记住,如果你这样做,你最好自己小写电子邮件或验证并禁止在电子邮件中使用大写字符,就像这样。
#1
3
This was a bit tricky to figure out, but the problem was not with my encryption logic but with a filter in the Devise gem. Devise lowercases email addresses before save by default, but because I'm encrypting and encoding them, I'm saving case sensitive UTF8 strings to the db. Lowercased, decoding the strings back to ASCII resulted in different results than the thing before the save, and that made decryption impossible.
要弄清楚这有点棘手,但问题不在于我的加密逻辑,而在Devise gem中有一个过滤器。在默认保存之前设计小写电子邮件地址,但因为我正在加密和编码它们,我将区分大小写的UTF8字符串保存到数据库。小写,将字符串解码回ASCII导致与保存之前的结果不同,这使得解密成为不可能。
Now if anyone runs into this, look for the case_insensitive_keys
setting in config/initializers/devise.rb
, and make sure it doesn't contain the keys you are saving encrypted. Keep in mind that if you do that you'd better either lowercase the emails yourself or validate and make uppercase characters in emails prohibited, something like that.
现在,如果有人遇到此问题,请在config / initializers / devise.rb中查找case_insensitive_keys设置,并确保它不包含您保存加密的密钥。请记住,如果你这样做,你最好自己小写电子邮件或验证并禁止在电子邮件中使用大写字符,就像这样。