openssl之C++实现私(公)钥生成、转换

openssl

私钥生成

  • 生成密钥对
    • RSA_generate_key
#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;
	//产生RSA密钥对
	pRSA = RSA_generate_key(bits, E, NULL, NULL);
	pEVPKey = EVP_PKEY_new();
	//将RSA对象赋给EVP_PKEY对象
	EVP_PKEY_assign_RSA(pEVPKey, pRSA);
	//可将pRSA 转换为私钥 无密码 DER编码格式或者PEM格式
	 toFormatPri(pRSA, priKey);
	//可将pEVPKey转换为私钥 带密码 DER编码格式或者PEM格式
	toFormatPriPwd(pEVPKey , priKey,priPwd);
	
	/*生成文件 PEM/DER编码 无密码 私钥*/
	toFormatPriFile(pRSA);
	/*生成文件 PEM/DER编码 带密码 私钥*/
	toFormatPriPwdFile(pEVPKey,priPwd);
}

私钥转换:包括是否带密码,生成文件,DER/PEM格式

  • 私钥转换为带密码保护的DER格式
    • i2d_PKCS8PrivateKey_bio
    • 解密待测试
int toFormatPriPwd(EVP_PKEY *pEVPKey, char * base64, char *pwd)
{
	/*带密码 字符串 DER编码 私钥*/
	int             iRV,nLen, baseLen = 0;
	BUF_MEM         *pBMem = NULL;
	BIO             *pBIO = NULL;
	pem_password_cb *passphrase;

	pBIO = BIO_new(BIO_s_mem());
	//encrypt the the private key with the passphrase and put it in the BIO in DER format 
	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)
{
	/*带密码 字符串 PEM编码 私钥*/
	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)
{
	/* DER编码 pri*/
	int             nLen, baseLen = 0;
	unsigned char   *pDer = NULL;
	unsigned char   *p = NULL;

	//将RSA对象转换为私钥 私钥分为带密码保护和无密码的 使用不同函数
	/*无密码 字符串 DER编码 私钥*/
	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)
{
	/*无密码 字符串 PEM编码 私钥*/
	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;

	/* PEM编码 私钥文件*/
	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;
}

  • 私钥转换为带密码保护的DER格式文件
    • i2d_PKCS8PrivateKey_bio
int toFormatPriPwdFile(EVP_PKEY *pEVPKey,char *pfxPwd)
{
	BIO             *pBIO = NULL;
	int             iRV = 0, nLen = 0;
	/* DER编码 带密码 私钥文件*/
	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);// 功能与i2d_PKCS8PrivateKey_bio_fp相同
	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;

	/* PEM编码 无密码 私钥文件*/
	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;

	/* DER编码 无密码 私钥文件*/
	pBIO = BIO_new_file("priKey.der", "w");
	if (!pBIO)
	{
		ZF_LOGE("priKey.der pBIO error");
		goto free_all;
	}

	iRV = i2d_RSAPrivateKey_bio(pBIO, pRSA);// 功能与i2d_RSAPrivateKey_bio_fp相同
	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-----

  • 不带密码的DER格式的私钥
MIIEogIBAAKCAQEAqqfRjYpxciFvTIudsEKQdFdqglGFHvfBS00CvzZ96CqewwTOuWKFsqQpakSYIlUkMupdn66+bhzxJNIpXm2H2C0oCj/08hBuFLscfq/qzHRXGGCrDNWhTB9q0D4eQNZlix7MEwRK1vpFmZzw/9i+kWyuqUehsuO/oOVUtuKs1H00ny4HNKIjjjSEhf7E46ovXMB0HfdV6CmgNcJY16h74vop3PkgG3R7w/1jedJe+E8tH9/N4e0EYI3xUgzmkWKDFKCnGeW9JFVIBPTYJewtaRxQfZ8c6k3YzwcsjFcR9Wv/g7AgKskHEXLqhFoYprrPecjO/vJ/lnQLxgOSFROJhwIDAQABAoIBAFvHcW273RNSY/c4xw+6XNIVCVUY3o0vFaeXvTh05/XqpgOgHEWbdOgEXbmnNmKQg61WWg+8/PFfY1k4JcOBCKP8dSI+D0/4AhvoHYUMuyxGDWkw5A08/0hfRSTFo6OfKnFNmNdJYa6IXtIkk4AlYyf22WB1A8OftLmlXJAXDHgiFKMvV7LWi55huRZcAedjYF/e2Qq0bVXwZs/vneJohFdeJ3HAg8Do583L7wMuI8Jn6j2hqzUgUobrUaz4R0dF3uUyeZz2lvrHAVOTrUFovwo+mraL06Vkm3nIran0xvRjVRSvKEbKfve0ozGer9CG0nVHdgYB0tf7PPL+nIMzf7ECgYEA4cQKz1rmTmji//uPYaAg9F5FXhMK4cafZ+4lF206V/ZG/KmWDdQEHAFctwJklEoX9fhLeBg5IcOsvsSYLmFVbvTQeip9HHD1ISgGQaHnS9iSrXpMbsoEHEyHuETp6plZJUsNNDdPoxq5WhNz8dn2PCU1l66flCALSXjWnyRL8EUCgYEAwYJsr8eeEIX0CzNXSVLswMYYPcpUCqbSe8vcMzVrlAa2lZpothVvHp5T8GJbbGZXUHLQDB5O6gqVrz7lqTbTnFTLuXud4deL7xAHYOtu2TRmGRrWYDKAnG62Mafv4qfQBR4nJjAlSLI01E6Ld4d408xRPe1bLd1Ms50PUY2FLVsCgYAA799bnPT3vley2EhwD0oTuZBwI4QYC8r9k29z+XAUjWEeC1YkGI0r0JWh7NCeDPCshKtLhE44ZaeB4y7+gkjofPughiyewZlC2fesrg9XsT5qmedXTl9V/rtReH
  • 带密码的DER格式的私钥
MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIuMXG9fmNxPoCAggAMAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECJ5wXBjIs79TBIIEyGtzYPi4uxAtKLUBRtYe1j4OUz6MHuxsDucJjZhI1Y384A5GeXzCHlUE5WIi1EVsUgur8mNJEnmw2Yo0dgA7cBj2M3WoO0owD5ui15fz41ktyDT/TN7yRbmyqW1wrfeyPAMrSKgTaL+3ismXp4IqlZ88aYhwTHG7HQhLVVNWwqs0njQ87zNYayMzsK1zcmT+K4hKudOYRHWMo/pGhOjS8g+5KOEQAEdk68zNcLGYsu3laQCDFv8iEojmTjf0Jh9Xpw/lEXTpmE9FM7XqcBsNBvSad9JzME8JbektHz2Ko8MBJYvqtn6J5SsolI5eA2TBDI2nEhqBmUjegBrTmI88SVu7l+aCOVvkvhBrO79RLE7UqmyGaw85G4kj3rzKu0VkUtX57q5BSN7GSlZn02gcA+IMc6mMpx90R712mZZipDThE5bIbRZsFw2dDzwjkxyO954IniN9qNuWA99RusCo/fmEDH09tQblP5WK0L+vY19ti+fnnFW2D5PcpOVit5WzpoAXDa4yFY+m7SWhFyr46oAjbmdW7Wi9LmviVrSvyXEU4PsDpl2+hrpFR+Ql+uszBfR4uXs3RF9NvqxxlsB4wT9Phlt13HGI8o2CaU94Hz85QLA4ZCrMdVXDkes3tAZSDsms7c0JjKp4VqbLTQDIuTLrADpIJmr4cYpoHlSqixZPSfc9DjtcMOyvBRDMcFe+BtCOt9PYb4fO9ZSt3ZlCeOdRIk2NQ2Gn7fomgMV1NJunLTgG3oI1YyWndbB4kvKYr4vFOXtnQBHltwop/DjfNPq3dHBow2gDX1XbmZMa45w7l3xzBEl761dalEssPXz31N1rrdidvqFjLtf75RFVaZNMUP88v32inZwpa0VvVFcp9IYfbA+gVaXTWFVmNoW6tHHrU9syoMWcCcyxGSRO0VZPBlAV7GQej4lY7lZgR6AbIVnwV47lnKyoS33nsCEawFijAXh3JKRiqMc0Ym/MTECJldxDV+jvu1MNmQLZ0dtPZwcI34KI18fg9G3ojcAdA4L3ssF88jwWebX/2NZtV9PuZ9GkskMRVDUSvHgC/53VxfN6idhIF/RmGuDdKmNFD87DDI6T1bGPvjqKt28HrdPOxi/KgScRZxVbc2i9Fj2DBYEzgwGTkQGaUD38UQ51yJJ/LAYJXEfKLU4nI1jtRYz6dgnwT4YyTwtLWJNDBnH

记录对应的公钥

  • PEM格式的公钥
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqqfRjYpxciFvTIudsEKQdFdqglGFHvfBS00CvzZ96CqewwTOuWKFsqQpakSYIlUkMupdn66+bhzxJNIpXm2H2C0oCj/08hBuFLscfq/qzHRXGGCrDNWhTB9q0D4eQNZlix7MEwRK1vpFmZzw/9i+kWyuqUehsuO/oOVUtuKs1H00ny4HNKIjjjSEhf7E46ovXMB0HfdV6CmgNcJY16h74vop3PkgG3R7w/1jedJe+E8tH9/N4e0EYI3xUg
  • DER格式的公钥
