如何使用 Ruby 加密文件?

Posted

技术标签:

【中文标题】如何使用 Ruby 加密文件?【英文标题】:How to encrypt files with Ruby? 【发布时间】:2012-06-18 03:34:20 【问题描述】:

我需要编写一个加密/解密文件的简单工具。

我猜最好的方法是使用 OpenSSL:

生成密钥:

openssl rand -base64 2048 > secret_key

加密文件:

openssl aes-256-cbc -a -e -in file -out file.enc -k secret_key

解密文件:

openssl aes-256-cbc -d -in file.enc -out file -k secret_key

有没有一种简单的方法可以在 Ruby 中实现这一点?有没有更好的方法来做到这一点?也许使用 PGP?

【问题讨论】:

那么究竟是什么问题:使用 OpenSSL 而无需调用外部程序? 解密命令应该是:openssl aes-256-cbc -d -a -in file.enc -out file -k secret_key,否则你会得到一个bad magic number 【参考方案1】:

Ruby 的 OpenSSL 是 OpenSSL 本身的一个精简包装器,并提供了几乎所有 OpenSSL 本身的功能,所以是的,您的所有示例都有一个一对一的映射:

openssl rand -base64 2048 > secret_key

这其实有点夸张,你使用的是 AES-256,所以你只需要一个 256 位的密钥,你这里没有使用 RSA。 Ruby OpenSSL 将这个决定从您的肩上卸下,它会根据您要使用的算法自动确定正确的密钥大小。

您也犯了在加密期间使用确定性 IV 的错误。为什么?因为您根本没有指定 IV,所以 OpenSSL 本身将默认为全零字节的 IV。这不是一件好事,所以我将向您展示正确的方法,更多信息请查看Cipher documentation。

require 'openssl'

# encryption
cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv

buf = ""
File.open("file.enc", "wb") do |outf|
  File.open("file", "rb") do |inf|
    while inf.read(4096, buf)
      outf << cipher.update(buf)
    end
    outf << cipher.final
  end
end

# decryption
cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.decrypt
cipher.key = key
cipher.iv = iv # key and iv are the ones from above

buf = ""
File.open("file.dec", "wb") do |outf|
  File.open("file.enc", "rb") do |inf|
    while inf.read(4096, buf)
      outf << cipher.update(buf)
    end
    outf << cipher.final
  end
end

如您所见,加密和解密非常相似,因此您可能可以将流式读/写合并到一个共享方法中,只需将正确配置的Cipher 加上相应的文件名传递给它,我只是明确说明了它们为了清楚起见。

如果您想对密钥(可能还有 IV)进行 Base64 编码,您可以使用 Base64 模块:

base64_key = Base64.encode64(key)

【讨论】:

我想知道这个答案是否需要任何更新,如果是这样,添加一些会很好。【参考方案2】:

Ruby 有一个 OpenSSL library,应该负责处理繁重的工作。

【讨论】:

谢谢。我可能需要迁移到 PGP,因为它支持文件的 PKI(我的文件很小),所以我可以轻松地支持多个用户,而不会遇到存储密钥的问题。 @Istvan OpenSSL 也支持 PKI。

以上是关于如何使用 Ruby 加密文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 jruby9.1.2.0 中使用 PGP 加密对文件进行加密?

如何在应用程序级别加密 ruby​​ on rails 中的完整路由

如何在 Ruby 中使用('DES/CBC/PKCS5Padding'模式)实现 DES 加密?

如何将 128 CFB 加密为 Ruby?

Web Crypto API:如何使用导入的 RSA 公钥加密数据并在 Ruby 中解密数据

加密空字符串