在Ruby中加密字符串并在Python中解密
我是Ruby的新手,如果这个问题很简单,我很抱歉。我必须更新rails应用程序,以便它使用密钥加密字符串。这将传递给一个用django编写的api,在这里,加密的字符串将使用相同的密钥解密。我有以下Python代码,但我不确定如何用Ruby加密相关消息。任何帮助都将不胜感激在Ruby中加密字符串并在Python中解密,python,ruby-on-rails,ruby,django,encryption,Python,Ruby On Rails,Ruby,Django,Encryption,我是Ruby的新手,如果这个问题很简单,我很抱歉。我必须更新rails应用程序,以便它使用密钥加密字符串。这将传递给一个用django编写的api,在这里,加密的字符串将使用相同的密钥解密。我有以下Python代码,但我不确定如何用Ruby加密相关消息。任何帮助都将不胜感激 import base64 from Crypto.Cipher import AES from Crypto import Random class AESCipher: def __init__( self,
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的一个薄包装。因此,您可以自己编写AESChipher的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
的调用,因为我不知道它是如何pad的,只使用了长度为16倍的字符串)
colinm的回答非常有用。我认为对于日常ruby用户来说,这并不是一个简单的问题。也许将加密/解密委托给底层系统更容易(即运行shell命令)。这样,Ruby和Python都可以使用相同的API。答案已经更新,应该完全回答了您的问题。