1

Rails 4 アプリで暗号化して保存しようとしているデータで問題が発生しています。これに関連する多くの質問を見てきましたが、多くのヒントがあり、ほとんどそこにいるように感じますが、どういうわけかデータを復号化できません. 関係する 2 つの方法は次のとおりです。

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

そして、たとえば次のように読み取り/書き込みを変更しました。

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より多くの人が遭遇するように見えるこれがスローされます。

どんな助けでも大歓迎です!

4

1 に答える 1

3

これを理解するのは少し難しいですが、問題は私の暗号化ロジックではなく、Devise gem のフィルターにありました。デフォルトでは保存前に小文字のメールアドレスを工夫しますが、暗号化してエンコードしているため、大文字と小文字を区別するUTF8文字列をデータベースに保存しています。小文字の文字列をデコードして ASCII に戻すと、保存前とは異なる結果になり、復号化が不可能になりました。

誰かがこれに遭遇した場合は、 でcase_insensitive_keys設定を探し、config/initializers/devise.rb暗号化して保存するキーが含まれていないことを確認してください。その場合は、メールを自分で小文字にするか、検証してメールの大文字を禁止するなどの方法をお勧めします。

于 2013-09-02T09:40:23.817 に答える