2017-12-03 25 views
0

하나 이상의 수신자에 대해 파일의 PGP 서명/암호화 및 암호 해독/유효성 검사를 수행하는 라이브러리를 개발했습니다. 이 부분은 훌륭하게 작동하며 스트림을 멋지게 효율적으로 사용하여 대용량 파일을 처리합니다.BouncyCastle C# 라이브러리를 사용하여 PGP 암호화 데이터에서받는 사람 식별

...

6.7 사용자 ID 패킷

목적 : PGP 메시지 교환 형식 사양 (RFC 1991)의

제품은 또한 다음과 같은 상태. 사용자 ID 패킷은 사용자를 식별하며 공개 키 또는 개인 키와 연관됩니다.

정의. 사용자 ID 패킷은 다음의 필드들의 연결이다 :

(a) 패킷 구조 필드 (2 바이트);

(b) 사용자 ID 문자열.

사용자 ID 문자열은 인쇄 가능한 ASCII 문자로 된 문자열 일 수 있습니다. 그러나이 패킷의 목적은 개인을 고유하게 식별하기위한 것이므로 일반적으로 사용자 ID 문자열은 사용자 이름 뒤에 해당 사용자의 전자 메일 주소, 뒤에 오는 으로 구성됩니다. 괄호.

...

나는 가능한 한 적은 사용자 개입을 가질 수 있도록 자동으로 파일의 암호를 해독에 적합한 키를 식별을 시도 할 필요가 만드는 오전 응용 프로그램. 키를 식별 할 수없는 경우 (예 :받는 사람이 숨겨져있는 경우) 응용 프로그램은 올바른 키를 선택하라는 메시지를 표시합니다. 가능한 한 간소화하기 위해 노력하고 있습니다.

RFC는 패킷이 의미있는 암호화 된 데이터의 일부가 아니라고 제안합니다. PGP를 사용하면 누가 데이터를 암호화했는지 쉽게 파악하고 식별 할 수 있습니다. Kleopatra가 키 데이터베이스에 관련 키를 추가 할 때 Kleopatra를 사용하여 파일을 해독하고 암호 해독 할 때이 사실이 분명합니다. 이 경우 비밀 키를 보호하는 암호를 묻습니다.

내 특정 질문은 :

가 어떻게 암호화 된 데이터가 의도 된 수신자 읽을 수있는 C# BouncyCastle 라이브러리를 사용합니까? 즉, 암호 해독에 사용할 개인 키는 무엇입니까?

Bouncy Castle GitHub repository을 사용하여 예제를 찾으려고 시도했지만이 특정 문제를 입증하지 못했습니다. 또한이 질문에 대한 많은 Google 검색 결과를 아무 소용이없는 것으로 보았습니다.

답변

0

내 질문에 대한 답변을 찾았습니다. 필자는 PGP 사양의 일부라면 너무 귀찮게하지 않아도되도록해야한다고 생각했습니다. 따라서 해독 과정과 그 과정에서 사용 된 모든 객체에 대해 면밀히 조사하기로했습니다.

디버거를 사용하여 PgpEncryptedDataList 내의 항목을 열거하고 PgpPublicKeyEncryptedData 개체 내에서 암호화 한 공개 키의 키 ID를 찾았습니다.

이 개체에는 이라는 long 유형의 속성이 포함되어 있습니다. 이것은 응용 프로그램에 저장된 키와 일치시키려는 값이었습니다.

using (var inputFile = File.OpenRead(@"E:\Staging\6114d23c-2595abef\testfile.txt.gpg")) 
using (var decoderStream = PgpUtilities.GetDecoderStream(inputFile)) 
{ 
    var objectFactory = new PgpObjectFactory(decoderStream); 
    var encryptedList = (PgpEncryptedDataList)objectFactory.NextPgpObject(); 
    foreach (var encryptedData in encryptedList.GetEncryptedDataObjects().Cast<PgpPublicKeyEncryptedData>()) 
    { 
     var keyId = encryptedData.KeyId.ToString("X"); 
     Console.WriteLine($"Encryption Key ID: {keyId}"); 
    } 
} 

첫 열거 한 후 중단 점을 설정하면 encryptedData 변수를 검토하고 비슷한 관찰 할 수있다 :

다음 코드 내가 KeyId 특성에 도달하는 데 사용되는 것을 단지 예입니다

enter image description here

그래서 모든 투쟁 끝에 실제로는 매우 간단했습니다. 암호 해독 과정에서 KeyId에 액세스하는 것은 간단하며 암호를 해독하기 위해 자동으로 올바른 개인 키를 가져올 수 있습니다.

완벽을 기하기 위해 파일이 단지 한 명 이상의 수신자를 위해 암호화되는 것이 일반적입니다. 이 경우 암호화 된 데이터 객체가 두 개 이상 표시됩니다. 데이터가 두 번 암호화된다는 의미는 아닙니다. 세션 키. 세션 키는 N 번 암호화되고 N은 수신자 수입니다. 이렇게하면 각받는 사람이 중 하나를 세션 키의 암호를 해독 한 다음 데이터를 해독하고 암호 해독 할 수 있습니다.

두 개체를 보여주는 아래의 이미지를 참조하십시오, 당신이 기대하는 것처럼,이 KeyId 속성 :

enter image description here

이 조각은 이미 암호화 된 개체를 통해 외모와 키를 확인하는 PgpDecrypt.cs에서입니다 머리를하고자하는 사람들을위한

foreach (PgpPublicKeyEncryptedData pked in encryptedDataList.GetEncryptedDataObjects()) 
{ 
    privateKey = PgpKeyHelper.FindSecretKey(secretKeyRing, pked.KeyId, passPhrase.ToCharArray()); 
    if (privateKey == null) 
    { 
     continue; 
    } 

    encryptedData = pked; 
    break; 
} 

은 PGP로 시작, BouncyCastle의 A : 매개 변수로 전달 된 PgpSecretKeyRingBundle에 대한 식별자 nd C#, refer to my library에는 많은 PGP 기능이 포함되어 있습니다. PgpDecrypt 클래스는이 질문에서 설명한대로 키 검색을 자동으로 통합하도록 변경할 수 있습니다.