2012-12-10 2 views
3

RSA 암호화 및 암호 해독을 위해 C++ 라이브러리 PolarSSL을 사용하고 있습니다. 그러나 암호화 된 문자열이 아니라면 암호화 된 문자열을 해독 할 수 없습니다. 다음 코드는 작동하지 않습니다 (리팩토링되지 않습니다). 텍스트를 암호화하고 출력을 Base64로 인코딩하고 다시 인코딩합니다. strcmp에 대한 조건 (문자열은 동일 함). 내가 암호화에서 outputBuffer와 rsa_pkcs1_decrypt를 호출하는 경우rsa 암호화/암호 해독 polarssl C++

AsymetricCipher::encrypt(const std::string &pathToPublicKey, std::istream &inputData, std::ostream &encryptedData) { 
    if(initServerPublicCtx(pathToPublicKey, 512)) { 
     std::cout << "Encryption error: Can't load public key from file: " << pathToPublicKey << std::endl; 
     return false; 
    } 

    entropy_context entropy; 
    ctr_drbg_context ctr_drbg; 
    char *pers = "rsa_encrypt"; 

    entropy_init(&entropy); 
    if(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, (unsigned char*)pers, strlen(pers)) != 0) { 
     std::cout << "Encryption error: ctr_drbg_init failed" << std::endl; 
     return false; 
    } 

    size_t inputSize = ::getStreamSize(inputData); 
    char *input = new char[inputSize]; 
    memset(input, 0, inputSize); 
    inputData.read(input, inputSize); 
    input[inputSize] = '\0'; 

    unsigned char *buffer = new unsigned char[ctx.len]; 
    memset(buffer, 0, ctx.len); 
    memcpy(buffer, input, inputSize); 

    // This has to be rewritten 
    size_t MAX_OUTPUT_LENGTH = ctx.len; 
    unsigned char *outputBuffer = new unsigned char[MAX_OUTPUT_LENGTH]; 
    memset(outputBuffer, 0, MAX_OUTPUT_LENGTH); 

    if(rsa_pkcs1_encrypt(&ctx, ctr_drbg_random, &ctr_drbg, RSA_PUBLIC, inputSize, buffer, outputBuffer) != 0) { 
     std::cout << "Encryption error: rsa_pkcs1_encrypt failed" << std::endl; 
     return false; 
    } 

    initServerPrivateCtx("data/private.key", 512); 
    size_t outputSize = 0; 

    std::string copyBuffer = ""; 

    std::stringstream encStream; 

    std::string base64 = ""; 

    Base64Wrapper::encode(outputBuffer, strlen((char*)outputBuffer), base64); 


    for(size_t i = 0; i < base64.length();) { 
     encStream << base64[i++]; 
    } 

    unsigned char *encBuffer = new unsigned char[MAX_OUTPUT_LENGTH+10]; 
    memset(encBuffer, 0, MAX_OUTPUT_LENGTH); 
    encStream.read((char *)encBuffer, MAX_OUTPUT_LENGTH+10); 
    copyBuffer.append((char *)encBuffer); 

    unsigned char *decoded = NULL; 
    size_t decodedSize = 0; 

    Base64Wrapper::decode(copyBuffer, &decoded, &decodedSize); 
    decoded[decodedSize] = '\0'; 

    if(strcmp((char*)outputBuffer, (char*)decoded) != 0) { 
     std::cout << "Different"; 
    } 

    memset(buffer, 0, ctx.len); 

    if(rsa_pkcs1_decrypt(&ctx, RSA_PRIVATE, &outputSize, decoded, buffer, MAX_OUTPUT_LENGTH) != 0) { 
     std::cout << "Decryption error: rsa_pkcs1_decrypt failed" << std::endl; 
     return false; 
    } 

    ::cleanMemory(outputBuffer, MAX_OUTPUT_LENGTH); 
    ::cleanMemory(buffer, ctx.len); 

    delete [] outputBuffer; 
    delete [] buffer; 
    delete [] encBuffer; 
    delete [] decoded; 
    //delete [] input; 

    return true; 
} 

그러나, 모든 것이 잘 작동합니다.

텍스트를 암호화하고 보내고 코드의 다른 위치에서 해독해야합니다.

어떤 제안을 잘못 했습니까?

답변

1

는 드디어 해결책을 찾았습니다. 이 \0rsa_pkcs1_encrypt 시작 출력하기 때문에 항상 0했다 becuase

