无法解密存储的加密数据 [英] Unable to decrypt stored encrypted data

查看:227
本文介绍了无法解密存储的加密数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在遇到与我在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.

这篇关于无法解密存储的加密数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