web-dev-qa-db-ja.com

Ruby:秘密鍵/公開鍵を使用したファイルの暗号化/復号化

次の要件を満たすファイルの暗号化/復号化のアルゴリズムを探しています。

  • アルゴリズムは信頼できるものでなければなりません
  • かなり大きなファイルの場合、アルゴリズムは高速である必要があります
  • 秘密鍵は、いくつかのパラメーター(パスワードなど)によって生成できます。
  • 生成された秘密鍵は公開鍵と互換性がある必要があります(公開鍵は一度だけ生成され、データベースに保存されます)

提案されたアルゴリズムのRuby実装はありますか?

21
tiktak

注:エンボスがコメントで言及しているように、この回答は実際のシステムには適していません。まず、ファイルの暗号化はこの方法を使用して実行しないでください(たとえば、libはAESを提供します)。第二に、この回答は、ソリューションのエンジニアリング方法にも影響を与える幅広い問題には対応していません。

元のソースも 詳細 に入ります。

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))

から ここ

32
brice

ここでは、認証/承認と機密性という2つの概念を混ぜ合わせて、両方の側面を1つのステップでカバーしようとしていますが、それは機能しません。非対称アルゴリズムで「実際のデータ」を暗号化しないでください。 a)それには遅すぎる、b)正しく行われなかった場合、ソリューションのセキュリティを大幅に弱める微妙な問題があります。

経験則として、秘密の非対称鍵で暗号化する必要があるのは、はるかに高速な対称鍵で使用される対称鍵だけです。アルゴリズム。しかし、ほとんどの場合、そうするべきではありません。なぜなら、90%の場合、実際に必要なのはTLS(SSL)であるためです。その理由を説明しようとしました ここ 少し前に。

あなたの場合、要件は次のとおりだと思います。

  • データベースに保存されるデータの機密性:一般の人々がデータを読み取ったり、アクセスしたりできないようにする必要があります。

  • 選択した少数(おそらく1人だけ)がそのデータにアクセスして読み取ることができるはずです

最初の目標は、通常、 対称暗号化 を使用して達成されます。 2番目の目標は、関連はあるものの、まったく異なる方法で実現することです。ファイルにアクセスするユーザーを認証(つまり、IDを確立)し、さらにユーザーを承認(つまり、確立されたIDに意図したことを実行する権利があるかどうかを確認)する必要があります。これは、非対称暗号化 may がステージに入る場所ですが、必ずしもそうとは限りません。あなたの質問はRails)でタグ付けされているので、私たちはRailsアプリケーションについて話していると思います。通常、そこでユーザーを認証および承認するための何らかの手段がすでにあります(おそらく前述のTLSを含む)、実際のファイルの暗号化/復号化のための対称キーを確立するためにそれらを再利用することができます。 パスワードベースの暗号化 は、この目的に適しています。非対称暗号化をまったく回避したい。すでに機密データの整合性も確保したい場合、つまり、認証および承認されたユーザーに、そのユーザーが何をしているのかという意味で一種の保証を与えたい場合は、事態はさらに複雑になります。最終的に、アクセスはその間に変更されていません。

このためのソリューションを開発することは簡単な作業ではなく、与えられた要件に大きく依存するため、すべての人に適した「ゴールデンウェイ」はないのではないかと思います。いくつかの調査を行い、達成しようとしていることとその方法をより明確に把握してから、まだ不確実/不快に感じている主題について追加のアドバイスを得るようにすることをお勧めします。

11
emboss

対称暗号化 は間違いなく高速で、非常に大きなファイルのストリーミングを優れた方法でサポートしています。

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: '[email protected]') do |writer|
  writer.write('Hello World')
  writer.write('and some more')
end

その他のPGPの例については、ファイルiostreams/lib/io_streams /pgp.rbを参照してください。また、Rubyから直接PGP鍵管理をサポートします。

1
Reid

私はこれを助けるために宝石を作りました。それはcryptosystemと呼ばれます。秘密鍵へのパスとパスワード、および公開鍵へのパスを構成するだけで、後はすべて実行されます。

暗号化は次のように簡単です。

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

そして復号化:

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

GitHub または RubyGems で確認できます。

0
user6713635