GMSSL接口使用总结

RSA相关

生成密钥对(PEM)

生成密钥对(DER)

从密钥对获取RSA*

通过RSA* 加密

BYTE* pbInData; ULONG ulInLen;
BYTE* pbOutData; ULONG* pulOutLen;
ULONG ulPadding;
RSA* key;
/* ---------------------------------------------------------- *
* 计算分组长度                                               *
* ---------------------------------------------------------- */
ULONG cipherLen = RSA_size(key);
ULONG plainLen = 0;
if (ulPadding == RSA_PKCS1_PADDING)
{
	plainLen = RSA_size(key) - 11;
}
else if (ulPadding == RSA_NO_PADDING)
{
	plainLen = RSA_size(key);
}
else if (ulPadding == RSA_PKCS1_OAEP_PADDING)
{
	plainLen = RSA_size(key) - 41;
}

/* ---------------------------------------------------------- *
* 计算分组次数                                               *
* ---------------------------------------------------------- */
int count = (ulInLen % plainLen) ? (ulInLen / plainLen + 1) : (ulInLen / plainLen);		//加密总次数
*pulOutLen = 0;

/* ---------------------------------------------------------- *
* 分组运算	                                                 *
* ---------------------------------------------------------- */
for (int i=0; i< count; i++)
{
	if (i == count - 1)	//最后一次加密
	{
		cipherLen = RSA_public_encrypt((ulInLen - (plainLen *(count-1))), &pbInData[i * plainLen], &pbOutData[*pulOutLen], key, ulPadding);	//前面的分组加密
		printfArray("rsaEncrypt:group:indata:", &pbInData[i * plainLen], (ulInLen - (plainLen * (count - 1))), 2);
		printfArray("rsaEncrypt:group:outdata:base64:", &pbOutData[*pulOutLen], cipherLen, 3);
	}
	else
	{
		cipherLen = RSA_public_encrypt(plainLen, &pbInData[i* plainLen], &pbOutData[*pulOutLen], key, ulPadding);	//前面的分组加密
		printfArray("rsaEncrypt:group:indata:", &pbInData[i * plainLen], plainLen, 2);
		printfArray("rsaEncrypt:group:outdata:base64:", &pbOutData[*pulOutLen], cipherLen, 3);
	}	
	
	if (cipherLen < 0)
	{
		return ENCRYPT_Calculate_FAIL;
	}

	*pulOutLen = *pulOutLen + cipherLen;
}

printfArray("rsaEncrypt:indata:", pbInData, ulInLen, 2);
printfArray("rsaEncrypt:outdata:base64:", pbOutData, *pulOutLen, 3);

通过RSA* 解密

BYTE* pbInData; ULONG ulInLen;
BYTE* pbOutData; ULONG* pulOutLen;
ULONG ulPadding;
RSA* key;
/* ---------------------------------------------------------- *
* 计算分组长度                                               *
* ---------------------------------------------------------- */
ULONG cipherLen = RSA_size(key);
ULONG plainLen = 0;
if ((ulInLen % cipherLen) != 0 )
{
	return ENCRYPT_INDATALENERR;		//解密长度应为密钥长度倍数
}

/* ---------------------------------------------------------- *
* 计算分组次数                                               *
* ---------------------------------------------------------- */
int count = ulInLen / cipherLen;		//解密总次数
*pulOutLen = 0;

/* ---------------------------------------------------------- *
* 分组运算	                                                 *
* ---------------------------------------------------------- */
for (int i = 0; i < count; i++)
{
	plainLen = RSA_private_decrypt(cipherLen, &pbInData[i * cipherLen], &pbOutData[*pulOutLen], key, ulPadding);	//前面的分组加密	
	printfArray("rsaDecrypt:group:indata:base64:", &pbInData[i * cipherLen], cipherLen, 3);
	printfArray("rsaDecrypt:group:outdata:", &pbOutData[*pulOutLen], plainLen, 2);
	if (plainLen < 0)
	{
		return ENCRYPT_Calculate_FAIL;
	}

	*pulOutLen = *pulOutLen + plainLen;
}

