问题描述
我正在遇到与我在Rails 4应用程序中加密存储的数据有关的问题。我一直在看很多与此相关的问题,并且有很多提示,感觉就像我几乎在那里,但不知何故,它不会解密数据。这些是两种方法:
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
但是当我尝试读取它时,它会抛出这个 OpenSSL :: Cipher :: CipherError:bad decrypt
更多的人似乎遇到了。
But when I try to read from it, it throws this OpenSSL::Cipher::CipherError: bad decrypt
that more people seem to run into.
任何帮助将不胜感激!
推荐答案
这有点棘手,但问题并不在于我的加密逻辑,而是在Devise宝石中使用了一个过滤器。默认情况下,Devise会将电子邮件地址缩小到保存之前,但由于我正在对其进行加密和编码,因此我将将区分大小写的UTF8字符串保存到数据库。较低的,将字符串解码回ASCII导致与存储之前的事情不同的结果,这使得解密不可能。
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.
现在如果有人遇到这种情况, case_insensitive_keys
设置在 config / initializers / devise.rb
中,并确保它不包含正在保存的密钥加密。请记住,如果你这样做,你最好自己小写电子邮件或验证,并禁止电子邮件中的大写字符,这样的话。
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.
这篇关于无法解密存储的加密数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!