我是 Ruby 新手,所以如果这个问题很简单,我深表歉意。我必须更新 Rails 应用程序,以便它使用 key 加密字符串。它被传递到用 django 编写的 api,其中加密的字符串将使用相同的 key 进行解密。我在 Python 中有以下代码,但我不确定如何在 Ruby 中加密相关消息。任何帮助将不胜感激。
import base64
from Crypto.Cipher import AES
from Crypto import Random
class AESCipher:
def __init__( self, key ):
self.key = key
def encrypt( self, raw ):
raw = pad(raw)
iv = Random.new().read( AES.block_size )
cipher = AES.new( self.key, AES.MODE_CBC, iv )
return base64.b64encode( iv + cipher.encrypt( raw ) )
def decrypt( self, enc ):
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] ))
最佳答案
根据 ArtjomB 的反馈,我更深入地研究了提议的库。它只不过是 ruby openssl 的一个薄包装。因此您可以自己编写 AESCipher 的 Ruby 版本。 经过一番摆弄和研究才找到正确的方法:
require 'base64'
require 'securerandom'
require 'openssl'
class AESCipher
attr_reader :key
def initialize(key)
@key = key
end
def encrypt(raw)
iv = SecureRandom.random_bytes(16)
cipher = build_encription_cipher(iv)
encrypted = cipher.update(raw) + cipher.final
Base64.encode64(iv + encrypted)
end
def decrypt(data)
data = Base64.decode64(data)
iv, raw = data[0..15], data[16..-1]
cipher = build_decrypt_cipher(iv)
cipher.update(raw) + cipher.final
end
private
def build_encription_cipher(iv)
OpenSSL::Cipher::AES.new(128, :CBC).tap do |cipher|
cipher.encrypt
cipher.key = key
cipher.iv = iv
cipher.padding = 0
end
end
def build_decrypt_cipher(iv)
OpenSSL::Cipher::AES.new(128, :CBC).tap do |cipher|
cipher.decrypt
cipher.key = key
cipher.iv = iv
cipher.padding = 0
end
end
end
在我的测试用例中,ruby 版本解密了由 python 加密的字符串,反之亦然。
(我对你的 python 代码做了一项修改:删除对 pad
的调用,因为我不知道它是如何填充的。并且只使用了长度为 16 倍数的字符串)。
colinm 在 AES Python encryption and Ruby encryption - different behaviour? 中的回答非常有用。
关于python - 在 Ruby 中加密字符串并在 Python 中解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37825758/