【问题标题】:rsa encryption/decryption polarssl c++rsa加密/解密polarssl c++
【发布时间】:2012-11-27 10:25:41
【问题描述】:

我正在使用 C++ 库 PolarSSL 进行 RSA 加密和解密。但是我无法解密加密的字符串,除非它是加密的输出。以下代码不起作用(未重构)。它加密文本并将输出编码到 Base64 并返回。 strcmp 的条件有效(字符串相同)。

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;
}

但是,如果我从加密中使用outputBuffer 调用 rsa_pkcs1_decrypt,一切正常。

我需要对文本进行加密、发送和解密。

任何建议我做错了什么?

【问题讨论】:

    标签: c++ rsa polarssl


    【解决方案1】:

    经典内存溢出

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

    【讨论】:

    • 感谢您的回复,这是一个错误,但它并没有解决我的问题。我从rsa_pkcs1_decrypt 收到POLARSSL_ERR_RSA_INVALID_PADDING 错误。但是如果我打电话给rsa_pkcs1_decrypt(&amp;ctx, RSA_PRIVATE, &amp;outputSize, outputBuffer, buffer, MAX_OUTPUT_LENGTH),其中outputBufferrsa_pkcs1_encrypt 的输出,它就可以正常工作。
    【解决方案2】:

    我终于找到了解决办法。

    问题是strlen((char*)outputBuffer),因为它始终是0,因为rsa_pkcs1_encrypt 的输出以\0 开头。

    正确的解决方案是

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 1970-01-01
      • 2012-06-02
      • 2013-03-17
      • 1970-01-01
      • 2012-03-13
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多