9

私はRSAについて非常に基本的な理論的知識しか持っていません。

実際の使用方法についてさまざまな情報源を読んでいる間、PKCS#1OAEPは良いことのように思われました。

テストの実装には、PyCryptoでPythonを使用します。たとえば、これはPKCS#1OAEPを使用した例です。

公開鍵を使用して暗号化し、次に秘密鍵を使用して復号化すると、正常に機能します。たとえば、公開鍵を使用して、公開鍵を使用してX氏にデータを送信できます。

RSAの仕組みについての基本的な理解から、公開鍵と秘密鍵を交換するだけでよいと思いました。つまり、暗号化には公開鍵を使用し、復号化には秘密鍵を使用できます。たとえば、人物Xは独自の秘密鍵を使用して一部のデータを暗号化し、公開鍵を使用して公開鍵を復号化できます。復号化が正常に機能する場合、これにより、データが人物Xからのものであるという何らかの証拠が得られます。

公開鍵を使用して復号化しようとすると、PyCryptoが文句を言います。

PyCryptoソースコードを読むと、_RSAKey._decrypt関数(ここ)で、キーオブジェクト自体が秘密キーか公開キーかを認識しており、それらの間で異なるように見えます(驚いたことに、RSAの非常に基本的な理解に基づいています)。

そこから、公開鍵を使用するように復号化機能をハックできるようです。または、多少異なる方法です。キーオブジェクトのパブリック指数eとプライベート指数を入れ替えることができます。d

しかし、これはすべて、このように使用/ハッキングされることを意図したものではないようです。それで、私はここで私の誤解について尋ねたかったのです。

また、好奇心から、いくつかのキー()を生成し、、、をRSA.generate(2048)調べましnた。すべての場合において、そしてすべての場合において一定(65537)である間、非常に巨大でした(私はそれを予期していなかったでしょう)。ednde

これらすべてから、私は本当に単に交換するべきではないと思いeますd

したがって、PKCS1_PSSのような署名には他の方法を使用する必要があると思います。


誰かが興味を持っているなら、暗号化/復号化のためのいくつかのコード:

def randomString(l):
    import random
    return ''.join(chr(random.randint(0, 0xFF)) for i in range(l))

def genkeypair():
    from Crypto.PublicKey import RSA
    key = RSA.generate(2048)
    pubkey = key.publickey().exportKey("DER")
    privkey = key.exportKey("DER")
    return (pubkey,privkey)

def encrypt(v, rsapubkey):
    from Crypto.PublicKey import RSA
    rsakey = RSA.importKey(rsapubkey)
    from Crypto.Cipher import PKCS1_OAEP
    rsa = PKCS1_OAEP.new(rsakey)
    import binstruct
    from array import array
    aeskey = randomString(32)
    iv = randomString(16)
    from Crypto.Cipher import AES
    aes = AES.new(aeskey, AES.MODE_CBC, iv)
    data = binstruct.varEncode(v)
    data += array("B", (0,) * (-len(data) % 16))
    out = binstruct.strEncode(rsa.encrypt(aeskey + iv))
    out += array("B", aes.encrypt(data))
    return out

def decrypt(stream, rsaprivkey):
    from array import array
    from StringIO import StringIO
    if isinstance(stream, array): stream = stream.tostring()
    if isinstance(stream, str): stream = StringIO(stream)
    from Crypto.PublicKey import RSA
    rsakey = RSA.importKey(rsaprivkey)
    from Crypto.Cipher import PKCS1_OAEP
    rsa = PKCS1_OAEP.new(rsakey)
    import binstruct
    aesdata = binstruct.strDecode(stream)
    aesdata = rsa.decrypt(aesdata)
    aeskey = aesdata[0:32]
    iv = aesdata[32:]
    from Crypto.Cipher import AES
    aes = AES.new(aeskey, AES.MODE_CBC, iv)
    class Stream:
        buffer = []
        def read1(self):
            if len(self.buffer) == 0:
                nextIn = stream.read(16)
                self.buffer += list(aes.decrypt(nextIn))
            return self.buffer.pop(0)
        def read(self, n):
            return "".join([self.read1() for i in range(n)])
    v = binstruct.varDecode(Stream())
    return v

