在Ruby中加密字符串并在Python中解密

在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,

我是Ruby的新手,如果这个问题很简单,我很抱歉。我必须更新rails应用程序,以便它使用密钥加密字符串。这将传递给一个用django编写的api,在这里,加密的字符串将使用相同的密钥解密。我有以下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的一个薄包装。因此,您可以自己编写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。答案已经更新,应该完全回答了您的问题。