SM2算法第十五篇:ECDSA数字签名算法的C语言实现

代码

#include <string.h>

#include <stdio.h>

#include <openssl/ec.h>

#include <openssl/ssl.h>

#include <openssl/ecdsa.h>

#include <openssl/objects.h>

#include <openssl/err.h>

 

int    main()

{

       EC_KEY              *key1,*key2;

       EC_POINT            *pubkey1,*pubkey2;

       EC_GROUP            *group1,*group2;

       int                 ret,nid,size,i,sig_len;

       unsigned char*      signature,digest[20];

       BIO                 *berr;

       EC_builtin_curve    *curves;

       int                 crv_len;

       char                shareKey1[128],shareKey2[128];

       int                 len1,len2;

 

       /* 构造EC_KEY数据结构 */

       key1=EC_KEY_new();

       if(key1==NULL)

       {

              printf("EC_KEY_new err!\n");

              return -1;

       }

       key2=EC_KEY_new();

       if(key2==NULL)

       {

     
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
SM2算法是一种椭圆曲线公钥密码算法,其实现需要使用椭圆曲线运算库。以下是一个简单的示例代码,假设使用了OpenSSL库: ```c #include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/err.h> #include <openssl/rand.h> int sm2_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *ciphertext, int *ciphertext_len, EC_KEY *ec_key) { int ret = 0; EC_GROUP *group = NULL; EC_POINT *pub_key = NULL; unsigned char *tmp_ciphertext = NULL; int tmp_ciphertext_len; EVP_CIPHER_CTX *ctx = NULL; group = EC_KEY_get0_group(ec_key); pub_key = EC_KEY_get0_public_key(ec_key); /* 生成临时公钥 */ EC_POINT *tmp_pub_key = EC_POINT_new(group); if (!tmp_pub_key) { ret = -1; goto cleanup; } if (!EC_POINT_copy(tmp_pub_key, pub_key)) { ret = -1; goto cleanup; } if (!EC_KEY_generate_key(ec_key)) { ret = -1; goto cleanup; } /* 加密 */ ctx = EVP_CIPHER_CTX_new(); if (!ctx) { ret = -1; goto cleanup; } if (!EVP_EncryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL)) { ret = -1; goto cleanup; } if (!EVP_EncryptUpdate(ctx, ciphertext, ciphertext_len, plaintext, plaintext_len)) { ret = -1; goto cleanup; } if (!EVP_EncryptFinal_ex(ctx, ciphertext + *ciphertext_len, &tmp_ciphertext_len)) { ret = -1; goto cleanup; } *ciphertext_len += tmp_ciphertext_len; /* 生成密文 */ tmp_ciphertext = (unsigned char *)OPENSSL_malloc(*ciphertext_len + 65); if (!tmp_ciphertext) { ret = -1; goto cleanup; } memcpy(tmp_ciphertext, ciphertext, *ciphertext_len); if (!EC_POINT_point2oct(group, tmp_pub_key, POINT_CONVERSION_UNCOMPRESSED, tmp_ciphertext + *ciphertext_len, 65, NULL)) { ret = -1; goto cleanup; } *ciphertext_len += 65; memcpy(ciphertext, tmp_ciphertext, *ciphertext_len); cleanup: if (tmp_pub_key) EC_POINT_free(tmp_pub_key); if (ctx) EVP_CIPHER_CTX_free(ctx); if (tmp_ciphertext) OPENSSL_free(tmp_ciphertext); return ret; } int sm2_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *plaintext, int *plaintext_len, EC_KEY *ec_key) { int ret = 0; EC_GROUP *group = NULL; EC_POINT *pub_key = NULL; EC_POINT *tmp_pub_key = NULL; unsigned char *tmp_ciphertext = NULL; int tmp_ciphertext_len; EVP_CIPHER_CTX *ctx = NULL; group = EC_KEY_get0_group(ec_key); pub_key = EC_KEY_get0_public_key(ec_key); /* 解密 */ ctx = EVP_CIPHER_CTX_new(); if (!ctx) { ret = -1; goto cleanup; } if (!EVP_DecryptInit_ex(ctx, EVP_sm4_ecb(), NULL, NULL, NULL)) { ret = -1; goto cleanup; } if (!EVP_DecryptUpdate(ctx, plaintext, plaintext_len, ciphertext, ciphertext_len - 65)) { ret = -1; goto cleanup; } if (!EVP_DecryptFinal_ex(ctx, plaintext + *plaintext_len, &tmp_ciphertext_len)) { ret = -1; goto cleanup; } *plaintext_len += tmp_ciphertext_len; /* 生成临时公钥 */ tmp_pub_key = EC_POINT_new(group); if (!tmp_pub_key) { ret = -1; goto cleanup; } if (!EC_POINT_oct2point(group, tmp_pub_key, ciphertext + ciphertext_len - 65, 65, NULL)) { ret = -1; goto cleanup; } /* 验证公钥是否正确 */ if (!EC_POINT_cmp(group, pub_key, tmp_pub_key, NULL)) { ret = -1; goto cleanup; } cleanup: if (tmp_pub_key) EC_POINT_free(tmp_pub_key); if (ctx) EVP_CIPHER_CTX_free(ctx); if (tmp_ciphertext) OPENSSL_free(tmp_ciphertext); return ret; } ``` 需要注意的是,SM2算法中使用的椭圆曲线参数需要从安全可信的源获取,并且在实现过程中需要注意安全性和性能。以上代码仅供参考,实际应用时应进行充分的测试和评估。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值