openssl 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[]) { // 产生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; }