Created SM2公钥加密 (markdown)

Zhi Guan
2015-11-04 13:48:23 +08:00
parent a9e5aabd6c
commit eb9df6839f

66
SM2公钥加密.md Normal file

@@ -0,0 +1,66 @@
SM2公钥加密算法国密公钥加密标准之一由国家密码管理局与2010年12月公布。SM2公钥加密是一种椭圆曲线公钥加密方案具体规范可参考《SM2椭圆曲线公钥密码算法 第4部分公钥加密算法》文本。
SM2公钥加密适用于加密长度较短的数据如会话密钥和消息报文。SM2公钥加密不仅对数据加密还提供防篡改的特性即被篡改的或伪造的密文可以在解密的过程中被检查发现因此通过SM2公钥加密的消息无需格外的校验机制。消息经过SM2公钥加密后长度会增加不到100字节的长度加密方在准备缓冲区时需要加以留意。
GmSSL提供了SM2公钥加密的实现。应用应优先通过EVP API调用SM2公钥加密的功能具体接口使用方法请参考手册页中的`EVP_PKEY_encrypt(3)``EVP_PKEY_decrypt(3)`等相关函数。
下面给出通过EVP API调用SM2公钥加密的例子
``` c
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
int main(int argc, char **argv)
{
EC_KEY *ec_key = NULL;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
char *msg = "Hello world!";
unsigned char ptbuf[256];
unsigned char ctbuf[256];
size_t ptlen, ctlen, i;
/* 生成 SM2 EVP_PKEY 对象 */
ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1);
pkey = EVP_PKEY_new();
EC_KEY_generate_key(ec_key);
EVP_PKEY_set1_SM2(pkey, ec_key);
ctx = EVP_PKEY_CTX_new(pkey, NULL);
/* 加密 */
EVP_PKEY_encrypt_init(ctx);
ctlen = sizeof(ctbuf);
bzero(ctbuf, ctlen);
EVP_PKEY_encrypt(ctx, ctbuf, &ctlen, (unsigned char *)msg, strlen(msg) + 1);
printf("encrypted message (%zu bytes) : ", ctlen);
for (i = 0; i < ctlen; i++) {
printf("%02x", ctbuf[i]);
}
printf("\n");
/* 解密 */
EVP_PKEY_decrypt_init(ctx);
ptlen = sizeof(ptbuf);
bzero(ptbuf, ptlen);
if (!EVP_PKEY_decrypt(ctx, ptbuf, &ptlen, ctbuf, ctlen)) {
fprintf(stderr, "sm2 decrypt failed.\n");
}
printf("decrypted message : %s\n", ptbuf);
EVP_PKEY_free(pkey);
EC_KEY_free(ec_key);
EVP_PKEY_CTX_free(ctx);
return 0;
}
```