binstructJSON / BSONと同様に、ツリーデータ構造をエンコード/デコードできる小さなモジュールです。)

encryptそこで、秘密鍵と公開鍵を使用することもできると思いdecryptました。


(うまくいけば)正しい署名/認証を使用した最終的な実装は、binstructにあります。

4

1 に答える 1

16

公開鍵と秘密鍵の役割を交換することについてのあなたの一般的な理解は正しいです。結局、RSAは次の事実に基づいています

m^(ed) congruent m (mod n)

通常RSA暗号化と呼ばれるのは、通常、操作です

m^e mod n,

メッセージをe乗に上げます。ここで、eは公開鍵です。

復号化は

(m^e)^d mod n,

暗号化されたメッセージをd乗します。dは秘密鍵です。べき乗の規則と乗算が可換であるという事実(これらはまだモジュラー算術で成り立つ)のために、私たちはそれを持っています

m congruent (m^e)^d congruent m^(ed) congruent m^(de) congruent (m^d)^e,

したがって、逆の順序で操作を適用すると、同じ結果が得られます。

誰もが公開鍵eを使用して署名を検証(「復号化」)できるため、反転によってデジタル署名が発生すると想定したのは正しいことでした。したがって、メッセージは、対応する秘密鍵を使用して「暗号化」(署名)された場合にのみ本物でした。 d。

結局のところ、PyCryptoは、ここで一方を他方と間違えないようにするだけです。OpenSSLまたはRuby OpenSSLを使用すると、たとえば、public_encrypt/public_decryptとprivate_encrypt/private_decryptの両方を実行できます。

理論についてはこれだけですが、これらを同じ意味で使用させないのには十分な理由があります。私が今説明したことは、しばしば「教科書RSA」と呼ばれ、それはまだ安全とはほど遠いものです。結果を実際に使用できるようにするには、追加の処理を行う必要があります。そして、それがPyCryptoに専用の署名パッケージがある理由です-これはあなたが説明したことを効果的に実行しますが、さらに私が言及したことも処理します。これらがどのように機能するかを理解することは私たちの理解にとっては良いことですが、実際には常にそのようなパッケージを使用する必要があります。

eが常に65537である理由については、実際には固定値である必要はありませんが、通常、バイナリ表現の1ができるだけ少ない非常に小さい数値(65537は10001)が選択されます。過去には、e=3またはe=17も選択されていましたが、暗号文の3番目または17番目のルートを取得するだけで攻撃される可能性があるため、実際には安全ではないと見なされていました。e=3およびm=3の場合、3 ^ 3は27であり、モジュラスn(通常ははるかに大きい)に関係なく、暗号文が27であるとすると、mが3であることを理解するのに天才は必要ありません。したがって、危険なのは、べき乗後でも暗号文が「モジュラス境界」を超えないため、e番目のルートを取得して元のメッセージに到達できるという事実にあります。1024〜4096ビットの一般的なモジュラスでは、これはe=65537では問題になりません。

バイナリ表現の1は、m^eを高速に計算するのにも適しています。べき乗剰余は、乗算と二乗のアルゴリズムを使用して実装されることが多く、パフォーマンスは、1が少ない小さなeに最適です。なぜそれがこのように選択され、その逆ではないのですか?たとえば、1が少ない小さなdがあるのですか?初心者にとっては、dはそのように推測する方が簡単です。2番目の利点は、デジタル署名では、通常、ドキュメントに1回署名しますが、頻繁に検証することです。つまり、m ^ dは1回実行されますが、m ^ eは頻繁に実行されるため、一般的なタスクのパフォーマンスは最高になりますが、まれなタスクのパフォーマンスは低下します。

