mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-16 05:16:26 +08:00
Destroyed SM2公钥加密 (markdown)
75
SM2公钥加密.md
75
SM2公钥加密.md
@@ -1,75 +0,0 @@
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
## 密文编码问题
|
||||
|
||||
SM2密文由C1、C2、C3三部分构成,如何对SM2密文进行编码在已经公布的两个标准中有所不同,在早期公布的《SM2椭圆曲线公钥密码算法 第4部分:公钥加密算法》中,SM2密文中的三部分依次输出,没有采用如Tag-Length-Value形式的编码,我们称其为Plain编码。在之后公布的GM/T国标中,SM2密文采用ASN.1/DER方式编码。
|
||||
|
||||
GmSSL通过`SM2_CIPHERTEXT_VALUE`对象来表示密文数据结构,函数`SM2_do_encrypt()`和`SM2_do_decrypt()`可以生成`SM2_CIPHERTEXT_VALUE`对象及对其解密,函数`SM2_CIPHERTEXT_VALUE_encode()`和`SM2_CIPHERTEXT_VALUE_decode()`实现该对象的Plain编解码。GmSSL预计还会通过函数`i2d_SM2_CIPHERTEXT_VALUE()`和`d2i_SM2_CIPHERTEXT_VALUE()`实现该密文对象的ASN.1/DER编解码,以支持最新的GM/T国密标准。
|
||||
|
||||
GmSSL的`SM2_encrypt()`和`SM2_decrypt()`在加解密的同时也完成`SM2_CIPHERTEXT_VALUE`对象的编解码。目前采用Plain编解码,在相应功能完成后会替换为ASN.1/DER编码方案。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user