OpenSSL 签名验签接口调用及测试

概述

项目中我们经常会遇到开发签名、验签功能。签名、验签是可信赖网络的一个重要功能。因此,我记录了OpenSSL 签名验签接口调用及测试。

相关测试代码

base64编码相关的代码

base64.h头文件

#ifndef BASE64_H

#define BASE64_H

#include

#include

#include

#include

#include

#include

int base64_encode( const unsigned char * bindata, int binlength, char * base64);

int base64_decode( const char * base64, unsigned char * bindata );

#endif

base64.c

#include "base64.h"

#ifndef MAX_PATH

#define MAX_PATH 256

#endif

const char * base64char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int base64_encode( const unsigned char * bindata, int binlength, char * base64)

{

int i, j;

unsigned char current;

for ( i = 0, j = 0 ; i < binlength ; i += 3 )

{

current = (bindata[i] >> 2) ;

current &= (unsigned char)0x3F;

base64[j++] = base64char[(int)current];

current = ( (unsigned char)(bindata[i] << 4 ) ) & ( (unsigned char)0x30 ) ;

if ( i + 1 >= binlength )

{

base64[j++] = base64char[(int)current];

base64[j++] = '=';

base64[j++] = '=';

break;

}

current |= ( (unsigned char)(bindata[i+1] >> 4) ) & ( (unsigned char) 0x0F );

base64[j++] = base64char[(int)current];

current = ( (unsigned char)(bindata[i+1] << 2) ) & ( (unsigned char)0x3C ) ;

if ( i + 2 >= binlength )

{

base64[j++] = base64char[(int)current];

base64[j++] = '=';

break;

}

current |= ( (unsigned char)(bindata[i+2] >> 6) ) & ( (unsigned char) 0x03 );

base64[j++] = base64char[(int)current];

current = ( (unsigned char)bindata[i+2] ) & ( (unsigned char)0x3F ) ;

base64[j++] = base64char[(int)current];

}

base64[j] = '\0';

return j;

}

int base64_decode( const char * base64, unsigned char * bindata )

{

int i, j;

unsigned char k;

unsigned char temp[4];

for ( i = 0, j = 0; base64[i] != '\0' ; i += 4 )

{

memset( temp, 0xFF, sizeof(temp) );

for ( k = 0 ; k < 64 ; k ++ )

{

if ( base64char[k] == base64[i] )

temp[0]= k;

}

for ( k = 0 ; k < 64 ; k ++ )

{

if ( base64char[k] == base64[i+1] )

temp[1]= k;

}

for ( k = 0 ; k < 64 ; k ++ )

{

if ( base64char[k] == base64[i+2] )

temp[2]= k;

}

for ( k = 0 ; k < 64 ; k ++ )

{

if ( base64char[k] == base64[i+3] )

temp[3]= k;

}

bindata[j++] = ((unsigned char)(((unsigned char)(temp[0] << 2))&0xFC)) |

((unsigned char)((unsigned char)(temp[1]>>4)&0x03));

if ( base64[i+2] == '=' )

break;

bindata[j++] = ((unsigned char)(((unsigned char)(temp[1] << 4))&0xF0)) |

((unsigned char)((unsigned char)(temp[2]>>2)&0x0F));

if ( base64[i+3] == '=' )

break;

bindata[j++] = ((unsigned char)(((unsigned char)(temp[2] << 6))&0xF0)) |

((unsigned char)(temp[3]&0x3F));

}

return j;

}

签名、验签测试代码

#include

#include

#include

#include

#include

#include

#include

#include

#include "base64.h"

int main ()

{

int err;

int sig_len;

unsigned char sig_buf [4096];

static char keyfile[] = "key.pem";

static char data[] = "3D2F0517-A9A8-49B6-BAEF-89C76934";

EVP_MD_CTX md_ctx;

EVP_PKEY * pkey;

FILE * fp;

X509 *x509;

ERR_load_crypto_strings();

fp = fopen (keyfile, "r");

if (fp == NULL) exit (1);

pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);

fclose (fp);

if (pkey == NULL) {

ERR_print_errors_fp (stderr);

exit (1);

}

/* Do the signature */

EVP_SignInit (&md_ctx, EVP_sha256());

EVP_SignUpdate (&md_ctx, data, strlen(data));

sig_len = sizeof(sig_buf);

err = EVP_SignFinal (&md_ctx, sig_buf, (unsigned int *)&sig_len, pkey);

char base64[4096]={0};

base64_encode( sig_buf, sig_len, base64);

printf("base64 signed %s\n",base64);

//base64_decode( const char * base64, unsigned char * bindata );

if (err != 1) {

ERR_print_errors_fp(stderr);

exit (1);

}

EVP_PKEY_free (pkey);

char pemCert[]="-----BEGIN CERTIFICATE-----\n"

"MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD\n"

"VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv\n"

"bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy\n"

"dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X\n"

"DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw\n"

"EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l\n"

"dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT\n"

"EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp\n"

"MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw\n"

"L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN\n"

"BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX\n"

"9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=\n"

"-----END CERTIFICATE-----";

BIO * b = BIO_new_mem_buf(pemCert, strlen(pemCert));

if (NULL == b){

return -1001;

}

PEM_read_bio_X509(b, &x509, NULL, NULL);

if (NULL == x509){

BIO_free(b), b=NULL;

X509_free(x509), x509=NULL;

return -1002;

}

if (x509 == NULL) {

ERR_print_errors_fp(stderr);

exit(1);

}

printf("halo\n");

/* Get public key - eay */

pkey=X509_get_pubkey(x509);

if (pkey == NULL) {

ERR_print_errors_fp (stderr);

exit (1);

}

/* Verify the signature */

unsigned char aa[4096]={0};

int sin_length = base64_decode(base64,aa );

EVP_VerifyInit (&md_ctx, EVP_sha256());

EVP_VerifyUpdate (&md_ctx, data, strlen((char*)data));

err = EVP_VerifyFinal (&md_ctx, aa, sin_length, pkey);

EVP_PKEY_free (pkey);

if (err != 1) {

ERR_print_errors_fp (stderr);

exit (1);

}

printf ("Signature Verified Ok.\n");

return(0);

}

测试证书

公钥证书-----BEGIN CERTIFICATE-----

MIICLDCCAdYCAQAwDQYJKoZIhvcNAQEEBQAwgaAxCzAJBgNVBAYTAlBUMRMwEQYD

VQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5ldXJv

bmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMTEmJy

dXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZpMB4X

DTk2MDkwNTAzNDI0M1oXDTk2MTAwNTAzNDI0M1owgaAxCzAJBgNVBAYTAlBUMRMw

EQYDVQQIEwpRdWVlbnNsYW5kMQ8wDQYDVQQHEwZMaXNib2ExFzAVBgNVBAoTDk5l

dXJvbmlvLCBMZGEuMRgwFgYDVQQLEw9EZXNlbnZvbHZpbWVudG8xGzAZBgNVBAMT

EmJydXR1cy5uZXVyb25pby5wdDEbMBkGCSqGSIb3DQEJARYMc2FtcG9AaWtpLmZp

MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNw

L4lYKbpzzlmC5beaQXeQ2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAATAN

BgkqhkiG9w0BAQQFAANBAFqPEKFjk6T6CKTHvaQeEAsX0/8YHPHqH/9AnhSjrwuX

9EBc0n6bVGhN7XaXd6sJ7dym9sbsWxb+pJdurnkxjx4=

-----END CERTIFICATE-----

私钥证书

-----BEGIN RSA PRIVATE KEY-----

MIIBPAIBAAJBAL7+aty3S1iBA/+yxjxv4q1MUTd1kjNwL4lYKbpzzlmC5beaQXeQ

2RmGMTXU+mDvuqItjVHOK3DvPK7lTcSGftUCAwEAAQJBALjkK+jc2+iihI98riEF

oudmkNziSRTYjnwjx8mCoAjPWviB3c742eO3FG4/soi1jD9A5alihEOXfUzloenr

8IECIQD3B5+0l+68BA/6d76iUNqAAV8djGTzvxnCxycnxPQydQIhAMXt4trUI3nc

a+U8YL2HPFA3gmhBsSICbq2OptOCnM7hAiEA6Xi3JIQECob8YwkRj29DU3/4WYD7

WLPgsQpwo1GuSpECICGsnWH5oaeD9t9jbFoSfhJvv0IZmxdcLpRcpslpeWBBAiEA

6/5B8J0GHdJq89FHwEG/H2eVVUYu5y/aD6sgcm+0Avg=

-----END RSA PRIVATE KEY-----

编译用的makefile

CC=ccCFLAGS= -g -I../../include -WallLIBS= ./base64.o -L../.. -lcrypto -ldlEXAMPLES=signall: $(EXAMPLES) sign: sign.o$(CC) -o sign sign.o $(LIBS)clean:rm -f $(EXAMPLES) *.otest: all./sign

php pkcs7签名验签算法,OpenSSL 签名验签接口调用及测试相关推荐

  1. Openssl ECC椭圆曲线算法 - 密钥/签名/验签/加密/解密/SM2密文 - 序列化反序列化导出导入 - C源码

    . . . . 废话不多说,本代码继承自另外一位讲解Openssl ECC椭圆曲线算法大佬的源代码:https://blog.csdn.net/scuyxi/article/details/59182 ...

  2. C语言——基于OpenSSL 的RSA 签名验签算法

    OpenSSL开源工程中,实现RSA签名方法有多种.该方法基于OpenSSL 3.0版本,调用OpenSSL EVP层的EVP_DigestSign*()与EVP_DigestVerify*()实现p ...

  3. 基于mbedTLS算法库实现国密SM2签名和验签算法

    网上有大量的基于OpenSSL实现的国密算法库,比如著名的GmSSL,可以直接拿来用.我自己常用的是mbedTLS的算法库,比较小巧简单,在mbedTLS的大数算法的基础上实现了国密SM2的签名和验签 ...

  4. php pfx加密,php基于sha1withRSA算法的签名和验签(pfx证书)

    在和第三方支付接口对接时经常会对数据进行签名和验签,sha1WithRSA也算是比较常用的一种签名加密算法.php开启openssl库后实现起来也算比较简单. 我在这里使用sha1withRSA算法来 ...

  5. RSA加密、解密、签名、验签(验证签名)RSA算法原理

    转载链接:https://www.jianshu.com/p/8dc4a5f64e06 https://www.cnblogs.com/pcheng/p/9629621.html RSA原理:http ...

  6. 国家医保移动支付国密算法SM2签名验签、SM4加解密DLL

    国家医保移动支付国密算法SM2签名验签.SM4加解密DLL 支持医保移动支付(国家统一版), 已知省份有广西.贵州.安徽.河北.黑龙江.湖南.吉林.江苏.四川.新疆等各地方. DLL,非.net开发, ...

  7. 国密SM9算法C++实现之五:签名验签算法

    SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...

  8. php dsa 签名,openssl使用DSA算法生成签名实例详解_PHP教程

    文章给大家介绍基于openssl使用DSA算法生成签名实例,生成签名方法很简单,我们需要懂得中间的原理就比较复杂了,大家一起来看看吧. 命令: openssl> dgst -dss1 -sign ...

  9. API接口签名生成算法和签名验证算法

    1.参考网上资料和书本资料,实现了API接口签名生成算法和签名验证算法. (1)参考资料:https://www.jianshu.com/p/d47da77b6419 (2)参考书籍:高级软件架构师教 ...

最新文章

  1. 注意:宝塔曝未授权访问数据库漏洞,尽快升级版本!
  2. SATA硬盘如何使用GHOST
  3. AQS.addWaiter
  4. 区间第K大(划分树)
  5. java字节数组转换成16进制_Java 将字节数组转化为16进制的多种方案
  6. JS拖拽,移动与拉伸
  7. 匿名函数自我调用_Python中的匿名函数及递归思想简析
  8. 巧设IP路由 实现不同网段互通
  9. 计算机的发展经历阶段应用领域,手机的发展经历了哪3个阶段?
  10. 威廉·布莱克《从一颗沙子看世界》(To see a world in a grain of sand)
  11. java基础总结06-常用api类-System类常用方法
  12. 【深度学习】CNN算法
  13. 如何通过搜索计算机共享打印机驱动程序,怎么解决连接共享打印机时“找不到驱动程序”...
  14. java日志框架JUL、JCL、Slf4j、Log4j、Log4j2、Logback 一网打尽
  15. 【计算机毕业设计】基于微信小程序的社区疫情防控系统
  16. JavaScript树形下拉框
  17. #把一个数把各个位数拆取出来
  18. n平方的求和公式_1到N的平方和,立方和公式是怎么推导的
  19. Java初级知识复习-2021.12.27~2022.02.09
  20. 鲲鹏聚数,华为宣布联合高校发起GaussDB金种子发展计划

热门文章

  1. MySQL删除SQL慢
  2. 电大通用计算机考试,电大计算机考试试题
  3. 4种搜集来的Axure原型上传+在线预览的方法
  4. 你遇到过哪些高质量的C++面试?
  5. oracle 分析函数视频教程,Oracle 分析函数使用教程(3)
  6. 解决Invalid numeric Value:Leading zeroes not allowed问题
  7. 初学Python-简单的,在图片上加png(logo)
  8. ASP.NET MVC 單元測試系列 (3):瞭解 Mock 假物件 ( moq )
  9. 百度地图API计算俩点距离
  10. 图的建立(邻接矩阵)与其深度优先和广度优先遍历