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

时间:2016-06-15 03:48:52

标签: 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, 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:] ))

1 个答案:

答案 0 :(得分:1)

在ArtjomB的反馈之后,我深入研究了拟议的图书馆。它只不过是红宝石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的长度倍数的字符串。)

AES Python encryption and Ruby encryption - different behaviour? colinm 的答案非常有用。