openssl
私钥生成
#include "base64.h"
#include <openssl/x509.h>
#include <openssl/pem.h>
int rsaLib:: genRsaKey ( char * priKey, char * priPwd, char * pubKey)
{
EVP_PKEY * pEVPKey = NULL ;
RSA * pRSA = NULL ;
int bits = 2048 ;
unsigned long E = RSA_F4;
pRSA = RSA_generate_key ( bits, E, NULL , NULL ) ;
pEVPKey = EVP_PKEY_new ( ) ;
EVP_PKEY_assign_RSA ( pEVPKey, pRSA) ;
toFormatPri ( pRSA, priKey) ;
toFormatPriPwd ( pEVPKey , priKey, priPwd) ;
toFormatPriFile ( pRSA) ;
toFormatPriPwdFile ( pEVPKey, priPwd) ;
}
私钥转换:包括是否带密码,生成文件,DER/PEM格式
私钥转换为带密码保护的DER格式
i2d_PKCS8PrivateKey_bio
解密待测试
int toFormatPriPwd ( EVP_PKEY * pEVPKey, char * base64, char * pwd)
{
int iRV, nLen, baseLen = 0 ;
BUF_MEM * pBMem = NULL ;
BIO * pBIO = NULL ;
pem_password_cb * passphrase;
pBIO = BIO_new ( BIO_s_mem ( ) ) ;
iRV = i2d_PKCS8PrivateKey_bio ( pBIO, pEVPKey, EVP_des_ede3_cbc ( ) , pwd, strlen ( pwd) , passphrase, pwd) ;
BIO_get_mem_ptr ( pBIO, & pBMem) ;
baseLen = getEncodeLen ( pBMem- > length, ( unsigned char * ) pBMem- > data) ;
if ( base64)
memcpy ( base64, base64_encode ( pBMem- > length, ( unsigned char * ) pBMem- > data) , baseLen) ;
base64[ baseLen] = '\0' ;
printf ( "pwd pri DER\n%s\n" , base64) ;
BIO_free ( pBIO) ;
return 0 ;
}
私钥转换为带密码保护的PEM格式
PEM_write_bio_PKCS8PrivateKey
int toFormatPriPwd ( EVP_PKEY * pEVPKey, char * base64, char * pwd)
{
pBIO = BIO_new ( BIO_s_mem ( ) ) ;
if ( PEM_write_bio_PKCS8PrivateKey ( pBIO, pEVPKey, EVP_des_ede3_cbc ( ) , NULL , 0 , 0 , pwd) != 1 ) {
printf ( "private key error\n" ) ;
}
BIO_get_mem_ptr ( pBIO, & pBMem) ;
if ( base64)
{
memcpy ( base64, pBMem- > data, pBMem- > length) ;
}
BIO_free ( pBIO) ;
return 0 ;
}
私钥转换为无密码的DER格式
i2d_RSAPrivateKey
公钥的话用i2d_RSA_PUBKEY
int toFormatPri ( RSA * pRSA, char * base64)
{
int nLen, baseLen = 0 ;
unsigned char * pDer = NULL ;
unsigned char * p = NULL ;
nLen = i2d_RSAPrivateKey ( pRSA, NULL ) ;
pDer = ( unsigned char * ) malloc ( nLen) ;
p = pDer;
nLen = i2d_RSAPrivateKey ( pRSA, & p) ;
baseLen = getEncodeLen ( nLen, pDer) ;
if ( base64)
memcpy ( base64, base64_encode ( nLen, pDer) , baseLen) ;
free ( pDer) ;
printf ( "not pwd pri DER\t%s\n" , base64) ;
return 0 ;
}
私钥转换为无密码的PEM格式
PEM_write_bio_RSAPrivateKey
公钥的话用PEM_write_bio_RSA_PUBKEY
int toFormatPri ( RSA * pRSA, char * base64)
{
BUF_MEM * pBMem = NULL ;
BIO * pBIO = NULL ;
pBIO = BIO_new ( BIO_s_mem ( ) ) ;
if ( PEM_write_bio_RSAPrivateKey ( pBIO, pRSA, NULL , NULL , 0 , NULL , NULL ) != 1 ) {
printf ( "private key error\n" ) ;
}
BIO_get_mem_ptr ( pBIO, & pBMem) ;
if ( base64)
{
memcpy ( base64, pBMem- > data, pBMem- > length) ;
}
printf ( "not pwd pri PEM\t%s\n" , base64) ;
BIO_free ( pBIO) ;
return 0 ;
}
私钥转换为带密码保护的PEM格式文件
PEM_write_bio_PKCS8PrivateKey
int toFormatPriPwdFile ( EVP_PKEY * pEVPKey, char * pfxPwd)
{
BIO * pBIO = NULL ;
int iRV = 0 , nLen = 0 ;
pBIO = BIO_new_file ( "priKey_pwd.pem" , "w" ) ;
if ( ! pBIO)
{
ZF_LOGE ( "priKey_pwd.pem pBIO error" ) ;
goto free_all;
}
iRV = PEM_write_bio_PKCS8PrivateKey ( pBIO, pEVPKey, EVP_des_ede3_cbc ( ) , NULL , 0 , 0 , pfxPwd) ;
if ( iRV != 1 ) {
ZF_LOGE ( "pri pwd error" ) ;
goto free_all;
}
free_all:
BIO_free ( pBIO) ;
return 0 ;
}
int toFormatPriPwdFile ( EVP_PKEY * pEVPKey, char * pfxPwd)
{
BIO * pBIO = NULL ;
int iRV = 0 , nLen = 0 ;
pBIO = BIO_new_file ( "priKey_pwd.der" , "w" ) ;
if ( ! pBIO)
{
ZF_LOGE ( "priKey_pwd.der pBIO error" ) ;
goto free_all;
}
iRV = i2d_PKCS8PrivateKey_bio ( pBIO, pEVPKey, EVP_des_ede3_cbc ( ) , NULL , 0 , 0 , pfxPwd) ;
if ( iRV != 1 )
{
ZF_LOGE ( "priKey_pwd.der error" ) ;
goto free_all;
}
free_all:
BIO_free ( pBIO) ;
return 0 ;
}
私钥转换为无密码的PEM格式文件
PEM_write_bio_RSAPrivateKey
公钥的话用PEM_write_bio_RSA_PUBKEY
int toFormatPriFile ( RSA * pRSA)
{
BIO * pBIO = NULL ;
BUF_MEM * pBMem = NULL ;
int iRV = 0 , nLen = 0 ;
pBIO = BIO_new_file ( "priKey.pem" , "w" ) ;
if ( ! pBIO)
{
ZF_LOGE ( "not pwd priKey.der pBIO error" ) ;
goto free_all;
}
iRV = PEM_write_bio_RSAPrivateKey ( pBIO, pRSA, NULL , NULL , 0 , NULL , NULL ) ;
if ( iRV != 1 ) {
ZF_LOGE ( "not pwd priKey.der error" ) ;
goto free_all;
}
free_all:
BIO_free ( pBIO) ;
return 0 ;
}
私钥转换为无密码的DER格式文件
i2d_RSAPrivateKey_bio
公钥的话用i2d_RSA_PUBKEY_bio
int toFormatPriFile ( RSA * pRSA)
{
BIO * pBIO = NULL ;
BUF_MEM * pBMem = NULL ;
int iRV = 0 , nLen = 0 ;
pBIO = BIO_new_file ( "priKey.der" , "w" ) ;
if ( ! pBIO)
{
ZF_LOGE ( "priKey.der pBIO error" ) ;
goto free_all;
}
iRV = i2d_RSAPrivateKey_bio ( pBIO, pRSA) ;
if ( iRV != 1 )
{
ZF_LOGE ( "priKey.der error" ) ;
goto free_all;
}
free_all:
BIO_free ( pBIO) ;
return 0 ;
}
私钥示例
带密码的PEM格式
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQI9R/QiovyBJMCAggA
MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECLJ/Ak/AqPOnBIIEyOssSm2qhYfb
mUOkBKFJJ0cGe7P7nhMOP9nBtUFb9OjVauyNsg5JBhedOs98mDdurWIWlcfWkmjx
+xfE9fL2Q9KciaJXnVGB9H2ugL5//PBWssXkCgE9B7z197Bk+iu2bqU/gKdlDH9W
c3QEqW1WaDLifjpEVFqBp7nejv/xM+s1dLWPSGCGMRWYkOqbVpdXwNXi2h0SCFdw
tEuAQUKg+6s+WC5uTl3261vu+YyRI71zvS4QN2oEhdA9IZzjj98suTGrgTDMFq/x
Wk0tcXjfFIbjM8xcKBMmCu7CZiCb/chqG6TXJ51lil8O5AveGXtpn76CASOQOXDb
zRlMZ8gDmVWIwcwbnJ3npCh0LV6Mnu+16apev2E57dQ06D78vOhPFXLXzxP6W4fr
FzYkP94pgS5GlBBuhgpodKiKRfn5PlmMVmi57HGnUzn+EoQBbBJQx/BKykaqaXfV
vr91eVbQNeO0AkrUM4eG9N475pajG+RHMQpKKKSvH/Zuut91wWTTct0hUTNhx4tA
0WV3WVARGwoht6UM8OryOIkn4JI3vON6NYKoUoMyEeLc8HZ2AkG+gmwT5YC+jBbV
jYQn3PpM6zJj4qxtZUFkzrXg8tstOsnGJjSGviwe8MCzz/HNKPno9LQlSyaRkPSP
CSKWsRm9ZmoJn+28QtU4wEQGHZyT4pAdXVDSW4YZOdIEdTFn6WKltk4xhl2/IYza
M6WSM/jduALy6mv4c6baX4Wd9Od0InUDR8F46jbwb8sZPA8EZfcempbpk/xXYsKe
2KgrWozniglT0Jz5l8lD5GANK7iwUcezL2Yqbl0XhudStNmhUDHv6t/ugfcp5NGT
CFie1zobVAcqamuN/OzW8bEv8PXTsmSoxD9ER0dZHXlrHCibppNfWeoTS2jjA38T
6Hw1/XoqJ7A3Aggd3/7uTGgPLNXB2wgB6nXIr5wNCdqrA6OA58iyml5B/CY0vfgW
iBBdaO4e0R18JWIH9nL8aVx+No5nkeQySFv/ly9ERXdp1cn77AScj87NT6trgUJi
f/vX89LB9DXNIxm0NxudIDB7HvqfqPSCRnygFox9A+6L6OW8b1FuVNC7KMrQULE5
NePWbqAYsKswoIxSgLSGK68eymGURjinHZeDYPa005s3ErNKeLmwISYe4CIew/oO
z1RvvA/zYAWmb7j2G/6gfoW2SJUEc0JU3eSJsxh3emS4A2PxNLxx+tIC185afU4+
pclPWqaiZDsRX7VRxd9nL26eadl3PzJFWvC0d7DO2BBls29Y/fP2/aOcR8GSzzd/
YO2jKkPDoA0M9+reKtTwh/reBDPZr6nA35iMcaxB3bzqE+NgiikifukNEOK0Lt+3
lmArGHl9N6EnKMRJlILbeUP6pCWMOHwy5eCOHLD9QIcSEJiTdW0teAg93ciK94EW
iiYyPtol65pGzlHatufklgNs7Y+ZGchpMezEB4wgEHgcKc/x+yePFFrPiWJheSAi
wa5KqI3VZA8TN0T0p+HROv2ch1+o1Lv8cPag/f4dWu/o6iYYAyzouyUXBOdNqgti
6rWaUrYqAfPW9qW9mGHnd3kMe3mpKYfImxxHSyTAq5rTPQots0CFrX4PWX/6q5JG
t0s44cY/YB0Sd7X4AJjCjw==
-----END ENCRYPTED PRIVATE KEY-----
无密码的PEM格式
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAqqfRjYpxciFvTIudsEKQdFdqglGFHvfBS00CvzZ96CqewwTO
uWKFsqQpakSYIlUkMupdn66+bhzxJNIpXm2H2C0oCj/08hBuFLscfq/qzHRXGGCr
DNWhTB9q0D4eQNZlix7MEwRK1vpFmZzw/9i+kWyuqUehsuO/oOVUtuKs1H00ny4H
NKIjjjSEhf7E46ovXMB0HfdV6CmgNcJY16h74vop3PkgG3R7w/1jedJe+E8tH9/N
4e0EYI3xUgzmkWKDFKCnGeW9JFVIBPTYJewtaRxQfZ8c6k3YzwcsjFcR9Wv/g7Ag
KskHEXLqhFoYprrPecjO/vJ/lnQLxgOSFROJhwIDAQABAoIBAFvHcW273RNSY/c4
xw+6XNIVCVUY3o0vFaeXvTh05/XqpgOgHEWbdOgEXbmnNmKQg61WWg+8/PFfY1k4
JcOBCKP8dSI+D0/4AhvoHYUMuyxGDWkw5A08/0hfRSTFo6OfKnFNmNdJYa6IXtIk
k4AlYyf22WB1A8OftLmlXJAXDHgiFKMvV7LWi55huRZcAedjYF/e2Qq0bVXwZs/v
neJohFdeJ3HAg8Do583L7wMuI8Jn6j2hqzUgUobrUaz4R0dF3uUyeZz2lvrHAVOT
rUFovwo+mraL06Vkm3nIran0xvRjVRSvKEbKfve0ozGer9CG0nVHdgYB0tf7PPL+
nIMzf7ECgYEA4cQKz1rmTmji//uPYaAg9F5FXhMK4cafZ+4lF206V/ZG/KmWDdQE
HAFctwJklEoX9fhLeBg5IcOsvsSYLmFVbvTQeip9HHD1ISgGQaHnS9iSrXpMbsoE
HEyHuETp6plZJUsNNDdPoxq5WhNz8dn2PCU1l66flCALSXjWnyRL8EUCgYEAwYJs
r8eeEIX0CzNXSVLswMYYPcpUCqbSe8vcMzVrlAa2lZpothVvHp5T8GJbbGZXUHLQ
DB5O6gqVrz7lqTbTnFTLuXud4deL7xAHYOtu2TRmGRrWYDKAnG62Mafv4qfQBR4n
JjAlSLI01E6Ld4d408xRPe1bLd1Ms50PUY2FLVsCgYAA799bnPT3vley2EhwD0oT
uZBwI4QYC8r9k29z+XAUjWEeC1YkGI0r0JWh7NCeDPCshKtLhE44ZaeB4y7+gkjo
fPughiyewZlC2fesrg9XsT5qmedXTl9V/rtReHfAEYLdNMKJRPF/q8y5IvuINW9g
MIdYadEfvEJPu8CoSG5IQQKBgCu55gdeawg+zKOPSWUHOPpiiO3Ff3IcuilBKpPj
uVhsn+t0Rb8HXuGjU0JZZ2E6SvahywNCAgD+vU4pP0oaWnzT6GkUVtvGkhdGHvS2
noi0P3Hiz5hTMR6oIcFcumcUFnxhkOUfMf2YTzm+OeObmCD75UvCC710aTWZAvIh
sXtLAoGAXiDIzam9og6bhxQusz/b/8Mg1nqDfNcZEPhEAqIWqNYgewS2gSfBmyqc
5YyRoQf7QpMwYsn0CCA+gFw+WA2KVXl8GZ0WW6d4kjEs5rKZjBatCB0qaUIf0BgC
zQFeynZ3aQXNU2Yv9hpAWBlUbNTHP4FfujG7VIPR+RPNkxIl1WI=
-----END RSA PRIVATE KEY-----
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
记录对应的公钥
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqfRjYpxciFvTIudsEKQdFdqglGFHvfBS00CvzZ96CqewwTOuWKFsqQpakSYIlUkMupdn66+bhzxJNIpXm2H2C0oCj/08hBuFLscfq/qzHRXGGCrDNWhTB9q0D4eQNZlix7MEwRK1vpFmZzw/9i+kWyuqUehsuO/oOVUtuKs1H00ny4HNKIjjjSEhf7E46ovXMB0HfdV6CmgNcJY16h74vop3PkgG3R7w/1jedJe+E8tH9/N4e0EYI3xUg
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqfRjYpxciFvTIudsEKQ
dFdqglGFHvfBS00CvzZ96CqewwTOuWKFsqQpakSYIlUkMupdn66+bhzxJNIpXm2H
2C0oCj/08hBuFLscfq/qzHRXGGCrDNWhTB9q0D4eQNZlix7MEwRK1vpFmZzw/9i+
kWyuqUehsuO/oOVUtuKs1H00ny4HNKIjjjSEhf7E46ovXMB0HfdV6CmgNcJY16h7
4vop3PkgG3R7w/1jedJe+E8tH9/N4e0EYI3xUgzmkWKDFKCnGeW9JFVIBPTYJewt
aRxQfZ8c6k3YzwcsjFcR9Wv/g7AgKskHEXLqhFoYprrPecjO/vJ/lnQLxgOSFROJ
hwIDAQAB
-----END PUBLIC KEY-----
依赖的base64编解码文件
如果不转DER格式的话 不需要该文件的~ base64.h
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_WIN32)
# define __export __declspec(dllexport)
#elif defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
# define __export __attribute__((visibility("default")))
#else
# define __export
#endif
__export int getEncodeLen ( int MaxLen, unsigned char * pbOutData) ;
__export int getDecodeLen ( unsigned char * pbOutData) ;
__export unsigned char * base64_encode ( int MaxLen, unsigned char * str) ;
__export unsigned char * base64_decode ( unsigned char * code) ;
#ifdef __cplusplus
}
#endif
#include "base64.h"
#include <stdlib.h>
#include <string.h>
int getEncodeLen ( int MaxLen, unsigned char * pbOutData)
{
if ( pbOutData == NULL )
return - 1 ;
int puLen;
for ( puLen = 0 ; puLen < MaxLen; puLen++ ) {
if ( pbOutData[ puLen] == '\0' ) {
int i = puLen;
while ( pbOutData[ i] == '\0' ) {
if ( i == MaxLen)
break ;
i++ ;
}
if ( i == MaxLen) {
break ;
}
}
}
return puLen;
}
unsigned char * base64_encode ( int MaxLen, unsigned char * str)
{
long len;
long str_len;
unsigned char * res;
int i, j;
unsigned char * base64_table = ( unsigned char * ) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
str_len = getEncodeLen ( MaxLen, str) ;
if ( str_len % 3 == 0 )
len = str_len / 3 * 4 ;
else
len = ( str_len / 3 + 1 ) * 4 ;
res = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * len + 1 ) ;
res[ len] = '\0' ;
for ( i = 0 , j = 0 ; i< len - 2 ; j + = 3 , i + = 4 )
{
res[ i] = base64_table[ str[ j] >> 2 ] ;
res[ i + 1 ] = base64_table[ ( str[ j] & 0x3 ) << 4 | ( str[ j + 1 ] >> 4 ) ] ;
res[ i + 2 ] = base64_table[ ( str[ j + 1 ] & 0xf ) << 2 | ( str[ j + 2 ] >> 6 ) ] ;
res[ i + 3 ] = base64_table[ str[ j + 2 ] & 0x3f ] ;
}
switch ( str_len % 3 )
{
case 1 :
res[ i - 2 ] = '=' ;
res[ i - 1 ] = '=' ;
break ;
case 2 :
res[ i - 1 ] = '=' ;
break ;
}
return res;
}
int getDecodeLen ( unsigned char * code)
{
long str_len;
long len = strlen ( ( char * ) code) ;
if ( strstr ( ( char * ) code, "==" ) )
str_len = len / 4 * 3 - 2 ;
else if ( strstr ( ( char * ) code, "=" ) )
str_len = len / 4 * 3 - 1 ;
else
str_len = len / 4 * 3 ;
return str_len;
}
unsigned char * base64_decode ( unsigned char * code)
{
int table[ ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 0 , 0 , 0 , 0 , 0 , 0 , 62 , 0 , 0 , 0 ,
63 , 52 , 53 , 54 , 55 , 56 , 57 , 58 ,
59 , 60 , 61 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 ,
13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 ,
22 , 23 , 24 , 25 , 0 , 0 , 0 , 0 , 0 , 0 , 26 ,
27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 ,
36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 ,
45 , 46 , 47 , 48 , 49 , 50 , 51
} ;
long len;
long str_len;
unsigned char * res;
int i, j;
len = strlen ( ( char * ) code) ;
if ( strstr ( ( char * ) code, "==" ) )
str_len = len / 4 * 3 - 2 ;
else if ( strstr ( ( char * ) code, "=" ) )
str_len = len / 4 * 3 - 1 ;
else
str_len = len / 4 * 3 ;
res = ( unsigned char * ) malloc ( sizeof ( unsigned char ) * str_len + 1 ) ;
res[ str_len] = '\0' ;
for ( i = 0 , j = 0 ; i < len - 2 ; j + = 3 , i + = 4 )
{
res[ j] = ( ( unsigned char ) table[ code[ i] ] ) << 2 | ( ( ( unsigned char ) table[ code[ i + 1 ] ] ) >> 4 ) ;
res[ j + 1 ] = ( ( ( unsigned char ) table[ code[ i + 1 ] ] ) << 4 ) | ( ( ( unsigned char ) table[ code[ i + 2 ] ] ) >> 2 ) ;
res[ j + 2 ] = ( ( ( unsigned char ) table[ code[ i + 2 ] ] ) << 6 ) | ( ( unsigned char ) table[ code[ i + 3 ] ] ) ;
}
return res;
}