編集:

安全を確保するためにRSA-PSSのようなスキームが何をするのかをさらに説明できるかどうか尋ねられました。

OAEPが暗号化に対して行うこととPSSが署名に対して行うことを比較すると、この2つは非常によく似ています。実際、どちらもプロセスにランダム化を導入しているため、特定の前提条件の下でOAEPPSSの証明可能なセキュリティが可能になります。私もこの論文を見つけました役に立つこと。証明可能安全性は、同じ仮定の下では証明可能安全性がないことを示すことができる、古い学校のPKCS 1.5暗号化および署名に比べて大きな利点です(重要なポイント:決定論的スキームは不可能であり、ランダム化が不可欠です)。提案された署名スキームと暗号化スキームの明らかな違いは、署名スキームは常に、署名されるメッセージを最初にハッシュすることを義務付けていることです。これは、効率に関してだけでなく、他の方法では可能になる攻撃を防ぐことにも意味があります。そして、それが、署名に署名スキームを、暗号化に暗号化スキームを常に使用する必要がある理由の要点につながると思います。提案されたスキームにはセキュリティ証明が添付されていますが、手作りのスキームには付属していません。

暗号学者は、私たちの生活を単なる人間の生活を楽にするためにこれらのスキームを発明しました-オプションの数を最小限に抑えることで、悪用や誤用を防ぐのに理想的なツールを提供します。たとえば、RSA-OAEPを使用して優れた署名スキームを思いついたとしても、それを使用する人は、署名を適用する前に最初にメッセージをハッシュする必要がある理由を知らない可能性があります。この種の誤用は、RSA-PSSでは不可能です。

あなたはまた、いくつかの良い読み物について尋ねました。これは非常に主観的なトピックですが、私はこれらを本当に楽しんだ:

実用的な側面:

  • AppliedCryptography-まだ古典的で読む価値があります。一部のセキュリティ担当者は、自分の暗号を書くのに十分な知識があると人々に信じ込ませるため、危険だと言います。でも私たちはみんな大人だと思いますよね?「そこにあるもの」についての感覚を得るのはまだ素晴らしいです

  • 暗号化エンジニアリング-いくつかの優れた実用的なアドバイスがあり、暗号化コードを実装する際の警告についても言及しています。

  • 応用暗号化ハンドブック-無料であり、特に実装に関して多くの良いアドバイスがあります。

理論的な側面:

  • 現代の暗号化-それは理論と実践のハイブリッドであり、実際に物事がどのようにうまくいかないかについて多くの洞察を持っています。

  • 暗号化-理論と実践-これは私にとってゲームチェンジャーでした。私はこの本が大好きです。あなたが今までに一冊の本しか読んだことがないなら、それをこれにしましょう:)

  • 現代の暗号化の概要-「現代のアプローチ」と、セキュリティ証明が実際にどのように機能し、どのような仮定の下で機能するかを説明するのに最適です。

  • 暗号化I&IIの基礎-前の本を読んだ後でも、一方向性関数や友人の理論を十分に理解できない場合は、これがあなたの本です。非常に技術的です。

セキュリティは暗号化だけではありません。

それとは別に、新しい攻撃やテクノロジーなどに関する最近の論文を読んで最新の状態に保つようにしています。r/ netsecは非常に役立ち、Twitterで研究者や実務家をフォローし、興味深い資料を定期的に投稿しています。

最後に、時間があれば、CourseraとUdacityの暗号化コースを受講してください。彼らは数週間以内に最初からやり直すと思います、彼らは本当に素晴らしいです、あなたがそれを後悔しないと確信しています。彼らは非常に楽しく、暗号化の実装を攻撃するさまざまな方法をうまく説明する多くの実践的な演習を行いました。

于 2012-06-10T17:01:27.737 に答える