printfArray("rsaDecrypt:indata:base64:", pbInData, ulInLen, 3);
printfArray("rsaDecrypt:outdata:", pbOutData, *pulOutLen, 2);

通过RSA* 签名

BYTE* pbInData; ULONG ulInLen;
BYTE* pbOutData; ULONG* pulOutLen;
ULONG ulPadding;
RSA* key;
/* ---------------------------------------------------------- *
* 计算分组长度                                               *
* ---------------------------------------------------------- */
ULONG cipherLen = RSA_size(key);
ULONG plainLen = 0;
if (ulPadding == RSA_PKCS1_PADDING)
{
	plainLen = RSA_size(key) - 11;
}
else if (ulPadding == RSA_NO_PADDING)
{
	plainLen = RSA_size(key);
}
else if (ulPadding == RSA_PKCS1_OAEP_PADDING)
{
	plainLen = RSA_size(key) - 41;
}

/* ---------------------------------------------------------- *
* 计算分组次数                                               *
* ---------------------------------------------------------- */
int count = (ulInLen % plainLen) ? (ulInLen / plainLen + 1) : (ulInLen / plainLen);		//加密总次数
*pulOutLen = 0;

/* ---------------------------------------------------------- *
* 分组运算	                                                 *
* ---------------------------------------------------------- */
for (int i = 0; i < count; i++)
{
	if (i == count - 1)	//最后一次加密
	{
		cipherLen = RSA_private_encrypt((ulInLen - (plainLen * (count - 1))), &pbInData[i * plainLen], &pbOutData[*pulOutLen], key, ulPadding);	//前面的分组加密
		printfArray("rsaEncrypt:group:indata:", &pbInData[i * plainLen], (ulInLen - (plainLen * (count - 1))), 2);
		printfArray("rsaEncrypt:group:outdata:base64:", &pbOutData[*pulOutLen], cipherLen, 3);
	}
	else
	{
		cipherLen = RSA_private_encrypt(plainLen, &pbInData[i * plainLen], &pbOutData[*pulOutLen], key, ulPadding);	//前面的分组加密
		printfArray("rsaEncrypt:group:indata:", &pbInData[i * plainLen], plainLen, 2);
		printfArray("rsaEncrypt:group:outdata:base64:", &pbOutData[*pulOutLen], cipherLen, 3);
	}

	if (cipherLen < 0)
	{
		return ENCRYPT_Calculate_FAIL;
	}

	*pulOutLen = *pulOutLen + cipherLen;
}

printfArray("rsaSignData:indata:", pbInData, ulInLen, 2);
printfArray("rsaSignData:outdata:base64:", pbOutData, *pulOutLen, 3);

通过RSA* 验签

BYTE* pbInData; ULONG ulInLen;
BYTE* pbSignData; ULONG pulSignLen;
ULONG ulPadding;
/* ---------------------------------------------------------- *
* 计算分组长度                                               *
* ---------------------------------------------------------- */
ULONG cipherLen = RSA_size(key);
ULONG plainLen = 0;
if ((ulInLen % cipherLen) != 0)
{
	return ENCRYPT_INDATALENERR;		//解密长度应为密钥长度倍数
}

/* ---------------------------------------------------------- *
* 计算分组次数                                               *
* ---------------------------------------------------------- */
int count = ulInLen / cipherLen;		//解密总次数
BYTE pbOutData[2048] = { 0 };
ULONG pulOutLen = 0;

/* ---------------------------------------------------------- *
* 分组运算	                                                 *
* ---------------------------------------------------------- */
for (int i = 0; i < count; i++)
{
	plainLen = RSA_public_decrypt(cipherLen, &pbInData[i * cipherLen], &pbOutData[pulOutLen], key, ulPadding);	//前面的分组加密
	printfArray("rsaVerify:group:indata:base64:", &pbInData[i * cipherLen], cipherLen, 3);
	printfArray("rsaVerify:group:outdata:", &pbOutData[pulOutLen], plainLen, 2);
	if (plainLen < 0)
	{
		return ENCRYPT_Calculate_FAIL;
	}

	pulOutLen = pulOutLen + plainLen;
}

