私はRSAについて非常に基本的な理論的知識しか持っていません。
実際の使用方法についてさまざまな情報源を読んでいる間、PKCS#1OAEPは良いことのように思われました。
テストの実装には、PyCryptoでPythonを使用します。たとえば、これはPKCS#1OAEPを使用した例です。
公開鍵を使用して暗号化し、次に秘密鍵を使用して復号化すると、正常に機能します。たとえば、公開鍵を使用して、公開鍵を使用してX氏にデータを送信できます。
RSAの仕組みについての基本的な理解から、公開鍵と秘密鍵を交換するだけでよいと思いました。つまり、暗号化には公開鍵を使用し、復号化には秘密鍵を使用できます。たとえば、人物Xは独自の秘密鍵を使用して一部のデータを暗号化し、公開鍵を使用して公開鍵を復号化できます。復号化が正常に機能する場合、これにより、データが人物Xからのものであるという何らかの証拠が得られます。
公開鍵を使用して復号化しようとすると、PyCryptoが文句を言います。
PyCryptoソースコードを読むと、_RSAKey._decrypt
関数(ここ)で、キーオブジェクト自体が秘密キーか公開キーかを認識しており、それらの間で異なるように見えます(驚いたことに、RSAの非常に基本的な理解に基づいています)。
そこから、公開鍵を使用するように復号化機能をハックできるようです。または、多少異なる方法です。キーオブジェクトのパブリック指数e
とプライベート指数を入れ替えることができます。d
しかし、これはすべて、このように使用/ハッキングされることを意図したものではないようです。それで、私はここで私の誤解について尋ねたかったのです。
また、好奇心から、いくつかのキー()を生成し、、、をRSA.generate(2048)
調べましn
た。すべての場合において、そしてすべての場合において一定(65537)である間、非常に巨大でした(私はそれを予期していなかったでしょう)。e
d
n
d
e
これらすべてから、私は本当に単に交換するべきではないと思い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
(binstruct
JSON / BSONと同様に、ツリーデータ構造をエンコード/デコードできる小さなモジュールです。)
encrypt
そこで、秘密鍵と公開鍵を使用することもできると思いdecrypt
ました。
(うまくいけば)正しい署名/認証を使用した最終的な実装は、binstructにあります。