openssl RSA基本加密解密

时间:2021-11-17 18:31:21
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>

int main(int argc, char *argv[])
{
// 产生RSA密钥对
RSA *rsaKey = RSA_generate_key(1024, 65537, NULL, NULL);

int keySize = RSA_size(rsaKey);

char fData[]="aaabbbccdskjkfd";
char tData[128];

int flen = strlen(fData);
//flen = 15

int ret = RSA_public_encrypt(flen, (unsigned char *)fData, (unsigned char *)tData, rsaKey, RSA_PKCS1_PADDING);
//ret = 128

ret = RSA_private_decrypt(128, (unsigned char *)tData, (unsigned char *)fData, rsaKey, RSA_PKCS1_PADDING);
//ret = 15

RSA_free(rsaKey);
return 0;
}


VC6.0编译通过

RSA_generate_key产生密钥对
参数一:密钥长度是 1024bit (小于1024被认为是不安全的)
参数二:公开的加密指数,通常是一个奇数,一般为3, 17 or 65537
后两个参数,回调函数和回调函数的参数,一般用不着。

RSA结构

struct rsa_st {
/*
* The first parameter is used to pickup errors where this is passed
* instead of aEVP_PKEY, it is set to 0
*/
int pad;
long version;
const RSA_METHOD *meth;
/* functional reference if 'meth' is ENGINE-provided */
ENGINE *engine;
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
...
};

BIGNUM是个什么东西呢?


struct bignum_st {
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};

因为计算机一般是32位或者64位的,表示一个很大的数有困难,所以用这个BIGNUM表示。
这个大数就存在d这块内存里,这块内存的大小是dmax。


TIPS

可以用printf("%s\n", BN_bn2hex(rsaKey->e));

打印出大数,假设这个大数是65537,则打印出来的是010001。


调用函数后,可得到的结构体内容为
-    rsaKey    0x00382db8
    pad    0
    version    0
+    meth    0x1010b350
    engine    0x00000000
-    n    0x003845b0
-        d    0x00384af8
        3364328589
    top    32
    dmax    64
    neg    0
    flags    1
-    e    0x00384610
-        d    0x00384730
          65537
    top    1
    dmax    1
    neg    0
    flags    1
-    d    0x003845e0
-        d    0x00385158
            3055509717
    top    32
    dmax    32
    neg    0
    flags    1
+    p    0x00384670
+    q    0x00384640

[MODULES]          模数   n
[PUBLIC EXPONENT]  公钥指数   e
[PRIVATE_EXPONENT]  私钥指数  d

n+e组成公钥
n+d组成私钥



RSA_public_encrypt
参数一:被加密的数据的长度
参数二:被加密数据
参数三:用于存放加密后的数据
参数四:密钥对
参数五:填充方式

RSA_private_decrypt
参数一:被解密的数据的长度
参数二:被解密数据
参数三:用于存放解密后的数据
参数四:密钥对
参数五:填充方式




补充:使用指定数字生成RSA密钥对


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>

int main(int argc, char *argv[])
{
BIGNUM *bn_e,*bn_n,*bn_d;
RSA *r;


//模数
const char *MODULUS="9EC7D9A2DC5B095F8E5F90295121F41262FAEFBE9AF57B772A71F1F9D9635F8769CB78DA2BCFE9B27FC1F3AD4A3D178F8C61981225EF5DEACBDC5665F12E691AA13DDD321A59CFCF376F002036612FF3C5E057A3007FF675AFA3EDE34DC23A1A2637294870EBE823F76B5CE21E25F3FA5137F5DE12437DE0118245B927B28221";
//公钥指数
unsigned long e = 65537;
//私钥指数
const char *PRIVATE="8B26E30ECA6E8F3668F6FA78B0C55FB75A4A3FAD0667B152933A4991D7A815D1498F5E1EF44ACEF6CDF252E56F367DED5BA024DF6B267B7E36BD35552DFA0A4CC1E9D0A4BC8E7C76F98D4971441D6693745A0A76E175571BD160E4B1536A6EFF5A08EDA45236E96E7A4748CF4D031CA8B2F4CCE9F2E1286F432DE6495A535E43";


bn_e = BN_new();
bn_d = BN_new();
bn_n = BN_new();
int ret = BN_set_word(bn_e, e);
BN_hex2bn(&bn_d, PRIVATE);
BN_hex2bn(&bn_n, MODULUS);

r = RSA_new();
r->e=bn_e;
r->d=bn_d;
r->n=bn_n;

RSA_free(r);
return 0;
}