printfArray("rsaVerify:indata:base64:", pbInData, ulInLen, 3);
printfArray("rsaVerify:outdata:", pbOutData, pulOutLen, 2);

/* ---------------------------------------------------------- *
* 验证签名是否成功                                           *
* ---------------------------------------------------------- */
if ((pulSignLen == pulOutLen) && (0 == memcmp(pbSignData, pbOutData, pulOutLen)) )
{
	printf("rsaVerify:result:true\n");
	return ENCRYPT_OK;
}
else
{
	printf("rsaEncrypt:result:false\n");
	return ENCRYPT_FAIL;
}

解析公私钥

AES相关

通过用户密钥获取加解密密钥

	ULONG ulBits = 256;
	BYTE* pbUserKey; ULONG ulKeyLen;
	BYTE* userkey = (BYTE*)malloc(ulBits / 8);
	memset(userkey, 0, (ulBits / 8));

	if (ulKeyLen < (ulBits / 8))
	{
		memcpy(userkey, pbUserKey, ulKeyLen);
	}
	else
	{
		memcpy(userkey, pbUserKey, (ulBits / 8));
	}
	printfArray("aesEncrypt:userkey:", userkey, (ulBits / 8), 0);

	//获取密钥
	AES_KEY m_aesEncryptkey, m_aesDecryptkey;
	AES_set_encrypt_key(userkey, ulBits, &m_aesEncryptkey);
	AES_set_decrypt_key(userkey, ulBits, &m_aesDecryptkey);

分组加密

BYTE* pbInData; ULONG ulInLen;
BYTE* pbOutData; ULONG* ulOutLen;
AESMode enumAesMode; 
BYTE* pbIv;

//加工待加密数据
int count = (ulInLen % 16) ? (ulInLen / 16 + 1) : (ulInLen / 16);
*ulOutLen = count * AES_BLOCK_SIZE;

BYTE* indata = (BYTE*)malloc(*ulOutLen);
memset(indata, 0, *ulOutLen);
memcpy(indata, pbInData, ulInLen);
printfArray("aesEncrypt:indata:", indata, *ulOutLen, 0);

//进行分组操作
if (enumAesMode == AESMode::ECB)
{
	for (int i = 0; i < count; i++) //每次操作16个字节
	{
		AES_encrypt((indata + i * AES_BLOCK_SIZE), (pbOutData + i * AES_BLOCK_SIZE), &m_aesEncryptkey);
	}
}
else if (enumAesMode == AESMode::CBC)
{
	AES_cbc_encrypt(indata, pbOutData, count * AES_BLOCK_SIZE, &m_aesEncryptkey, pbIv, AES_ENCRYPT);
}
printfArray("aesEncrypt:outdata:", pbOutData, *ulOutLen, 0);

分组解密

BYTE* pbInData; ULONG ulInLen;
BYTE* pbOutData; ULONG* ulOutLen;
AESMode enumAesMode; 
BYTE* pbIv;

//加工待解密数据
int count = (ulInLen % 16) ? (ulInLen / 16 + 1) : (ulInLen / 16);
*ulOutLen = count * AES_BLOCK_SIZE;

BYTE* indata = (BYTE*)malloc(*ulOutLen);
memset(indata, 0, *ulOutLen);
memcpy(indata, pbInData, ulInLen);
printfArray("aesDecrypt:indata:", indata, *ulOutLen, 0);

//进行分组操作
if (enumAesMode == AESMode::ECB)
{
	for (int i = 0; i < count; i++) //每次操作16个字节
	{
		AES_decrypt((indata + i * AES_BLOCK_SIZE), (pbOutData + i * AES_BLOCK_SIZE), &m_aesDecryptkey);
	}
}
else if (enumAesMode == AESMode::CBC)
{
	AES_cbc_encrypt(indata, pbOutData, count * AES_BLOCK_SIZE, &m_aesDecryptkey, pbIv, AES_DECRYPT);
}
printfArray("aesDecrypt:outdata:", pbOutData, *ulOutLen, 0);

## 证书相关

### PEM    ->    X509 *(文件PEM)