이 문제는 strlen((char*)outputBuffer)했다.

적합한 솔루션은 실수했지만 내 문제가 해결되지 않았다

bool AsymetricCipher::encrypt(const std::string &pathToPublicKey, std::istream &inputData, std::ostream &encryptedData) { 
    if(initServerPublicCtx(pathToPublicKey, 512)) { 
     std::cout << "Encryption error: Can't load public key from file: " << pathToPublicKey << std::endl; 
     return false; 
    } 

    entropy_context entropy; 
    ctr_drbg_context ctr_drbg; 
    char *pers = "rsa_encrypt"; 

    entropy_init(&entropy); 
    if(ctr_drbg_init(&ctr_drbg, entropy_func, &entropy, (unsigned char*)pers, strlen(pers)) != 0) { 
     std::cout << "Encryption error: ctr_drbg_init failed" << std::endl; 
     return false; 
    } 


    size_t inputSize = ::getStreamSize(inputData); 
    unsigned char *buffer = new unsigned char[inputSize]; 
    memset(buffer, 0, inputSize); 
    inputData.read((char *)buffer, inputSize); 


    size_t MAX_OUTPUT_LENGTH = ctx.len; 
    unsigned char *outputBuffer = new unsigned char[MAX_OUTPUT_LENGTH]; 
    memset(outputBuffer, 0, MAX_OUTPUT_LENGTH); 

    bool retVal = true; 
    if(rsa_pkcs1_encrypt(&ctx, ctr_drbg_random, &ctr_drbg, RSA_PUBLIC, inputSize, buffer, outputBuffer) != 0) { 
     std::cout << "Encryption error: rsa_pkcs1_encrypt failed" << std::endl; 
     retVal = false; 
    } 

    if(retVal) { 
     std::string base64; 
     Base64Wrapper::encode(outputBuffer, MAX_OUTPUT_LENGTH, base64); 
     encryptedData << base64; 
     ::cleanMemory(base64); 
    } 

    ::cleanMemory(outputBuffer, MAX_OUTPUT_LENGTH); 
    ::cleanMemory(buffer, ctx.len); 

    delete [] outputBuffer; 
    delete [] buffer; 

    return retVal; 
} 

그리고 암호 해독에 답장을

bool AsymetricCipher::decrypt(const std::string &pathToPrivateKey, std::istream &encryptedData, std::ostream &decryptedData) { 
    if(initServerPrivateCtx(pathToPrivateKey, 512)) { 
     std::cout << "Decrypt error: Can't load private key from file: " << pathToPrivateKey << std::endl; 
     return false; 
    } 

    size_t inputSize = ::getStreamSize(encryptedData); 
    size_t outputSize = 0; 

    unsigned char* buffer = NULL; 
    std::string base64; 
    size_t bufferSize = 0; 
    encryptedData >> base64; 

    Base64Wrapper::decode(base64, &buffer, &bufferSize); 
    ::cleanMemory(base64); 

    size_t MAX_OUTPUT_LENGTH = ctx.len; 
    unsigned char *outputBuffer = new unsigned char[MAX_OUTPUT_LENGTH]; 

    bool retVal = true; 
    if(rsa_pkcs1_decrypt(&ctx, RSA_PRIVATE, &outputSize, buffer, outputBuffer, MAX_OUTPUT_LENGTH) != 0) { 
     std::cout << "Decryption error: rsa_pkcs1_decrypt failed" << std::endl; 
     retVal = false; 
    } 

    if(retVal) { 
     outputBuffer[outputSize] = '\0'; 
     decryptedData << outputBuffer; 
    } 

    ::cleanMemory(buffer, bufferSize); 
    ::cleanMemory(outputBuffer, outputSize); 

    delete [] outputBuffer; 
    delete [] buffer; 

    return retVal; 
} 
1

클래식 메모리 오버 플로우

char *input = new char[inputSize]; 
input[inputSize] = '\0'; 
+0

감사합니다. 'rsa_pkcs1_decrypt'에서'POLARSSL_ERR_RSA_INVALID_PADDING' 오류가 나타납니다. 그러나'rsa_pkcs1_decrypt (& ctx, RSA_PRIVATE, & outputSize, outputBuffer, buffer, MAX_OUTPUT_LENGTH)'를 호출하면'outputbuffer'가'rsa_pkcs1_encrypt'에서 출력되는데 제대로 작동합니다. – tvazac

관련 문제