2012-06-10 8 views
7

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, ed 보았다. 모든 경우에 nd은 매우 큰 반면 e은 모두 상수 (65537) (예상하지 못했음)입니다.

나는이 모든 것이 내가 단지 ed을 교환해서는 안된다고 생각한다.

그래서 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입니다.

+0

"공개 키를 사용하여 암호를 해독하려고하면 PyCrypto가 불평합니다." 보다 구체적으로 코드를 보여주십시오. –

+0

@GregS :'_RSAKey._decrypt'에서'TypeError ("개인 키 없음")을 발생시킵니다. 링크 된 코드에서 알 수 있습니다. 그것이 내가 말한 것입니다. 해독 할 때 개인 키가 필요합니다. – Albert

+0

암호에 대한 기초 지식 만있는 사용자는 API가 사용되지 않는 방식으로 API를 사용하지 않습니다. 나는 10 년의 경험을 가지고 있으며 심지어 암호화 라이브러리를 사용하지 않을 때 조심 스럽습니다. 가능한 한 그렇게하지 않으려 고 노력합니다. –

답변

15

공개 키와 개인 키의 역할을 상호 교환하는 것에 대한 일반적인 이해가 정확합니다. 결국, RSA는 일반적 RSA 암호화 표제 무엇

m^(ed) congruent m (mod n) 

전형적 예는 공개 키가 전자 승 메시지를 올리는 동작

m^e mod n, 

사실에 기초 .

해독 D가되는 비밀 키와 D 승으로 암호화 된 메시지를 상승 후

(m^e)^d mod n, 

이다. 이제 때문에 지수 곱셈은 교환 법칙이 성립한다는 사실의 규칙 우리는

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

이 있고 반대 순서로 작업을 적용 할 경우, 따라서 동일한 결과를 얻을 수 (이 여전히 모듈러 산술에서 개최).

모든 사람이 공개 키 e를 사용하여 서명을 검증 ("해독") 할 수 있기 때문에 역 분개가 디지털 서명으로 이어질 것이라는 가정하에, 메시지는 "암호화 된"(서명 된) 경우에만 본격적이었습니다. 해당 개인 키 d.

그것이 나오는 것에 따라, PyCrypto는 여기에 다른 하나의 착각에서 당신을 방지하기 위해 노력하고있다가,은 OpenSSL 또는 루비 OpenSSL을 사용하면 for example이 두 가지를 모두 수행 할 수 있습니다 : public_encrypt/public_decrypt 및 private_encrypt/private_decrypt.

이론상으로, 왜 당신이 그들을 서로 바꾸어 사용할 수없는 좋은 이유가 있는지에 대한 이론입니다. 방금 설명한 내용은 종종 "교과서 RSA"라고도하며 아직 안전하지 않습니다. 결과를 실제로 사용할 수 있도록하기 위해 추가로주의해야 할 사항이 있습니다. 이것이 바로 PyCrypto에 전용 signature package이있는 이유입니다. 이는 효과적으로 설명했던 것을 수행하지만, 앞서 언급 한 것들을 추가적으로 처리합니다. 이러한 것들이 어떻게 작동 하는지를 이해하는 것이 좋지만, 실제로 패키지를 사용하는 것은 항상 우리 자신의 패키지를 만들 때 우리가 도입 할 실수를 이미 만들고 수정했기 때문에 실제로 사용해야합니다.

e는 항상 65537입니다. 실제로 고정 값 일 필요는 없지만 일반적으로 이진 표현에서 가능한 적은 수의 1로 매우 작은 숫자로 선택됩니다 (65537은 10001 임) . 과거에는 e = 3 또는 e = 17도 선택되었지만 실제로는 암호문의 3 번째 또는 17 번째 루트를 사용하여 공격 할 수 있기 때문에 실제로 안전하지 않은 것으로 간주되었습니다. e = 3이고 m = 3이라면 3^3은 27이고, modulus n (일반적으로 훨씬 더 큼)에 관계없이 암호문이 27 인 경우 m이 3이라는 것을 알기 위해 천재는 필요하지 않습니다. 따라서 지수는 지수를 지나도 암호문이 "모듈러스 경계"를 넘지 않으므로 단순히 e- 루트를 가져 와서 원래 메시지에 도달 할 수있는 위험에 놓여 있습니다. 1024 ~ 4096 비트의 표준 모듈을 사용하면 e = 65537에서는 더 이상 문제가되지 않습니다.

바이너리 표현의 소수 1도 m^e를 빠르게 계산하는 데 적합합니다. 모듈러 지수법은 종종 Multiply and Square 알고리즘을 사용하여 구현되며 성능은 1을 거의 사용하지 않는 작은 전자의 경우 가장 좋습니다. 왜이 방법을 선택하고 다른 방법으로 돌리지 않는가? 예를 들어 1의 수가 적고 작은 d를 갖는 경우? 처음에는 d가 그렇게 쉽게 추측 할 수 있습니다. 두 번째 이점은 디지털 서명을 사용하면 일반적으로 한 번만 문서에 서명하지만 자주 확인해야한다는 것입니다. 이것은 m^d가 한 번만 수행되지만 m^e는 자주 수행된다는 것을 의미하므로, 일반적인 태스크는 가장 잘 수행하고 희소 한 태스크는 빈약 한 수행을 허용합니다.

편집 : 당신은 내가 더 RSA-PSS와 같은 제도가 순서대로 보안 할 일을 설명 할 수 있는지 물었다

