【问题标题】:Ruby: file encryption/decryption with private/public keysRuby:使用私钥/公钥进行文件加密/解密
【发布时间】:2012-04-11 02:41:59
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

    注意:正如 emboss 在 cmets 中提到的,这个答案不适合实际系统。首先,不应该使用这种方法进行文件加密(例如,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

    【讨论】:

    • 我实际上不是 Rubyist,但这些都是相当不错的电池。我想知道在 python 中等价物有多难......
    • 只是想补充一点,文件应该用例如AES-256加密,但它的密钥应该用rsa发送。
    • 很抱歉,这确实是个糟糕的建议。 OP 谈论文件加密/解密,你不应该使用 RSA。
    • @emboss:见 tiktak 之前的评论。你是绝对正确的——在想回答这个问题时,我并没有真正停下来考虑更广泛的问题。我会尝试修改我的帖子以显示这一点。
    • @brice:太好了!没有伤害,只是不想让人们被误导:)
    【解决方案2】:

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

    一个好的经验法则是,您最终应该使用私有 非对称 密钥进行加密的是更快的对称算法使用的 对称 密钥。但在几乎所有情况下,您甚至都不应该这样做,因为在 90% 的情况下,您真正​​想要的是 TLS (SSL) - 我刚才试图解释为什么here

    在你的情况下,我假设要求是:

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

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

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

    为此开发解决方案绝非易事,并且在很大程度上取决于您的给定要求,因此恐怕没有适合所有人的“黄金之路”。我建议做一些研究,更清楚地了解您想要实现的目标以及如何实现,然后尝试就您仍然不确定/不舒服的主题获得更多建议。

    【讨论】:

    • 感谢您的回答!我通过以下方式传输和存储数据解决了这个问题:1)生成对称加密密钥(sym-key)2)用sym-key加密文件3)用公共asym-key加密sym-key 4)发送文件并加密sym-key 5) 用用户的秘密令牌解密用户私有加密的 asym-key 6) 用私有 asym-key 解密收到的 sym-key 7) 用解密的 sym-key 解密文件。觉得挺正常的。
    • 这是正确的方向!但它仍然容易受到重放攻击。您不能使用 TLS 代替发送由非对称密钥包装的密钥吗?我发现在几乎所有将数据从 A 传输到 B 的情况下,您都应该使用 TLS 而不是非对称加密 - TLS 可以保护您免受最有可能破坏自定义协议的事情的影响。
    【解决方案3】:

    Symmetric Encryption 速度肯定很快,并且对超大文件的流式传输具有出色的支持。

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

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

    在与其他组织共享文件时,最好的选择是 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 密钥管理。

    【讨论】:

      【解决方案4】:

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

      加密很简单:

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

      和解密:

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

      您可以在GitHubRubyGems 上查看。

      【讨论】:

        猜你喜欢
        • 2021-02-17
        • 2018-07-31
        • 2017-11-25
        • 2017-01-04
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多