```cpp
FILE* fp;
X509* cacert = X509_new();

if (!(fp = fopen("CACERT", "r"))) {
	printf("Error reading CA cert file\n");
	return CERT_FAIL;
}
if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
	printf("Error loading CA cert into memory\n");
	fclose(fp);
	return CERT_FAIL;
}
fclose(fp);

证书相关

PEM -> X509 *(字符串PEM)

std::string CA_Cert =
"-----BEGIN CERTIFICATE-----\n"
"MIICjzCCAfgCCQClyqawadOc6DANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMC\n"
"Q04xDjAMBgNVBAgMBUFuaHVpMQ4wDAYDVQQHDAVIZWZlaTEOMAwGA1UECgwFWmR4\n"
"bHoxFjAUBgNVBAsMDU9wdGljYWxBdHRhY2sxEjAQBgNVBAMMCURldmVsb3BlcjEg\n"
"MB4GCSqGSIb3DQEJARYRZGV2ZWxvcGVyQDE2My5jb20wHhcNMjExMTEyMDgyNzI0\n"
"WhcNMzExMTEwMDgyNzI0WjCBizELMAkGA1UEBhMCQ04xDjAMBgNVBAgMBUFuaHVp\n"
"MQ4wDAYDVQQHDAVIZWZlaTEOMAwGA1UECgwFWmR4bHoxFjAUBgNVBAsMDU9wdGlj\n"
"YWxBdHRhY2sxEjAQBgNVBAMMCURldmVsb3BlcjEgMB4GCSqGSIb3DQEJARYRZGV2\n"
"ZWxvcGVyQDE2My5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL5jMkck\n"
"eXB3mjE21gx7u9LDYpsDD5sPqoTu0jNN+GR6tqz6Q9peIiFYBX21dONw+A0Gint5\n"
"+EXpygI6lMHWwEhnMNRYGCBY6X4zwltF8wGK3lv8wOxIAlzwPnb6EPRTMLCbkKFP\n"
"c7ymICwGMm4XrRxc0zLn6Fi6jhlk7uI1leeLAgMBAAEwDQYJKoZIhvcNAQELBQAD\n"
"gYEARhC72AwPVahu2Co0FHhNS76TuwSTR+hd4MBFTe03Qf7FNLmHnu8zNFUrLm/r\n"
"mAFuNfQzIIpZQYw+51CyDXF5u1akDfbf3p0oPW6Gmnh061ye4FSPKE4QD2jNT7Rn\n"
"hSWu8qHcCGkk2WNqEonCEm5fKlQeLJUuvQ5wfkYJ6pKjwuE=\n"
"-----END CERTIFICATE-----\n";
BIO* biocert = BIO_new(BIO_s_mem());
X509* cacert = X509_new();

biocert = BIO_new_mem_buf(CA_Cert.c_str(), CA_Cert.size());
if (!(cacert = PEM_read_bio_X509(biocert, nullptr, nullptr, nullptr))) {
	printf("Error loading CA cert into memory\n");
	return CERT_FAIL;
}

X509* -> PEM

X509* newcert= X509_new();
BIO* outbio = BIO_new(BIO_s_mem());
BUF_MEM* pBMem = NULL;
BYTE Cert[2048] = {0};
ULONG CertLen = 0;

if (!PEM_write_bio_X509(outbio, newcert)) {
	BIO_printf(outbio, "Error printing the signed certificate\n");
}
BIO_get_mem_ptr(outbio, &pBMem);
CertLen = pBMem->length;
memcpy(Cert, pBMem->data, pBMem->length);

X509* -> DER

X509* newcert= X509_new();
BIO* outbio = BIO_new(BIO_s_mem());
BUF_MEM* pBMem = NULL;
BYTE Cert[2048] = {0};
ULONG CertLen = 0;

if (!i2d_X509_bio(outbio, newcert)) {
	BIO_printf(outbio, "Error printing the signed certificate\n");
}
BIO_get_mem_ptr(outbio, &pBMem);
CertLen = pBMem->length;
memcpy(Cert, pBMem->data, pBMem->length);

X509_Req* 生成

X509* 生成

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值