如何制作一个rsa加密C++和解密C#

本文关键字:C++ 加密 解密 rsa 一个 何制作 | 更新日期: 2023-09-27 17:58:33

我遇到了一个问题-与客户端、用C#编写的服务器以及C++(Windows MacOs Linux)上的客户端进行加密通信。

我为Rijndael生成了一个密钥,RSA对其进行加密并发送给服务器。

我的问题是我不能加密RSA,我有一个带有公钥的xml文件

<RSAKeyValue><Modulus>pmmv...</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>

我如何使用C++?可能有一个适用于所有平台的库或更好的算法,将其包含在草案中

我在谷歌上找到了一个算法,但它需要BigInt的公钥格式。如何摆脱XML?

如何制作一个rsa加密C++和解密C#

表示格式为RFC 3275,XML签名语法和处理。

您需要解析RFC 3275 RSAKeyValue,然后将其放入OpenSSL RSA结构中。

有点痛苦。。。。你确定要看吗?(XML解析留给读者练习,但它使用了上面提供的值)。

#include <stdio.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
int main(int argc, char* argv[])
{
    int ret = -1;
    char nz[] = "sqprMX0n4y1gmmgpTt6pHb870k5U0MIuXixidD+S8foQf5Bb"
             "FS44kth2uWDKzXOXqiONxIPHPb+84XdxrRi2O7bvLysztgrF"
             "eU8oNDMeuIwJOKVQzKoJ1vGqjBKiA9w48oQKxvO+Ck3GmObW"
             "67LFNcrt50sEco2/OMmrpiH3W8hRx55TcR1flCJduU0/6jA7"
             "Yct9ZfhOw5wBq6o5IwiT8Mi1R6LVq9sTzSNAWHC/bFcEONkt"
             "z6NgUKbFKtt+mTfFGToiwPB1L4TecGyTIweH84nl8jVAngcM"
             "vvFP415Eg1kd9PJbRqrIESM5AU1YcsapWV3bsqEGVS2y+r5N"
             "4yzXPCYRCRyFWJSnNVlax+gtDFTNz3m9UT8m2E7elGe5hPhR"
             "6nN3votzBNvTeQ4Lwc5JDIvnWUg7aOdVIXnHQbBqEQke79BX"
             "xIv8tzVPczGkFqFExkmPPQQv8zJvBKkIYc+BFJtkylBiZfQX"
             "0590NS3L1y31VSeXn8Ncx2/ceJfUXsMWJ3sQ+dk51MKBJ2LL"
             "oyJq8IgloBLnXWvlYZ+tkzRVTExFR277V3Jr17DeTOMQGEg5"
             "HqRkbDDVGPTl2RvC2S2BTe7+r9xNzyAZMieVjZLZgb6icE6u"
             "SJFcu4qqJ1khQUjW7taymqW8Ao3oEiCUJKvRpZcJPMN+JtMn"
             "ji+2we17ytk=";
    char ez[] = "AQAB";
    BIO* nn = NULL, *ee = NULL;
    BIO* b1 = NULL, *b2 = NULL;
    RSA* rsa = NULL;
    nn = BIO_new_mem_buf(nz, strlen(nz));
    if(!nn) { ret = 1; goto done; }
    ee = BIO_new_mem_buf(ez, strlen(ez));
    if(!ee) { ret = 2; goto done; }
    b1 = BIO_new(BIO_f_base64());
    if(!b1) { ret = 3; goto done; }
    b2 = BIO_new(BIO_f_base64());
    if(!b2) { ret = 4; goto done; }
    /* If you leave these out even though you   */
    /* are reading, then BIO_read will return 0 */
    /* and BIO_should_retry will return false   */
    BIO_set_flags(b1, BIO_FLAGS_BASE64_NO_NL);
    BIO_set_flags(b2, BIO_FLAGS_BASE64_NO_NL);
    nn = BIO_push(b1, nn);
    if(!nn) { ret = 5; goto done; }
    ee = BIO_push(b2, ee);
    if(!ee) { ret = 6; goto done; }
    rsa = RSA_new();
    if(rsa == NULL) { ret = 7; goto done; }
    unsigned char buff[4096];
    const int bsize = sizeof(buff);
    int rr = 0, rd = 0;
    /* See http://marc.info/?l=openssl-users&m=123171064303018&w=2 */
    /* for this contorted goodness */
    rd = 0;
    do {
        rr = BIO_read(nn, buff + rd, bsize - rd);
        if(rr < 0) { ret = 8; goto done; } /* failed */
        rd += rr;
    } while (rr > 0 || BIO_should_retry(nn));
    if(rd == 0) { ret = 9; goto done; }
    rsa->n = BN_bin2bn(buff, rd, NULL);
    if(rsa->n == NULL) { ret = 10; goto done; }
    rd = 0;
    do {
        rr = BIO_read(ee, buff + rd, bsize - rd);
        if(rr < 0) { ret = 11; goto done; } /* failed */
        rd += rr;
    } while (rr > 0 || BIO_should_retry(ee));
    if(rd == 0) { ret = 12; goto done; }
    rsa->e = BN_bin2bn(buff, rd, NULL);
    if(rsa->e == NULL) { ret = 13; goto done; }
    /***** Paydirt *****/
    RSA_print_fp(stdout, rsa, 0);
    ret = 0;
done:
    if(ret != 0)
        fprintf(stderr, "Failed to parse and validate RSA key'n");
    if(rsa)
       RSA_free(rsa), rsa = NULL;
    if(nn)
        BIO_free_all(nn), nn = NULL;
    if(ee)
        BIO_free_all(ee), ee = NULL;
    return ret;
}

通过解析XML,base64对文本中的文本进行解码,并使用生成的字节数组创建一个无符号大整数,一个用于模数,一个用作公共指数(尽管后者可能总是0x10001或65537,这是Fermat F4的第四个数字,就像现在用于当前密钥对生成器一样)。

如果只需要做一次,还可以对字符串进行base64解码,并手动将结果复制到C++代码中。