.

OAEP가 암호화를 위해 수행하는 작업과 서명을 위해 PSS가 수행하는 작업을 비교할 때이 두 작업은 매우 유사합니다. 그리고 실제로 그들은 둘 다 임의의 가정하에 OAEPPSS의 증명 가능한 보안을 허용하는 과정에서 임의 화를 도입합니다. 나는 또한이 paper이 도움이된다는 것을 알았다. 신뢰할 수있는 보안은 이전 가정 PKCS 1.5 암호화 및 서명보다 큰 장점입니다. 이는 동일한 가정 하에서 확실히 안전하지 못하다는 것을 나타낼 수 있습니다 (핵심 포인트 : 결정 론적 계획이 없어도 무작위 화가 필수적입니다). 제안 된 서명과 암호화 체계의 명백한 차이점은 서명 체계가 항상 서명 된 메시지를 먼저 해시해야한다는 것입니다. 이것은 효율성과 관련하여 의미가있을뿐만 아니라 가능할 수도있는 공격을 예방합니다. 그리고 우리가 서명을위한 서명 스키마와 암호화를위한 암호화 스키마를 항상 사용해야하는 이유를 제시합니다. 제안 된 스키마에는 보안 증명이 첨부되어 있습니다. 우리의 수작업 방식은 그렇지 않습니다.

암호 작성자는 단순한 필사자의 삶을 더 쉽게 만들어주는 제도를 발명합니다. 옵션을 최소한으로 줄임으로써 남용이나 오용을 허용하는 도구를 제공합니다. 예를 들어, RSA-OAEP를 사용하는 훌륭한 서명 구성표를 작성해도 서명을 적용하기 전에 먼저 해시해야하는 이유를 모르는 사람이있을 수 있습니다. RSA-PSS와 같은 종류의 오용 가능성조차 없습니다.

당신은 또한 좋은 읽을 거리에 대해 물었습니다. 여전히 고전하고 가치 읽기 -

  • Applied Cryptography :

    실제적인 측면이 매우 주관적인 주제이지만, 난 정말이를 즐겼다. 일부 보안 전문가들은 사람들이 자신의 암호를 작성할만큼 충분히 알고 있다고 믿게하기 때문에 위험하다고 말합니다. 하지만 우리는 모두 어른이라 생각하지? "무엇이 있는지"에 대한 느낌을 얻는 것은 여전히 ​​좋은 일입니다.

  • Cryptography Engineering - 암호화 코드를 구현할 때 몇 가지 실용적인 조언과주의 사항이 있습니다.

  • Handbook of Applied Cryptography - 무료이며 구현 측면에서 여전히 많은 조언을 제공합니다.

이론적 인 측면 :

  • Modern Cryptography는 - 그것은 이론과 실천 사이의 하이브리드의 일들이 실제로 잘못 될 수있는 방법에 대한 통찰력을 많이했다.

  • Cryptography - Theory and Practice - 이것은 나를 위해 게임 체인저였습니다. 입니다. 책 하나만 읽으면이 책을 읽으십시오.

  • Introduction to Modern Cryptography - "현대적 접근법"을 설명하고 보안 증명이 실제로 어떤 방식으로 작동하는지 가정 할 때 훌륭한 역할을합니다.

  • Foundations of Cryptography I&II - 이전 책을 읽은 후에도 여전히 단방향 함수 및 친구 이론을 충분히 얻을 수없는 경우이 책이 귀하의 책입니다. 매우 기술적입니다.

보안뿐만 아니라 암호화입니다 :

  • Security engineering - 사운드 원칙은 실제로 잘못 될 수있는 방법을 많은 예제를 가지고

  • Information Security - 범위의 보안 엔지니어링과 유사하게, 설명 보안 단순한 암호화보다 넓습니다. 그 외에도에서

, 나는 r/netsec 매우 도움이뿐만 아니라 트위터에 연구자와 실무자 다음, 그들은 게시 흥미로운 자료를 정기적으로 발견 등 새로운 공격 기술에 대한 최근의 논문을 읽어 최신 상태로 유지하려고 .

마지막으로 시간이 있다면 Coursera 및 Udacity의 암호화 과정을 선택하십시오! 나는 그들이 다음 몇 주 후에 다시 시작할 것이라고 생각합니다. 정말 훌륭합니다. 나는 후회하지 않을 것이라고 확신합니다. 그들은 재미 있고 암호화 구현을 공격하는 다양한 방법을 잘 보여주는 많은 실제 연습을했습니다.

+1

감사합니다. 매우 유용합니다! - "추가 사항은주의해야합니다. [..] [서명 패키지]는 내가 언급 한 것들을 추가적으로 처리합니다." 나는 당신이 그런 것들을 명시 적으로 언급하지 않았거나 나는 그것을 얻지 못했다고 생각합니다. 추가로 어떤 것들이 있습니까? RSAES-OAEP (개인 키를 사용하여 암호화)가 아닌 RSASSA-PSS를 사용하는 이유는 무엇입니까? - 이론적 인 교과서 RSA 지식에서 실제 사용법에 이르는 방법에 대한 더 많은 독서 자료를 추천 할 수 있습니까? (왜냐하면 대부분의 도서관조차도 거의 대부분 간단한 예제 만 보았 기 때문입니다.) – Albert

+0

@Albert 내 대답이 업데이트되었습니다. 도움이 되었습니까? – emboss

관련 문제