web-dev-qa-db-ja.com

非対称暗号化/復号化ルーチンの簡単な例はありますか?

Java、Perl、JavaScriptのコードはよく理解できます。残りは勉強していませんが、読み方・翻訳方法は理解できたと思います。

最も単純な非対称ルーチンが何であるか知りたいのですが。本当に複雑すぎて心配したくないですか?

暗号化専用のキーを作成する方法に興味があります。それがリバースエンジニアリングに抵抗することができるので、私はそれがどのように機能するのか知りたいので、私には驚くほどです!

  1. 複雑すぎますか。
  2. 実装を検索できる最も単純な標準の非対称暗号化ルーチン(の1つ)は何ですか?
  3. 場合は、ニースになる最小限のコード例があります。

私はすでに ウィキペディアの動作方法に関する段落 を確認しましたが、数学的分類や実装の説明はなく、 実装の数 のみでした。私は実際にどれを見るかをランダムに選びたくありませんでしたし、最も堅牢で最も複雑であると予想される最も一般的なものを選びたくもありませんでした。

何かご意見は?

11
Bryan Field

クレジットは、詳細については Jeffの回答 に、 Steveの回答 も参考になりました。クレジットは tylerl's answer にも適用され、すべての機能、特に modInverse のWikipediaへのリンクが含まれ、eありがとうございます。私はあなたの回答に賛成し、3つすべての回答の組み合わせた情報を使用して、より良い回答になることを願っています。

作るための鍵リバースエンジニアリングはとても高価なので、power-ofを使用しています。平方根はそれほど難しくありません。3の累乗は、3乗根が必要であることを意味しますが、34,051,489の累乗はかなり難しいです。他にリバースエンジニアリングが難しい数学演算があります。非対称アルゴリズムを作成する方法もいくつかありますが、この答えはRSAに焦点を当てています。最も古く、最も一般的です。

RSAアルゴリズムthe Java Code に基づく)

以下の計算は 任意の精度の整数 で行う必要があります。 (BigIntやBigIntegerなど)

キーの生成:

  • 一定のキーの長さはlです。
  • 通常、定数_e_start_は、単純にするために_=3_にすることができます。ただし、_0x10001_がより一般的です。いずれにしても、素数が最適です(キー生成のパフォーマンス上の理由から、おそらく他の理由から)。
  • pqはランダムに生成された正の素数であり、格納には最大lビットが必要です。 (これらを正に保つために、最初のビットは常に_0_になります)
  • n = _p*q_これは、暗号化と復号化の両方に使用されます。
  • eは_e_start_で始まります。これは最終的に暗号化キーの一部になります。
  • m = _(p-1)*(q-1)_は、edに変換するために使用されます。これは、復号化に使用されます。
  • _while(_ gcd _(e,m)>1){e+=2}_これは、次のステップが機能するために必要です。
  • _d=_ modInverse _(e,m)_これは、標準の算術演算を実行します。おそらく、特にプログラミング言語にこれが組み込まれている場合は、詳しく調べる価値はありません。

暗号化または復号化するには、最初にバイトを単一の任意精度整数に変換します。

暗号化:encrypted=(plain^e)%n

注:_plain>=n_の場合、plainを2つ以上の小さい値に分割し、個別に暗号化する必要があります。

復号化:plain=(encrypted^d)%n

非対称暗号化は通常、対称暗号化よりも効率的ではありません。非対称暗号化は、鍵交換にのみ使用される場合があります。

6
Bryan Field

RSAに関する限り、 this は従うことができる良い例を提供し、対応する入力と出力の例を示します。この demo アプリケーションは、さまざまな手順を説明し、作業を確認できるようにします。時々、そのような手順で何かをクリックするだけで解決する場合があります。ウィキペディアの記事については、実際のアルゴリズムの記事を見る必要があります: [〜#〜] rsa [〜#〜] 対応する数学について。

実装に関しては、Java in 行以下 で明確にまとめることができます。

理解のために、暗号化専用のキーなどはありません。むしろ、パートナーの操作を逆にする2つの等しいキーがあります。ペアの1つをプライベートとして、もう1つをパブリックとして割り当てます。一方のキーで暗号化されたものは、もう一方のキーで復号化できます。これは、署名で使用される原則です。

キーを安全にするのはアンチリバースエンジニアリングの問題ではなく、大規模なキースペースを(キーが非常に大きい数のスペースを使用する場合)合理的にチェックして一致するキーを見つけることができないという数学的な概念です。因数分解作業の本当のスピードアップはありません。

学ぶべき他の非対称鍵アルゴリズムがありますが、あなたが凝視しているように、私は最初に最も古く、最も一般的なRSAを理解しようと思います。

13
Jeff Ferland

pythonを使用してRSAのデモンストレーションをまとめました(これまでに見たことがない場合でもPythonは非常に読みやすいです)。コードが十分に長いため、シングルに適合しませんページですが、数分で読み、理解できるほど短いです。

暗号化/復号化は単一の組み込みコマンド--_exp(PLAINTEXT,KEY,MODULUS)--で実行できるので、鍵導出プロセス全体も実行します。

コードはここにあります: https://Gist.github.com/1239116

コードを実行すると、>12345または<12345の形式で入力するよう求められます。ここで、>プレフィックスは、秘密鍵を番号に適用するように指示しますが、<は、公開鍵を適用するように指示します。単純化のために、数値のみをエンコードします。しかし、それができたら、任意のデータのエンコードはフォーマットの問題にすぎません。

6
tylerl

実際、私が理解しているように、その周りの数学はかなり単純です。途方もなく大きい素数(数千桁)の累乗の値を取り、別の数からmodを実行します。

暗号化するには、次のようにします:EncryptedBits =(PlainText ^ YourPublicKey)%Modulus

そして解読するには、次のようなものがあります:PlainText =(EncryptedBits ^ YourPrivateKey)%Modulus

私はそれについてかなり読みやすいドキュメントをここで見つけました: http://mathaware.org/mam/06/Kaliski.pdf

しかし、どのライブラリを見ればよいかわかりません。

5
Steve

かわいい、最小限のPerlソリューションが必要な場合は、 1995 のAdam Backによるクラシックなソリューションがあります。

This T-shirt is a Munition」という文とともに、コンピューターで読み取れるようにバーコードを含めてTシャツに印刷されました。強力な暗号化が1996年に 再分類されて 技術的に「軍需品」ではなくなる前に、その声明は米国で正確でした。しかし、輸出管理規則(EAR)が2000年に 改正されるまで、米国から強力な暗号を輸出することは依然として広く違法でした

このソフトウェアは、タトゥー、電子メールの署名、宛名ラベル、その他の多くの形式でも配布され、 New York Times (記事、写真なしで、 Between a Hacker And a Hard Place )でオンラインです。より最近の2行バージョンは次のとおりです。

print pack"C*",split/\D+/,`echo "16iII*o\U@{$/=$z;[(pop,pop,unpack"H*",<>
)]}\EsMsKsN0[lN*1lK[d2%Sa2/d0<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<J]dsJxp"|dc`

元のアプローチは、Unixの「dc」プログラムに依存して任意精度の演算を行っていることに注意してください。アノテーション付きの純粋なPerlバージョンは、

2
nealmcb