-----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
  • base64.cpp
#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;//检查后面是不是都是'\0'
			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;
	//定义base64编码表  
	unsigned char *base64_table = (unsigned char *) "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

	//计算经过base64编码后的字符串长度  
	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';

	//以3个8位字符为一组进行编码  
	for (i = 0, j = 0; i<len - 2; j += 3, i += 4)
	{
		res[i] = base64_table[str[j] >> 2]; //取出第一个字符的前6位并找出对应的结果字符  
		res[i + 1] = base64_table[(str[j] & 0x3) << 4 | (str[j + 1] >> 4)]; //将第一个字符的后位与第二个字符的前4位进行组合并找到对应的结果字符  
		res[i + 2] = base64_table[(str[j + 1] & 0xf) << 2 | (str[j + 2] >> 6)]; //将第二个字符的后4位与第三个字符的前2位组合并找出对应的结果字符  
		res[i + 3] = base64_table[str[j + 2] & 0x3f]; //取出第三个字符的后6位并找出结果字符  
	}

	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)
{
	//根据base64表,以字符找到对应的十进制数据  
	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';

	//以4个字符为一位进行解码  
	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); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合  
		res[j + 1] = (((unsigned char)table[code[i + 1]]) << 4) | (((unsigned char)table[code[i + 2]]) >> 2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合  
		res[j + 2] = (((unsigned char)table[code[i + 2]]) << 6) | ((unsigned char)table[code[i + 3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合  
	}

	return res;

}

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在QT C++中使用OpenSSL生成jwk,可以参考以下步骤: 1. 首先,需要安装OpenSSL库。可以在官网上下载对应的安装包进行安装。 2. 在QT C++项目中添加OpenSSL库的头文件和库文件。在.pro文件中添加以下代码: ``` INCLUDEPATH += /usr/local/ssl/include LIBS += -L/usr/local/ssl/lib -lssl -lcrypto ``` 3. 编写生成jwk的代码。可以参考以下代码: ``` #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> #include <openssl/bio.h> #include <openssl/err.h> #include <QJsonObject> QJsonObject generateJWK(int keySize) { QJsonObject jwk; // 生成RSARSA* rsa = RSA_generate_key(keySize, RSA_F4, NULL, NULL); // 将RSA转换为PEM格式 BIO* bio = BIO_new(BIO_s_mem()); PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL); size_t privateKeyLen = BIO_pending(bio); char* privateKey = new char[privateKeyLen + 1]; BIO_read(bio, privateKey, privateKeyLen); privateKey[privateKeyLen] = '\0'; BIO* pubkeyBio = BIO_new(BIO_s_mem()); PEM_write_bio_RSA_PUBKEY(pubkeyBio, rsa); size_t publicKeyLen = BIO_pending(pubkeyBio); char* publicKey = new char[publicKeyLen + 1]; BIO_read(pubkeyBio, publicKey, publicKeyLen); publicKey[publicKeyLen] = '\0'; jwk.insert("kty", "RSA"); jwk.insert("n", QByteArray(reinterpret_cast<const char*>(rsa->n->data), rsa->n->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("e", QByteArray(reinterpret_cast<const char*>(rsa->e->data), rsa->e->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("d", QByteArray(reinterpret_cast<const char*>(rsa->d->data), rsa->d->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("p", QByteArray(reinterpret_cast<const char*>(rsa->p->data), rsa->p->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("q", QByteArray(reinterpret_cast<const char*>(rsa->q->data), rsa->q->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("dp", QByteArray(reinterpret_cast<const char*>(rsa->dmp1->data), rsa->dmp1->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("dq", QByteArray(reinterpret_cast<const char*>(rsa->dmq1->data), rsa->dmq1->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("qi", QByteArray(reinterpret_cast<const char*>(rsa->iqmp->data), rsa->iqmp->length).toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals)); jwk.insert("privateKey", privateKey); jwk.insert("publicKey", publicKey); // 释放RSA对和BIO RSA_free(rsa); BIO_free_all(bio); BIO_free_all(pubkeyBio); return jwk; } ``` 4. 调用生成jwk的函数,并将生成的jwk保存到文件中: ``` QJsonObject jwk = generateJWK(2048); QFile file("jwk.json"); if (file.open(QIODevice::WriteOnly)) { QJsonDocument doc(jwk); QByteArray data = doc.toJson(QJsonDocument::Indented); file.write(data); file.close(); } ``` 以上就是使用OpenSSL在QT C++生成jwk的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值