如何使用 OpenSSL::Cipher 加密 UTF-8 字符串中的数据?
Posted
技术标签:
【中文标题】如何使用 OpenSSL::Cipher 加密 UTF-8 字符串中的数据?【英文标题】:How to encrypt data in a UTF-8 string using OpenSSL::Cipher? 【发布时间】:2012-06-18 01:12:39 【问题描述】:在 Rails 3.0 (Ruby 1.9.2) 应用程序中,我尝试使用以下方式加密一些数据:
cipher = OpenSSL::Cipher.new 'aes-256-cbc'
cipher.encrypt
cipher.key = cipher.random_key
cipher.iv = cipher.random_iv
encrypted = cipher.update 'most secret data in the world'
encrypted << cipher.final
这将进入一个 UTF-8 数据库。我的问题是
> encrypted.encoding
=> #<Encoding:ASCII-8BIT>
> encrypted.encode 'utf-8'
Encoding::UndefinedConversionError: "\xF7" from ASCII-8BIT to UTF-8
如何获取 UTF-8 加密字符串?
【问题讨论】:
【参考方案1】:解决方法是将ASCII-8BIT字符串转换为Base64,然后编码为UTF-8。
cipher = OpenSSL::Cipher.new 'aes-256-cbc'
cipher.encrypt
cipher.key = cipher.random_key
cipher.iv = cipher.random_iv
encrypted = cipher.update 'most secret data in the world'
encrypted << cipher.final
encoded = Base64.encode64(encrypted).encode('utf-8')
一旦持久化并从数据库中检索,
decoded = Base64.decode64 encoded.encode('ascii-8bit')
最后解密。
PS:如果你好奇:
cipher = OpenSSL::Cipher.new 'aes-256-cbc'
cipher.decrypt
cipher.key = random_key
cipher.iv = random_iv
decrypted = cipher.update encoded
decrypted << cipher.final
> decrypted
=> 'most secret data in the world'
【讨论】:
» encoded = Base64.encode64('Tromsø').encode('utf-8') => "VHJvbXPDuA==\n" » Base64.decode64(encoded.encode('ascii-8bit')) => "Troms\xC3\xB8"
谢谢你,拯救了我的一天!【参考方案2】:
我相信你最好的选择是使用force_encoding
找到here。
> encrypted.encoding
=> #<Encoding:ASCII-8BIT>
> encrypted.force_encoding "utf-8"
> encrypted.encoding
=> #<Encoding:UTF-8>
【讨论】:
.encode
从 ASCII-8BIT 到 UTF-8 失败,所以 .force_encoding
只会生成一个无效的字节序列。以上是关于如何使用 OpenSSL::Cipher 加密 UTF-8 字符串中的数据?的主要内容,如果未能解决你的问题,请参考以下文章
Conjur quickstart创建myConjurAccount,显示rake中止了! OpenSSL :: Cipher :: CipherError: