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

原创 2016年05月19日 18:12:38

代码

#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)

       {

              printf("EC_KEY_new err!\n");

              return -1;

       }

       /* 获取实现的椭圆曲线个数 */

       crv_len = EC_get_builtin_curves(NULL, 0);

       curves = (EC_builtin_curve *)malloc(sizeof(EC_builtin_curve) * crv_len);

       /* 获取椭圆曲线列表 */

       EC_get_builtin_curves(curves, crv_len);

       /* 

       nid=curves[0].nid;会有错误,原因是密钥太短

       */

       /* 选取一种椭圆曲线 */

       nid=curves[25].nid;

       /* 根据选择的椭圆曲线生成密钥参数group */

       group1=EC_GROUP_new_by_curve_name(nid);

       if(group1==NULL)

       {

              printf("EC_GROUP_new_by_curve_name err!\n");

              return -1;

       }

       group2=EC_GROUP_new_by_curve_name(nid);

       if(group1==NULL)

       {

              printf("EC_GROUP_new_by_curve_name err!\n");

              return -1;

       }

       /* 设置密钥参数 */

       ret=EC_KEY_set_group(key1,group1);

       if(ret!=1)

       {

              printf("EC_KEY_set_group err.\n");

              return -1;

       }

       ret=EC_KEY_set_group(key2,group2);

       if(ret!=1)

       {

              printf("EC_KEY_set_group err.\n");

              return -1;

       }

       /* 生成密钥 */

       ret=EC_KEY_generate_key(key1);

       if(ret!=1)

       {

              printf("EC_KEY_generate_key err.\n");

              return -1;

       }

       ret=EC_KEY_generate_key(key2);

       if(ret!=1)

       {

              printf("EC_KEY_generate_key err.\n");

              return -1;

       }

       /* 检查密钥 */

       ret=EC_KEY_check_key(key1);

       if(ret!=1)

       {

              printf("check key err.\n");

              return -1;

       }

       /* 获取密钥大小 */

       size=ECDSA_size(key1);

       printf("size %d \n",size);

       for(i=0;i<20;i++)

              memset(&digest[i],i+1,1);

       signature=(unsigned char *)malloc(size);

       ERR_load_crypto_strings();

       berr=BIO_new(BIO_s_file());

       BIO_set_fp(berr,stdout,BIO_NOCLOSE);

       /* 签名数据,本例未做摘要,可将digest中的数据看作是sha1摘要结果 */

       ret=ECDSA_sign(0,digest,20,signature,(unsigned int *)&sig_len,key1);

       if(ret!=1)

       {

              ERR_print_errors(berr);

              printf("sign err!\n");

              return -1;

       }

       /* 验证签名 */

       ret=ECDSA_verify(0,digest,20,signature,sig_len,key1);

       if(ret!=1)

       {

              ERR_print_errors(berr);

              printf("ECDSA_verify err!\n");

              return -1;

       }

       /* 获取对方公钥,不能直接引用 */

       pubkey2 = (struct ec_point_st *)EC_KEY_get0_public_key(key2);

       /* 生成一方的共享密钥 */

       len1=ECDH_compute_key(shareKey1, 128, pubkey2, key1, NULL);

       pubkey1 = (struct ec_point_st *)EC_KEY_get0_public_key(key1);

       /* 生成另一方共享密钥 */

       len2=ECDH_compute_key(shareKey2, 128, pubkey1, key2, NULL);

       if(len1!=len2)

       {

              printf("err\n");

       }

       else

       {

              ret=memcmp(shareKey1,shareKey2,len1);

              if(ret==0)

                     printf("生成共享密钥成功\n");

              else

                     printf("生成共享密钥失败\n");

       }

       printf("test ok!\n");

       BIO_free(berr);

       EC_KEY_free(key1);

       EC_KEY_free(key2);

       free(signature);

       free(curves);

       return 0;

}


运行结果



版权声明:本文为博主原创文章,未经博主允许不得转载。

SM2算法第二十五篇:ECDSA数字签名算法原理与实现

这边博客中有关 EC_KEY_set_private_key和EC_KEY_set_public_key函数 EC_POINT_mul 对于理解SM2有很大帮助...
  • qq_30866297
  • qq_30866297
  • 2016年05月21日 02:49
  • 3028

SM2算法第十三篇:SM2密钥协商协议的C语言实现

记录每一点小小的进展,今天终于把”SM2的C语言实现”的程序成功的运行起来了,下面记录了我的操作流程。...
  • qq_30866297
  • qq_30866297
  • 2016年05月18日 12:47
  • 2599

SM2算法第二十五篇:ECDSA数字签名算法原理与实现

这边博客中有关 EC_KEY_set_private_key和EC_KEY_set_public_key函数 EC_POINT_mul 对于理解SM2有很大帮助...
  • qq_30866297
  • qq_30866297
  • 2016年05月21日 02:49
  • 3028

C语言实现的SM2数字签名验证

在 goldboar 写的 SM2 签名及验签函数( http://download.csdn.net/detail/goldboar/3833072)基础上,改写了一个纯粹用于验证SM2签名的函数。...
  • henter
  • henter
  • 2014年07月15日 15:31
  • 2725

ECDSA数字签名算法及JAVA实现

ECDSA数字签名算法          ECDSA椭圆曲线数字签名算法是针对素数域和伽罗瓦域上的椭圆曲线定义的,在实际中前者更为常用,以下是针对素数域的说明:          1.使用椭圆曲线E其...
  • qq_35612816
  • qq_35612816
  • 2017年12月26日 16:58
  • 59

PBOC3.0 SM2 算法各种证书、数字签名的验证

1、关于SM2     SM2算法是一种非对称算法,与国际算法里中的RSA相对应。     SM2推荐的曲线参数如下:          在验证PBOC卡片中的发卡行公钥证书、IC卡公钥证书、签名的静...
  • wenyangwangw
  • wenyangwangw
  • 2015年12月15日 21:44
  • 3124

椭圆曲线数字签名算法(ECDSA)中文版

  • 2011年11月02日 12:24
  • 199KB
  • 下载

ecdsa 椭圆曲线数字签名算法

来源:http://www.cryptopp.com/wiki/Elliptic_Curve_Digital_Signature_Algorithm Elliptic Curve Digital ...
  • sprawling
  • sprawling
  • 2015年03月27日 15:52
  • 1554

【比特币】椭圆曲线数字签名算法-ECDSA

比特币目前使用ECDSA对货币的所有权
  • wuzh1230
  • wuzh1230
  • 2014年07月17日 10:44
  • 6947

数字签名加密算法(RSA、DSA、ECDSA)

RSA的例子:import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGe...
  • sx5273
  • sx5273
  • 2016年01月17日 17:24
  • 1422
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SM2算法第十五篇:ECDSA数字签名算法的C语言实现
举报原因:
原因补充:

(最多只允许输入30个字)