王铁树 2015-08-05 00:52 采纳率: 28.6%
浏览 6785
已采纳

有全部源码,我调用openssl库的RSA和AES算法进行加密。加密字符串太长就会报错,具体如下。

报错信息是这样的:
Error encrypting message: error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size
Error decrypting message: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02

我用的Linux环境进行开发的,不过也应该没有太大关系啦!
另外代码上有什么问题也可以指出来,万分感谢!!!
具体代码 如下:

 #include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <assert.h>
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>

#define RSA_KEYLEN 2048
#define AES_KEYLEN 128
#define AES_ROUNDS 6

#define KEY_SERVER_PRI 0
#define KEY_SERVER_PUB 1
#define KEY_CLIENT_PUB 2
#define KEY_AES        3
#define KEY_AES_IV     4
#define KEY_LENGTH  2048
#define PUB_EXP     3

//用AES进行加密
int EncodeAES(unsigned char* password,unsigned int pass_len, unsigned char* data,unsigned int data_len,unsigned char** out_data,unsigned int *out_len)
{
    AES_KEY aes_key;
    if(AES_set_encrypt_key((const unsigned char*)password, 192, &aes_key) < 0)  
    {
        assert(false);
        return -1;
    }
    std::string  strRet;
    std::string  data_bak((const char*)data);
    unsigned int data_length = data_len;

    int padding = 0;
    if (data_len % AES_BLOCK_SIZE > 0)
    {
        padding =  AES_BLOCK_SIZE - data_len % AES_BLOCK_SIZE;
    }
    data_length += padding;
    while (padding > 0)
    {
        data_bak += '\0';
        padding--;
    }
    for(unsigned int i = 0; i < data_length/AES_BLOCK_SIZE; i++)
    {
        std::string str16 = data_bak.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);
        unsigned char out[AES_BLOCK_SIZE];
        ::memset(out, 0, AES_BLOCK_SIZE);
        AES_encrypt((const unsigned char*)str16.c_str(), out, &aes_key);
        strRet += std::string((const char*)out, AES_BLOCK_SIZE);
    }

    *out_len=strRet.length();
    *out_data=(unsigned char*)malloc(*out_len);
    *out_data=(unsigned char*)strRet.c_str();
    return 0;
}


//用aes进行解密
int DecodeAES(unsigned char *password,unsigned int pass_len, unsigned char* data,unsigned int data_len,unsigned char** out_data,unsigned int *out_len )
{
    AES_KEY aes_key;
    if(AES_set_decrypt_key((const unsigned char*)password, 192, &aes_key) < 0)
    {
        assert(false);
        return -1;
    }
    std::string strRet;
    std::string strData((const char*)data);
    try
    {
        for(unsigned int i = 0; i < data_len/AES_BLOCK_SIZE; i++)
        {
            std::string str16 = strData.substr(i*AES_BLOCK_SIZE, AES_BLOCK_SIZE);
            unsigned char out[AES_BLOCK_SIZE];
            ::memset(out, 0, AES_BLOCK_SIZE);

            AES_decrypt((const unsigned char*)str16.c_str(), out, &aes_key);
            strRet += std::string((const char*)out, AES_BLOCK_SIZE);

        } 
    }
    catch (std::exception const &exc)
    {
        std::cerr << "Exception caught " << exc.what() << "\n";
    }
    catch (...)
    {
        std::cerr << "Unknown exception caught\n";
    }
    *out_len=strRet.length();
    *out_data=(unsigned char*)malloc(*out_len);
    *out_data=(unsigned char*)strRet.c_str();
    return 0;
}

//生成RSA需要的公钥和私钥
int generateRSAKeys(char ** pri_key, char ** pub_key) {
    RSA *keypair = RSA_generate_key(KEY_LENGTH, PUB_EXP, NULL, NULL);

    // To get the C-string PEM form:
    BIO *pri = BIO_new(BIO_s_mem());
    BIO *pub = BIO_new(BIO_s_mem());

    PEM_write_bio_RSAPrivateKey(pri, keypair, NULL, NULL, 0, NULL, NULL);
    PEM_write_bio_RSAPublicKey(pub, keypair);

    size_t pri_len = BIO_pending(pri);
    size_t pub_len = BIO_pending(pub);

    char* prikey = (char*)malloc(pri_len + 1);
    char* pubkey = (char*)malloc(pub_len + 1);

    if (prikey == NULL&&pubkey == NULL)
    {
        return -1;
    }

    BIO_read(pri, prikey, pri_len);
    BIO_read(pub, pubkey, pub_len);

    *pri_key = prikey;
    *pub_key = pubkey;

    RSA_free(keypair);
    BIO_free_all(pri);
    BIO_free_all(pub);
    return 0;
}


