轨道加密/解密

Posted

技术标签:

【中文标题】轨道加密/解密【英文标题】:rails encryption/decryption 【发布时间】:2012-01-23 07:46:42 【问题描述】:

我需要在我的 Rails 应用程序中进行加密和解密。我尝试使用 ezcrypto,但每当我解密时都会出现此错误。

OpenSSL::Cipher::CipherError in ProfilesController#show

wrong final block length

需要更改哪些内容才能阻止此错误。我尝试使用这样的 openssl 的另一种实现(从我的模型中调用的方法)

def encrypt_attr(unencrypted)
    c = OpenSSL::Cipher.new("aes-256-cbc")
    c.encrypt
    c.key = Digest::SHA1.hexdigest('pass')
    e = c.update(unencrypted)
    e << c.final
    return e
end

def decrypt_attr(encrypted_attr)
  if encrypted_attr != ""
    c = OpenSSL::Cipher::Cipher.new("aes-256-cbc")
    c.decrypt
    c.key = Digest::SHA1.hexdigest('pass')
    d = c.update(encrypted_attr)
    d << c.final
    return d
  end
end

它在解密时抛出完全相同的错误。我应该如何进行加密和解密而不得到这个openssl错误。

【问题讨论】:

嗯,我的错,你在c.key中确实有相同的密钥 为我工作。仅当 encrypted_attr != e 来自 encrypt_attr 方法时,我才会收到此错误。在这种情况下,您应该在 decrypt_attr 方法中使用 rescue @jack,出于好奇,如果您使用密码块链接,您的初始化向量在哪里?参见 5.3,初始化向量,csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf 看看这个***.com/questions/2711709/… 【参考方案1】:
require 'openssl'
require 'base64'

class AesEncryptDecrypt

  KEY = "EncryptDecryptGurudathBN"
  ALGORITHM = 'AES-128-ECB'

  def self.encryption(msg)
    begin
      cipher = OpenSSL::Cipher.new(ALGORITHM)
      cipher.encrypt()
      cipher.key = KEY
      crypt = cipher.update(msg) + cipher.final()
      crypt_string = (Base64.encode64(crypt))
      return crypt_string
    rescue Exception => exc
      puts ("Message for the encryption log file for message #msg = #exc.message")
    end
  end

  def self.decryption(msg)
    begin
      cipher = OpenSSL::Cipher.new(ALGORITHM)
      cipher.decrypt()
      cipher.key = KEY
      tempkey = Base64.decode64(msg)
      crypt = cipher.update(tempkey)
      crypt << cipher.final()
      return crypt
    rescue Exception => exc
      puts ("Message for the decryption log file for message #msg = #exc.message")
    end
  end
end

加密

irb(main):007:0> AesEncryptDecrypt.encryption('gurudath')
=> "rUPKObydUJd9cY9agm3Glw==\n"

解密

irb(main):008:0> AesEncryptDecrypt.decryption('rUPKObydUJd9cY9agm3Glw==')
=> "gurudath"

【讨论】:

什么是padding机制,上面程序中如何使用PKCS5Padding加密数据 我使用相同的算法,但我的密钥是 OpenSSL::PKey::RSA 类型,当我们将密钥设置为 cipher.key = KEY 时抛出 no implicit conversion of OpenSSL::PKey::RSA into String 异常 注意,ECB mode is insecure【参考方案2】:

我知道 Ruby 的 openssl 包的文档非常少。但是,如果您想使用 cipher-block chaining,这里有一段简短的 sn-p 代码,概述了如何使用 AES-256-CBC 密码:

require 'openssl'

# your data
raw  = 'the data to be encrypted goes here'
pwd  = 'secret'
salt = OpenSSL::Random.random_bytes(8)

# prepare cipher for encryption
e = OpenSSL::Cipher.new('AES-256-CBC')
e.encrypt
# next, generate a PKCS5-based string for your key + initialization vector 
key_iv = OpenSSL::PKCS5.pbkdf2_hmac_sha1(pwd, salt, 2000, e.key_len+e.iv_len)
key = key_iv[0, e.key_len]
iv  = key_iv[e.key_len, e.iv_len]

# now set the key and iv for the encrypting cipher
e.key = key
e.iv  = iv

# encrypt the data!
encrypted = '' << e.update(raw) << e.final
p encrypted

# and now we prepare to decrypt
d = OpenSSL::Cipher.new('AES-256-CBC')
d.decrypt
# now set the key and iv for the decrypting cipher
# this assumes that the password, salt, and iv are known,
# so then you would be able to generate the key as per above
d.key = key
d.iv  = iv

# decrypt the data!
decrypted = '' << d.update(encrypted) << d.final
p decrypted

这个 sn-p 几乎一字不差地取自 Japanese (original?) version of the Ruby standard library documentation on openssl。但是,它确实为您和您的应用程序设计提出了一些问题:

    您需要保存salt 值。这与密码一起用于生成密钥(您不需要保存密钥)。 您需要保存iv 初始化向量。这用于启动密码块链中的第一个块。无需加密此值,但应为您加密的每条消息生成此值。

祝你好运!

【讨论】:

【参考方案3】:

我遇到了和你一样的问题,我就是这样解决的:

    您的数据库列必须是:t.column :data, :binary, :limit => 10.megabyte。 使用准确的代码this blog post。 选择 AES-256-ECB 将 ivs 设为 nil 选择一个长键

【讨论】:

以上是关于轨道加密/解密的主要内容,如果未能解决你的问题,请参考以下文章

RSA 加密解密

为啥公钥加密只能私钥解密而不能公钥解密

C 语言文件操作 ( 文件加密解密 | 加密解密原理 | 对称加密 | 非对称加密 | 散列函数 )

Delphi RSA加解密 (RSA公钥加密,私钥解密)(RSA私钥加密,公钥解密)MD5加密SHA加密

java密码加密与解密

针对url的加密与解密