web-dev-qa-db-ja.com

PGPが対称暗号化とRSAを使用するのはなぜですか?

Pretty Good Privacyの詳細を見ると、セッションキーを使用してメッセージを暗号化し、RSAを介して受信者の公開キーを使用してキーを暗号化する背後にある理由について混乱しています。これが実際のメッセージを直接RSA暗号化するよりも安全であることを確認できません。

セキュリティと暗号化の点で単純すぎると思う可能性が高いですが、RSA秘密キーを取得できた場合、メッセージの本文またはメッセージのロックを解除する他のキーにアクセスできるかどうかが問題になるのはなぜですか。体?

23
Ken Bellows

RSAは、プレーンテキストの大きな部分を暗号化するために実際に構築されていません。各RSAの「ラウンド」は117バイトのデータを暗号化できます。さらに暗号化するには、いくつかの チェーンモード を使用する必要があります。現在、これは追加のオーバーヘッド、速度低下(RSAはかなり遅いことを忘れないでください)、およびセキュリティの不確実性(RSA-chaningModeは他の種類の暗号化スキームとして精査されていません)を意味します。 <-BAD

ハイブリッド暗号化 (対称鍵の場合は対称+非対称)を使用すると、非対称の利点が得られます。つまり、鍵の交換について心配する必要がなくなります。対称的で、非常に高速で、十分に吟味されています。 <-GOOD

詳細については、次を確認してください。 RSAなどの非対称暗号化を使用して、任意の長さの平文を暗号化するにはどうすればよいですか?

34
Adi

RSAは、特に復号化の場合、低速のアルゴリズムです。 _m = c^d mod N_を計算する必要があります。ここで、dはおおよその係数のサイズです。 RSA-1024/2048/4096(1024/2048/4096はモジュラスNのバイト数)の場合、二乗を繰り返すことによる高速なモジュラー指数計算でも、約1.5 lg N(〜1500 /〜3000 /〜6000)が必要です。 Nビット整数の乗算。 Nビット整数の乗算はプリミティブ演算ではありませんが、nビット整数の場合はO(N ^ 1.6)としてスケーリングされます(したがって、各乗算は64ビット乗算プリミティブより約84/256/776倍遅くなります)。

注:RSA暗号化は復号化よりも大幅に高速です。適切なパディングを使用すると、e = 65537のような小さな公開鍵指数を選択するのに弱点がありません。実際、2つの乗算のみを必要とするe = 3は、適切なパディングで完全に正常に機能します。

さらに、bビットRSAの1つのアプリケーションは、おおよそその長さの2つの素数を生成する必要があったことを意味します)約b-128ビット(128ビットのランダムパッドを使用)またはおおよそ112/240/0〜Nの数値のみを一意にデコードするため、496バイト。8ビットASCIIエンコーディングでのこの回答には7449バイトが必要です。

したがって、対称キーの方がはるかに高速であり、暗号化モード(CBC、CTRなど)を使用して任意のサイズのメッセージを暗号化できるため、通常は対称キーを暗号化するだけです。


上記の分析を正当化するタイミング情報

4096ビットのRSA鍵ペア(N、e)と(N、d)をランダムに作成し(import rsa; rsa.newkeys(nbits=4096)を使用)、「教科書」を比較するタイミングをとった(弱い-ランダムバイトが埋め込まれていない)RSA暗号化/ AES暗号化への復号化。

タイミングRSAの設定は、暗号化/復号化の下にあります。

_>>> encryption = "pow(m,e,N)"
>>> decryption = "pow(c,d,N)"
>>> setup =  """N = 650022002033202164791638561174816123258916492020045683486079596172818033518252144860009135975860423604411399274822133841546708494765449009472683563317182198759309684914356008659922538583279515419473227210977474088638850782595732910857797571156318425669817244314450827318145758475770172116229990603884173470104902799641093008914867436680133631971559712828465243806241512864086546090728020169682901285441149037545107765998640217114788723715575098893307499744794060936075307573516246976128444578474543743151813381476261995022381469996299316134038828450334308951123635607639233510908350391842701316709834010335732144351192249236953330927673972067894385163240378028762678952835544528074929660347162229394149982403274141710996800529609644247153732931740566379474447028470447165473543764460712691302632667942726305345440613110797535733482536487121364569032950159436896042439632454394173272272373593467791776848612054118558722637286863035388661691125609333937871344046274188817824229897604542696165894703693345718292207375417809743565484488696015562272970275127353631067240331072960179800283770558952793368549384848991363395614092594834723746484679602433778811932755737361396956451757817273043140309312219744371338360280947729616063853738641

e = 65537

d = 163256819101675505935126275492278764497028632049833711493978518287449606050176698725845711249563797130302144316394896364372168726426893063398086141449880510117616574052677112204439095245140620165777031598832556014144612720776443287192263118867708337069520909431555619232749121633751575949969416441703671137188560661642925231956585104715733090960096935672315454064890600755952584778878850298197667808388563912873529057301030226798746088352508752731797937742028323588321094384242144517250929974849184277771012531228150089843422784017258750683831715157735366668225506845014904307329056055723208632277201486994123654288753880392020556964543443597828229493325467616467308118864809565200248599428162198788308364968380312577988297310500286974136209331121821893719017982045957945241683426015912952303440579610553088057331105677592306795472995839704525934407019706992740653789223747419222232691256397983243926154436341276701812083801394467756814989897357722664273229362826815661611670740504736110949984419908621950792127278167263015929591331285519955311164883226113070661776218890597216617564529563317568347817244502395174702566462626236588608296425638109493962233171124725237010153412040065506840529586822535766472003407847003802265141256193

m= int("This is a secret message provided as a test for RSA-4096 and AES encryption.  To be fair it is 496 bytes long.  Keyboard mashing follows: asdbklajsdgl;sdjgl;kasjdgiowepgj opijg aslekgjase;lgk jasel; elask;gj lask;lgjl;ske gjasle;k asel;k gjl;asekgj asljsel;k jseal; gkjasel; kjsael;kjg aal;se asegkl;j asel;kjasegl;k jasegl;k jasel;gk jasegl;k jasel gkjsael;gkjasel;gkj sea;lekgjseal;kjasegl;asekgjasel;kgjsael;jkasel;gjkgasel;asfasfl;kjasf;lkjsadfkljdl;kfaskl;jfasldk;fkfkjl;akasdfasdfasdfkjkjga".encode('hex'),16)
c = pow(m, e, N)
"""
>>> import timeit
>>> timeit.repeat(encryption, setup=setup, repeat=3, number=1)
[0.0044488906860351562, 0.0045480728149414062, 0.0044538974761962891]