//用RSA公钥进行加密
int encryptWithPub(char *pub_key,char* msg, char **encrypt, int* encrypt_len ) {
    RSA *rsa = NULL;
    BIO* keybio = BIO_new_mem_buf((void *)pub_key, -1);
    char *err = (char*)malloc(130);

    if (keybio == NULL) {
        printf("failed to create key BIO\n");
        return -1;
    }

#ifdef RSAPUBKEY
    if ((rsa = PEM_read_bio_RSA_PUBKEY(keybio, NULL, NULL, NULL)) == NULL)
#else
    if ((rsa = PEM_read_bio_RSAPublicKey(keybio, NULL, NULL, NULL)) == NULL)
#endif

        if (!rsa){
            printf(" rsa is null %s\n", ERR_error_string(ERR_get_error(), NULL));
            return -1;
        }
    *encrypt_len = RSA_size(rsa);
    *encrypt = (char *)malloc(1024);

    if ((RSA_public_encrypt(strlen(msg) + 1, (unsigned char*)msg, (unsigned char*)*encrypt,rsa, RSA_PKCS1_PADDING)) == -1) 
    {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error encrypting message: %s\n", err);
        return -1;
    }

    RSA_free(rsa);
    free(err);
    BIO_free_all(keybio);
    // *encrypt_len=enstr.length();
    return 0;
}

//用RSA私钥进行解密
int decryptWtihPri(char *pri_key,char* msg,char **decrypt, int encrypt_len){
    RSA *rsa = NULL;
    BIO* keybio = BIO_new_mem_buf(pri_key, -1);
    if (keybio == NULL) {
        printf("failed to create key BIO\n");
        return -1;
    }


#ifdef RSAPRIVATE
    if ((rsa = PEM_read_bio_RSA_PRIVATE(keybio, NULL, NULL, NULL)) == NULL)
#else
    if ((rsa = PEM_read_bio_RSAPrivateKey(keybio, NULL, NULL, NULL)) == NULL)
#endif


        if (!rsa){
            printf(" rsa null %s\n", ERR_error_string(ERR_get_error(), NULL));
            return -1;
        }
    char *err = (char*)malloc(130);
    *decrypt = (char*)malloc(encrypt_len);
    if (RSA_private_decrypt(encrypt_len, (unsigned char*)msg, (unsigned char*)*decrypt, rsa, RSA_PKCS1_PADDING) == -1) {
        ERR_load_crypto_strings();
        ERR_error_string(ERR_get_error(), err);
        fprintf(stderr, "Error decrypting message: %s\n", err);
        return -1;
    }

    RSA_free(rsa);
    free(err);
    BIO_free_all(keybio);
    return 0;
}

/**
*测试函数部分
*/

int test_aes();
int test_rsa();

int main()
{
    test_rsa();
    test_aes();
    return 0;
} 

int test_rsa()
{
    printf("\n----------THE RSA TESTING -------- \n");
    char * pri_key;
    char * pub_key;
    generateRSAKeys(&pri_key, &pub_key);

    //printf("\n%s\n%s\n", pri_key, pub_key);

    char *encrypt;
    char *decrypt;
    int encrypt_length;
    encryptWithPub(pub_key,(char *)"i havei have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a key a key",&encrypt, &encrypt_length);

    decryptWtihPri( pri_key,encrypt, &decrypt,encrypt_length);
    printf("decrypted message: %s\n", decrypt);

    return 0;
}


int test_aes()
{
    printf("\n----------THE AES TESTING --------\n");
    char* pass=(char*)"key";
    int ret;
    char* data=(char*)"infocoei have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a key ei have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a key re big tree ";
    char *output=NULL;
    unsigned int out_len;
    char *newoutput=NULL;
    unsigned int new_len;

    std::cout<<"the length of key:"<<strlen(pass)<<std::endl;
    std::cout<<"before encryption:"<<data<<std::endl;

    ret=EncodeAES((unsigned char*)pass, strlen(pass),(unsigned char *)data,strlen(data),(unsigned char **)&output, &out_len);
    //std::cout<<"the en len:"<<out_len<<std::endl;
    ret=DecodeAES((unsigned char*)pass, strlen(pass),(unsigned char *)output,out_len,(unsigned char **)&newoutput, &new_len);
    //std::cout<<"the deenc len:"<<new_len<<std::endl;
    std::cout<<"after decryption:"<<newoutput<<std::endl;

}

代码的运行结果如下:

 ----------THE RSA TESTING -------- 
Error encrypting message: error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size
Error decrypting message: error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
decrypted message: 惙l=

----------THE AES TESTING --------
the length of key:3
before encryption:infocoei have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a key ei have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a keyi have a key re big tree 
Exception caught basic_string::substr
after decryption:Ϝż§§<¾yK*. 

[root@localhost boost_encryption]# 

我的邮箱是fubohuauser@163.com 有啥问题也可以一起联系交流。谢谢

  • 写回答

1条回答

  • oyljerry 2015-08-05 01:29
    关注

    rsa加密算法是有限制的。受到密钥长度限制。你应该把要加密的内容分块。一块块加密。这样可以避免长度限制问题

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题