C/C++ 中,modulus,privateExponent, pulbicExponent 如何转换成 RSA密钥

p.s: 以下内容均以 openssl 实现。
RSA 密钥的存储方式有很多,某些情况下,我们直接保存密钥的 modulus(n),publicExponent(e),privateExponent(d),使用的时候再将它们转换成 RSA 密钥。下面来讲讲在 C/C++ 环境中,如何把这几个大整数转换成 RSA 密钥来用。
根据 openssl 的文档,openssl提供了这样一个函数

int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d);

这个参数里面的 n , e , q 对应 RSA 算法里面的参数,实际使用中,它们分别是

  • n --> modulus
  • e --> publicExponent
  • d --> privateExponent

其中,n和e组成了公钥,n和d组成私钥(取自 RSA算法原理),那么,我们想用 modulus(n),publicExponent(e),privateExponent(q) 来生成一个RSA密钥使用的话,可以用下面这样简短的方式

RSA* rsa = RSA_new();
BIGNUM* modulus = BN_new();
BIGNUM* publicExponent = BN_new();
BIGNUM* privateExponent = BN_new();
BN_hex2bn(&modulus,"the_modulus_hex_str");
BN_hex2bn(&publicExponent,"the_publicexponent_hex_str");
BN_hex2bn(&privateExponent,"the_privateexponent_hex_str");
RSA_set0_key(rsa,n,e,d);

其中,"the_modulus_hex_str" ,"the_publicexponent_hex_str","the_privateexponent_hex_str"是指对应的巨大整数的十六进制字符串。例如

n: XXXXXX31C433EDD1B99CE2B218C253F46FDFFFB888B6CFC6B2ED7C733454E744BF95369DA3E6648AFB6FB11EF85A5BB25A1F328266844C2E3FAC8EFAAB4B2C45588604BAC6CF8A9B528F0D03E6B56BDE534B0360F1BD9E8B36D4197FE6F058D97DE670C0F178D9633FEEAE94237827A4006BC737344932E8F3E349F62175B7
e: 010001
d: XXXXXXX6566B839C1F88C15D1A46771F1E4C3918000787D56016208B758F3E1A33A923226850DA53C288F9CF6753DFBE48750A83B3DE58D5C0B85933C5B92ABCCD60D80992AABA03C3B1A7E58B8289A93383D8DAA4EE23178660D09E0335522EDCEAD84FB34D7A39B7794C905F15883FC8D1F3D57790259B4D51BA25F67D2D211

上面对应的巨大整数的十进制数为

n: XXXXXXX9057732971629580498028671059682869498690832625587443656573925941563146104539350008204291144532450083831552937873084816334755400478676505846850294967700928692649221538739009633205352515287702420255727528786212412171786407245232978625501660599119803054000638252479305264674077018562561222430729026237879
e: 65537
d: XXXXXXXX041865311331499528401083208041704898325216901065444649537573972168292421030450065823066407208305456734951704373218531670621023627175563960996010664960509836168571614423098404829680294776295068450558648709945648817915783177775326687433116356887666860252766677606932669252345719029413488408688871813075473

这样,我们就得到了一个RSA密钥。接下来可以使用这个密钥对一些数据加密/解密。
比如,使用 RSA/ECB/PKCS1Padding 填充方式,进行公钥加密,私钥解密例子

    char encrypteddata[1024] = { 0 };
    char originnaldata[1024] = { 0 };
    const char* testinfo = "this is a sample info to encrypt";
    int encryptlen = 0;
    int retlen = 0;
    encryptlen = RSA_public_encrypt(strlen(testinfo), (const unsigned char*)testinfo, (unsigned char *)encrypteddata, rsa, RSA_PKCS1_PADDING);
    if (encryptlen > 0)
    {
        retlen = RSA_private_decrypt(encryptlen, (const unsigned char*)encrypteddata, (unsigned char*)originnaldata, rsa, RSA_PKCS1_PADDING);
        if (retlen > 0)
        {
            printf("%.*s\n", retlen, originnaldata);
        }
    }

openssl 里面,公钥加密,私钥解密的函数原型是

 int RSA_public_encrypt(int flen, const unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);

 int RSA_private_decrypt(int flen, const unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);

同样的,还有私钥加密,公钥解密的函数原型是

 int RSA_private_encrypt(int flen, unsigned char *from,
                         unsigned char *to, RSA *rsa, int padding);

 int RSA_public_decrypt(int flen, unsigned char *from,
                        unsigned char *to, RSA *rsa, int padding);

参考资料:

  1. rsa-ecb-pkcs1padding(openssl)
  2. openssl doc
  3. RSA算法原理
posted @ 2022-04-10 20:16  SupperMary  阅读(708)  评论(0编辑  收藏  举报