2

현재 Windows 암호화 API를 실험 중이며 공개 키 암호화와 관련된 몇 가지 문제가 있습니다. 항목을 암호화하는 방법에 대한 많은 예제가 있지만 처음부터 끝까지 공개 키 모델을 직접 처리하는 것은 없습니다.WinCrypt에서 공개 키 암호화를 생성하고 사용하는 방법

여기에 내 현재 코드는 암호화 키 쌍을 생성하기 위해 어떻게 보이는지의 대략적인 윤곽이, 난 가독성을 위해 코드를 검사 오류를 제거했습니다

// MAKE AN RSA PUBLIC/PRIVATE KEY: 
    CryptGenKey(hProv, CALG_RSA_KEYX, CRYPT_EXPORTABLE, &hKey); 

// NOW LET'S EXPORT THE PUBLIC KEY: 
    DWORD keylen; 
    CryptExportKey(hKey,0,PUBLICKEYBLOB,0,NULL,&keylen); 
    LPBYTE KeyBlob; 
    KeyBlob = (LPBYTE)malloc(keylen); 
    CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,KeyBlob,&keylen); 
    ofstream outputkey; 
    outputkey.open("TestPublicKey.txt", ios_base::out | ios_base::binary); 
    for(size_t i=0; i < keylen; ++i) 
     outputkey<&ltKeyBlob[i]; 
    outputkey.close(); 
    free(KeyBlob); 

// NOW LET'S EXPORT THE PRIVATE KEY: 
    CryptExportKey(hKey, 0, PRIVATEKEYBLOB,0,NULL,&keylen); 
    KeyBlob = (LPBYTE)malloc(keylen); 
    CryptExportKey(hKey,NULL,PRIVATEKEYBLOB,0,KeyBlob,&keylen) 
    outputkey.open("TestPrivateKey.txt", ios_base::out | ios_base::binary); 
    for(size_t i=0;i&ltkeylen;++i) 
     outputkey<&ltKeyBlob[i]; 
    outputkey.close(); 
    free(KeyBlob); 

// ENCRYPT A (SHORT) TEST MESSAGE [SHOULD JUST BE ANOTHER ALG'S KEY LATER]: 
    DWORD encryptBufferLen=0; 
    CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // how much space? 
    BYTE* encryptionBuffer = (BYTE*)malloc(encryptBufferLen); 
    memcpy(encryptionBuffer, TestMessage, TestMessageLen); // move for in-place-encrypt 
    CryptEncrypt(hKey,0,true,0, encryptionBuffer, &bufferlen, encryptBufferLen); 

    ofstream message; 
    message.open("Message.txt", ios_base::out | ios_base::binary); 
    for(size_t i=0;i&ltencryptBufferLen;++i) 
     message<&ltencryptionBuffer[i]; 
    message.close(); 

내 두 개의 수출 키가 다르지만, 둘 다 할 수 있습니다 다른 키가로드되지 않고 메시지를 해독합니다. 또한 내 보낸 공개 키를로드하는 새 세션에서 새 메시지를 암호화하는 경우에도 두 키 중 하나를 사용하여 해당 메시지를 해독 할 수 있습니다.

내가 잘못했거나 누락 된 부분에 대해 조언 해 줄 사람이 있습니까? 나는 완전히 잘못된 길을 가고 있는가?

답변

0

귀하의 질문을 완전히 이해하지 못했습니다. 하지만 일반적으로

  1. 공개 키를 사용하여 직접 데이터를 암호화하지 마십시오.

  2. 암호화 중 : 세션/대칭/개인 키를 사용하여 데이터를 암호화합니다. 이 세션 키는 AT_EXCHANGE 공개 키로 암호화됩니다.

  3. 암호 해독 중 : AT_EXCHANGE 개인 키가 세션 키를 해독합니다. 차례로이 세션 키는 실제 데이터의 암호를 해독하는 데 사용됩니다.

+0

덧글 1 : 나는이 주석을 정말로 이해하지 못합니다. 공개 키와 비공개 키를 모두 사용하여 암호화하고 싶습니다. (전통적으로 공개 키를 사용하여 '키 소유자'에게 보내고 개인 키 소유자와 마찬가지로 '서명'). # 2/# 3은 괜찮지 만 다소 관련성이 없습니다. 키에 원시 액세스를 원하지만 표준 메시지 교환에는 암호화를 사용하지 않고 공용/개인 암호화의 다른 측면을 활용합니다. 요점은 - 공개 키/개인 키 중 하나를 적절히 해독 할 수없는 이유는 무엇입니까? – Tom

