Ruby:使用私钥/公钥进行文件加密/解密

时间:2012-03-27 14:36:26

标签: ruby-on-rails ruby encryption public-key-encryption encryption-asymmetric

我正在寻找一种满足以下要求的文件加密/解密算法:

  • 算法必须可靠
  • 对于相当大的文件,算法应该很快
  • 私钥可以通过某些参数(例如,密码)生成
  • 生成的私钥必须与公钥兼容(公钥只生成一次并存储在数据库中)

是否有建议算法的Ruby实现?

4 个答案:

答案 0 :(得分:32)

  

注意:在评论中提到压纹,这个答案很适合实际系统。首先,不应使用此方法执行文件加密(例如,lib提供AES)。其次,这个答案并没有解决任何影响你如何设计解决方案的更广泛的问题。

     

原始来源也会进入more details

Ruby可以使用openssl来执行此操作:

#!/usr/bin/env ruby

# ENCRYPT

require 'openssl'
require 'base64'

public_key_file = 'public.pem';
string = 'Hello World!';

public_key = OpenSSL::PKey::RSA.new(File.read(public_key_file))
encrypted_string = Base64.encode64(public_key.public_encrypt(string))

解密:

#!/usr/bin/env ruby

# DECRYPT

require 'openssl'
require 'base64'

private_key_file = 'private.pem';
password = 'boost facile'

encrypted_string = %Q{
...
}

private_key = OpenSSL::PKey::RSA.new(File.read(private_key_file),password)
string = private_key.private_decrypt(Base64.decode64(encrypted_string))

来自here

答案 1 :(得分:11)

我担心你在这里混合了两个概念,即身份验证/授权和机密性,试图在一个步骤中涵盖这两个方面,这是行不通的。您永远不应该使用非对称算法加密“真实数据”。 a)它们太慢了,b)有一些微妙的问题,如果做得不好,将严重削弱你的解决方案的安全性。

一个好的经验法则是,您应该使用私有非对称密钥加密的唯一方法是使用更快的对称算法使用的对称密钥。但在几乎所有情况下你都不应该这样做,因为在90%的情况下你真正想要的是那些情况下的TLS(SSL) - 我试着解释为什么here不久前。

在您的情况下,我认为要求是:

  • 要存储在数据库中的数据的机密性:一般公众不应该阅读它(甚至不能访问它)

  • 选定的几个人(可能只有一个人)应该能够访问和阅读该数据

通常使用symmetric encryption来实现第一个目标。第二个目标虽然是相关的,但却是通过完全不同的方式实现的。您希望访问该文件的用户进行身份验证(即建立身份),最重要的是您还希望他们获得授权(即检查已建立的身份是否有权按照他们的意图行事)。这是非对称加密可能进入舞台的地方,但不一定如此。由于你的问题用Rails标记,我假设我们正在讨论Rails应用程序。您通常已经有一些方法来对那里的用户进行身份验证和授权(很可能涉及上述TLS),您可以简单地重用它们以便为实际文件加密/解密建立对称密钥。如果您想要避免不对称加密,Password-based encryption适合此目的。如果您还想确保已经保密的数据的完整性,事情变得更加复杂,也就是说,您希望为经过身份验证和授权的用户提供一种保证,即他们最终访问的内容没有以任何方式被更改同时。

为此制定解决方案将不是一项微不足道的任务,并且在很大程度上取决于您的要求,所以我担心没有适合每个人的“黄金方式”。我建议做一些研究,更清楚地了解你想要实现的目标和方法,然后尝试获得有关你仍感到不确定/不舒服的主题的额外建议。

答案 2 :(得分:0)

我做了一个宝石来帮助解决这个问题。它被称为cryptosystem。只需配置私钥的路径和密码以及公钥的路径,剩下的工作就完成了。

加密非常简单:

rsa = Cryptosystem::RSA.new
rsa.encrypt('secret') # => "JxpuhTpEqRtMLmaSfaq/X6XONkBnMe..."

并解密:

encrypted_value = rsa.encrypt('secret') # => "Y8DWJc2/+7TIxdLEolV99XI2sclHuK..."
rsa.decrypt(encrypted_value) # => "secret"

您可以在GitHubRubyGems上查看。

答案 3 :(得分:0)

Symmetric Encryption肯定很快,并且非常支持非常大的文件流。

SymmetricEncryption::Writer.open('my_file.enc') do |file|
  file.write "Hello World\n"
  file.write "Keep this secret"
end

Symmetric Encryption旨在加密组织内的数据和大型文件。

在与其他组织共享文件时,最好的选择是PGP。对于使用PGP传输非常大的文件,请考虑:IOStreams

IOStreams.writer('hello.pgp', recipient: 'receiver@example.org') do |writer|
  writer.write('Hello World')
  writer.write('and some more')
end

查看文件iostreams / lib / io_streams / pgp.rb以获取更多PGP示例。它还直接从Ruby支持PGP密钥管理。