如何用另一种语言解密由Ruby的“对称加密” gem加密的数据? [英] How do I decrypt data encrypted by Ruby's `symmetric-encryption` gem in another language?

查看:181
本文介绍了如何用另一种语言解密由Ruby的“对称加密” gem加密的数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想访问Rails创建的数据库中的数据,以供非Ruby代码使用。有些字段使用 attr_encrypted 访问器,而使用的库是对称加密 gem。如果我尝试使用例如NodeJS crypto 库解密数据,就会始终出现错误的最终块长度错误。



我怀疑这与字符编码或填充有关,但根据文档我无法弄清楚。



作为一个实验,我尝试从Ruby自己的OpenSSL库中的对称加密解密数据,但出现错误的解密错误或相同的问题:

  SymmetricEncryption.cipher = SymmetricEncryption :: Cipher.new(
键: 1234567890ABCDEF,
iv: 1234567890ABCDEF,
cipher_name: aes-128-cbc


ciphertext = SymmetricEncryption.encrypt( Hello world)

c = OpenSSL :: Cipher.new( aes-128-cbc)
c.iv = c.key = 1234567890ABCDEF
c.update(密文)+ c.final

这给了我一个错误解密错误。



有趣的是,数据库中的加密数据可以通过对称加密 gem解密,但与 SymmetricEncryption的输出不同.encrypt (和Ope






编辑:

  psql =#从人数限制1中选择 encrypted_firstName; 
encryption_firstName
----------------------------------------- -----------------
QEVuQwBAEAAuR5vRj / iFbaEsXKtpjubrWgyEhK5Pji2EWPDPoT4CyQ ==
(1行)

然后

  irb> SymmetricEncryption.decrypt QEVuQwBAEAAuR5vRj / iFbaEsXKtpjubrWgyEhK5Pji2EWPDPoT4CyQ == 
=> Lurline
irb> SymmetricEncryption.encrypt Lurline
=> QEVuQwAAlRBeYptjK0Fg76jFQkjLtA ==


解决方案

查看对称加密gem的来源,默认为在输出中添加标头,然后 base64对其进行编码,尽管这两个都是可配置的。 p>

要直接使用Ruby的OpenSSL进行解密,您需要对其进行解码并剥离此标头,在这种简单情况下长度为6个字节

 密文= Base64.decode64(密文)
密文=密文[6 ..- 1]

c = OpenSSL :: Cipher.new( aes-128-cbc)
c.decrypt
c.iv = 1234567890ABCDEF
c.key = 1234567890ABCDEF

结果= c.update(密文)+ c.final

当然,您可能需要根据对称加密中使用的设置进行更改,例如标头长度可能会有所不同。为了解密数据库中的结果,您将需要解析标头。看看源代码


I want to access data in a database created by Rails for use by non-Ruby code. Some fields use attr_encrypted accessors, and the library in use is the symmetric-encryption gem. I consistently get a "wrong final block length" error if I try to decrypt the data with, e.g., the NodeJS crypto library.

I suspect this has to do either with character encoding or with padding, but I can't figure it out based on the docs.

As an experiment, I tried decrypting data from symmetric-encryption in Ruby's own OpenSSL library, and I get either a "bad decrypt" error or the same problem:

SymmetricEncryption.cipher = SymmetricEncryption::Cipher.new(
  key: "1234567890ABCDEF",
  iv:  "1234567890ABCDEF",
  cipher_name: "aes-128-cbc"
)

ciphertext = SymmetricEncryption.encrypt("Hello world")

c = OpenSSL::Cipher.new("aes-128-cbc")
c.iv = c.key = "1234567890ABCDEF"
c.update(ciphertext) + c.final

That gives me a "bad decrypt" error.

Interestingly, the encrypted data in the database can be decrypted by the symmetric-encryption gem, but isn't the same as the output of SymmetricEncryption.encrypt (and OpenSSL doesn't successfully decrypt it, either).


Edit:

psql=# SELECT "encrypted_firstName" FROM people LIMIT 1;
                   encrypted_firstName                    
----------------------------------------------------------
 QEVuQwBAEAAuR5vRj/iFbaEsXKtpjubrWgyEhK5Pji2EWPDPoT4CyQ==
(1 row)

Then

irb> SymmetricEncryption.decrypt "QEVuQwBAEAAuR5vRj/iFbaEsXKtpjubrWgyEhK5Pji2EWPDPoT4CyQ=="
=> "Lurline"
irb> SymmetricEncryption.encrypt "Lurline"
=> "QEVuQwAAlRBeYptjK0Fg76jFQkjLtA=="

解决方案

Looking at the source for the symmetric-encryption gem, by default it adds a header to the output and base64 encodes it, although both of these are configurable.

To decrypt using Ruby’s OpenSSL directly, you will need to decode it and strip off this header, which is 6 bytes long in this simple case:

ciphertext = Base64.decode64(ciphertext)
ciphertext = ciphertext[6..-1]

c = OpenSSL::Cipher.new("aes-128-cbc")
c.decrypt
c.iv = "1234567890ABCDEF"
c.key = "1234567890ABCDEF"

result = c.update(ciphertext) + c.final

Of course, you may need to alter this depending on what settings you are using in symmetric-encryption, e.g. the header length may vary. In order to decrypt the result from the database you will need to parse the header. Have a look at the source.

这篇关于如何用另一种语言解密由Ruby的“对称加密” gem加密的数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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