>>> timeit.timeit(decryption, setup=setup, repeat=3, number=1)  
[1.9231810569763184, 1.9048171043395996, 1.9280149936676025]
_

4096ビットのRSA暗号化は1回の実行あたり約4.5ミリ秒かかり、復号化には1.9秒かかります(dはeよりはるかに大きいため、暗号化よりも約500倍遅くなります)。このメッセージをRSAで暗号化するには、16ブロックが必要であり、復号化には最大30秒かかります。他のRSAサイズについて繰り返しますが、1024ビットのRSAは暗号化に約0.5ミリ秒、復号に40ミリ秒かかることがわかりました。 2048ビットRSAは、暗号化に約1.6ミリ秒、復号化に約270ミリ秒かかります。

次に、pycryptoライブラリを使用したAES-128を見てみましょう。

_setup = """
from Crypto.Cipher import AES 
from Crypto import Random
from hashlib import sha256

def aes_encrypt(plaintext, key):
    block_size = AES.block_size
    iv = Random.new().read(block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    pad_len = block_size - (len(plaintext) % block_size)
    padding = ''.join([chr(pad_len)]*pad_len)
    encrypted_msg = iv + cipher.encrypt(plaintext + padding)
    return encrypted_msg

def aes_decrypt(encrypted_msg, key):
    block_size = AES.block_size
    iv = encrypted_msg[:block_size]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_msg = cipher.decrypt(encrypted_msg[block_size:])
    pad_len = ord(padded_msg[-1])
    msg = padded_msg[:len(padded_msg)-pad_len]
    return msg

key = sha256("secret passphrase").digest()[0:16]
message = "This is a secret message provided as a test for RSA-4096 and AES encryption.  To be fair it is 496 bytes long.  Keyboard mashing follows: asdbklajsdgl;sdjgl;kasjdgiowepgj opijg aslekgjase;lgk jasel; elask;gj lask;lgjl;ske gjasle;k asel;k gjl;asekgj asljsel;k jseal; gkjasel; kjsael;kjg aal;se asegkl;j asel;kjasegl;k jasegl;k jasel;gk jasegl;k jasel gkjsael;gkjasel;gkj sea;lekgjseal;kjasegl;asekgjasel;kgjsael;jkasel;gjkgasel;asfasfl;kjasf;lkjsadfkljdl;kfaskl;jfasldk;fkfkjl;akasdfasdfasdfkjkjga"
cipher = aes_encrypt(message,key)
"""

>>> timeit.repeat("aes_encrypt(message,key)", setup=setup, repeat=3, number=1)
[6.198883056640625e-05, 6.198883056640625e-05, 6.008148193359375e-05]

>>> timeit.repeat("aes_decrypt(cipher,key)", setup=setup, repeat=3, number=1)
[1.0967254638671875e-05, 9.059906005859375e-06, 9.059906005859375e-06]
_

ボトムライン、AES暗号化はおおよそ8/25/5 RSAよりも高速で、AES復号化は約4000/25000/2000 RSAよりも高速です(それぞれ1024/2048/4096ビット暗号化)。したがって、ハイブリッド暗号化は、複数のブロックが必要な場合は常に意味があります。

10
dr jimbob

3年前に私が書いたものから:「私たちが日常的に使用する暗号化には、2つの基本的なタイプがあります。誰もがそれを使用します。私のおばあちゃんも。

タイプ1は対称、別名シングルキー、別名シークレットキー、別名超高速...すべてのS単語がどのように組み合わされるかに注意してください:)

タイプ2は非対称、別名公開鍵/秘密鍵(または単に公開鍵)、別名2鍵、別名暗号化が遅い。これは、人々がPGPを使用するときに一般的に使用していると考えるものです。 (そうですが、作業の大部分を行うために対称暗号化も使用しています) " http://www.infosecisland.com/blogview/4497-Public-Key-Private-Key-Secret-Key- Everyday-Encryption-.html

基本的に、上記のjimbob博士が示したように、公開鍵はバルク暗号化に使用するには遅すぎます。それを対称と組み合わせるとそれが修正され、対称のみを使用しない理由は鍵交換の問題です。目的の受信者が確実にキーを取得し、それらがキーを取得する唯一の人であることを他にどのように保証しますか?

2
Rod MacPherson

これが役立つもう1つの理由は、柔軟性が向上するためです。たとえば、セッションキーのみを暗号化すると、オーバーヘッドが比較的少ない複数のキーペアを使用できます。鍵ペアごとに暗号化されたセッション鍵を追加するだけです。

1
Tim Lamballais