如何用另一种语言解密由Ruby的“对称加密” gem加密的数据? [英] How do I decrypt data encrypted by Ruby's `symmetric-encryption` gem in another language?
问题描述
我想访问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屋!