RSA에 관한 매우 기초적인 이론적 지식 만 있습니다.PKCS # 1 OAEP 암호화/암호 해독에서 공개/개인 키 교환
실제로 사용하는 방법에 대한 여러 출처를 읽는 동안 PKCS # 1 OAEP가 좋은 것 같았습니다.
테스트 구현을 위해 Python을 PyCrypto와 함께 사용합니다. 예 : this은 PKCS # 1 OAEP를 사용한 예입니다.
공개 키를 사용하여 암호화 한 다음 개인 키를 사용하여 암호를 해독하면 정상적으로 작동합니다. 예 : 대중은 개인 키로 개인 X에게 데이터를 보낼 수 있습니다.
RSA가 작동하는 방식에 대한 기본적인 이해에서 공개/개인 키를 교환 할 수 있다고 생각했습니다. 즉, 공개 키를 사용하여 암호를 해독하고 개인 키를 해독 할 수 있습니다. 예 : 사람 X는 자신의 개인 키로 일부 데이터를 암호화 할 수 있고 공개 키를 사용하여 공개 키를 해독 할 수 있습니다. 암호 해독이 정상적으로 작동하면 데이터가 사람 X에서 온다는 증거를 얻을 수 있습니다.
공개 키를 사용하여 암호를 해독하려고하면 PyCrypt가 불평합니다.
_RSAKey._decrypt
함수 (here)의 PyCrypto 소스 코드를 읽으면 키 객체 자체가 개인용 또는 공개용 키인지 알 수 있으며 그 사이에 차이가 있습니다 (놀랍게도 내 기본 RSA 이해).
공개 키를 사용하도록 해독 기능을 해킹 할 수있는 것처럼 보입니다. 또는 다소 다르게 : 나는 공개 지수 e
과 개인용 지수 d
을 키 객체로 교환 할 수 있습니다.
하지만이 모든 방법은이 방법으로 사용되거나 해킹되지 않는 것 같습니다. 그래서 저는 여기에 오해에 대해 물어보고 싶었습니다.
또한, 단지 호기심에서, 나는 몇 가지 키 (RSA.generate(2048)
)를 생성
n
,
e
및
d
보았다. 모든 경우에
n
및
d
은 매우 큰 반면
e
은 모두
상수 (65537) (예상하지 못했음)입니다.
나는이 모든 것이 내가 단지 e
과 d
을 교환해서는 안된다고 생각한다.
그래서 PKCS1_PSS와 같은 서명을 위해 다른 방법을 사용해야한다고 생각합니다.
암호화/해독에 대한 몇 가지 코드, 누군가가 관심이있는 경우 : (. binstruct
/디코딩 트리 데이터 구조를 인코딩 할 수있는 작은 모듈입니다 - JSON/BSON과 유사)을
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
가
개인 키는 encrypt
이고 공개 키는 decrypt
입니다.
정확한 서명/인증을 통한 최종 구현은 here in binstruct입니다.
"공개 키를 사용하여 암호를 해독하려고하면 PyCrypto가 불평합니다." 보다 구체적으로 코드를 보여주십시오. –
@GregS :'_RSAKey._decrypt'에서'TypeError ("개인 키 없음")을 발생시킵니다. 링크 된 코드에서 알 수 있습니다. 그것이 내가 말한 것입니다. 해독 할 때 개인 키가 필요합니다. – Albert
암호에 대한 기초 지식 만있는 사용자는 API가 사용되지 않는 방식으로 API를 사용하지 않습니다. 나는 10 년의 경험을 가지고 있으며 심지어 암호화 라이브러리를 사용하지 않을 때 조심 스럽습니다. 가능한 한 그렇게하지 않으려 고 노력합니다. –