+0

@Tom, 다음 게시물이 도움이 될 수 있습니다. http://stackoverflow.com/questions/3121740/decrypt-data-using-an-rsa-public-key – Raj

0

나는이 암호화 작업에 대한 전문가가 아닙니다. 하지만 난

뭔가가 암호화 비트가 어긋 나서 보이는 ... 그래서 당신의 고통을 느낄 수있는 순간이 함께 일하고

// ENCRYPT A (SHORT) TEST MESSAGE [SHOULD JUST BE ANOTHER ALG'S KEY LATER]: 
DWORD encryptBufferLen=0; 
CryptEncrypt(hKey, 0, true, 0, NULL, &encryptBufferLen, 0); // how much space? 
BYTE* encryptionBuffer = (BYTE*)malloc(encryptBufferLen); 
memcpy(encryptionBuffer, TestMessage, TestMessageLen); // move for in-place-encrypt 
CryptEncrypt(hKey,0,true,0, encryptionBuffer, &bufferlen, encryptBufferLen); 

당신이 당신의 크기를 제공하는 기능을 요구하는 것으로 보인다 암호화 된 메시지 그래서 당신은 그 크기 즉, 메모리를 할당 할 수 있습니다 ...하지만 당신은 그 정보를 확실하게 줄 수있을 것이라고 생각하지 않을 정도로 키 자체로부터 아무 것도 전달하지 않습니다 ..

당신은 CryptEncrypt (hKey , 0, true, 0, NULL, & encryptBufferLen, 0); //하지만 실제로 "NULL"은 암호화 할 문자열이 들어있는 버퍼를 전달해야하므로 크기를 계산하여 반환 할 수 있습니다. 나머지는 계속 진행할 수 있습니다. 내보내기 비트가 작동하는 방식을 알았습니다 (해당 컨텍스트의 키를 사용하기 때문에). 반면 실제 메시지는 처리합니다. 매개 변수를 전달하고 이것이 어떻게되는지보십시오.

나는 실제로 아무것도 암호화하지 않았기 때문에 두 키를 사용하여 실제로 해독 할 수 없다는 것을 알게 될 것입니다. 내 생각에 0 크기의 버퍼에 메시지를 암호화합니다.

내가 전문가는 아니지만 나에게 잘못된 것처럼 보입니다 ... 이상한 점은 다른 일에 게시물을 발견하고 작업 비트를 수확하여 이해하는 데 도움이되므로이 정보가 도움이되기를 바랍니다. !

+1

안녕하세요 LeeC, 좋은 질문입니다. 이것은 일반적인 Microsoft 패턴이며 MSDN의 관련 문서 라인입니다. pbData가 NULL이면 오류가 반환되지 않고이 함수는 pdwDataLen으로 지정된 변수에 데이터의 크기를 바이트 단위로 저장합니다. 이를 통해 응용 프로그램은 정확한 버퍼 크기를 명확하게 결정할 수 있습니다. - http://msdn.microsoft.com/en-us/library/aa925235.aspx – Tom

+0

안녕하세요 톰, 오, 이제 동의 해주세요! 당신은 공급자 등 (Aquire Context 비트에서 선택)을 기반으로 버퍼의 실제 크기를 결정하려고합니다. 따라서 모든 암호화 된 블록은 원본 메시지와 상관없이 동일한 크기이지만 공급자에 따라 달라집니다. 미안 나는 도움이 될 수 없었다! 솔직히 말해서 나는 이것으로 시작한 적이 없었 으면 좋겠다. 나는 서버에서 클라이언트로 공개 키를 전달할 과제를 가지고있다. 클라이언트는 메시지를 암호화하고 서버로 돌아 간다.하지만 공개 키는 훌륭하게 재생되지 않는다. 우리 모두에게 행운을 비네! – LeeC

+0

LeeC,이 문제를 해결하기 위해 결국 CryptoPP (http://www.cryptopp.com/)를 포기하고갔습니다. 이것이 옵션이라면 훨씬 유용합니다. – Tom

0

당신이 사용하고 CryptImportKey에서 제공하는 아래 링크를 통해 이동? 암호화가 생성 한 키에 대한 핸들을 사용하는 것처럼 보입니다. Public/Private 쌍을 올바르게하려면 CryptExportKey를 사용하여 공개 키만 내보내고 누구에게나 공개해야합니다. 이것은 진정한 "암호화"가 아니지만 그 사람이 당신에게서 온 것임을 그 사람이 알 수있는 방법입니다.