php pkcs7签名验签算法,OpenSSL 签名验签接口调用及测试
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 签名验签接口调用及测试相关推荐
- Openssl ECC椭圆曲线算法 - 密钥/签名/验签/加密/解密/SM2密文 - 序列化反序列化导出导入 - C源码
. . . . 废话不多说,本代码继承自另外一位讲解Openssl ECC椭圆曲线算法大佬的源代码:https://blog.csdn.net/scuyxi/article/details/59182 ...
- C语言——基于OpenSSL 的RSA 签名验签算法
OpenSSL开源工程中,实现RSA签名方法有多种.该方法基于OpenSSL 3.0版本,调用OpenSSL EVP层的EVP_DigestSign*()与EVP_DigestVerify*()实现p ...
- 基于mbedTLS算法库实现国密SM2签名和验签算法
网上有大量的基于OpenSSL实现的国密算法库,比如著名的GmSSL,可以直接拿来用.我自己常用的是mbedTLS的算法库,比较小巧简单,在mbedTLS的大数算法的基础上实现了国密SM2的签名和验签 ...
- php pfx加密,php基于sha1withRSA算法的签名和验签(pfx证书)
在和第三方支付接口对接时经常会对数据进行签名和验签,sha1WithRSA也算是比较常用的一种签名加密算法.php开启openssl库后实现起来也算比较简单. 我在这里使用sha1withRSA算法来 ...
- RSA加密、解密、签名、验签(验证签名)RSA算法原理
转载链接:https://www.jianshu.com/p/8dc4a5f64e06 https://www.cnblogs.com/pcheng/p/9629621.html RSA原理:http ...
- 国家医保移动支付国密算法SM2签名验签、SM4加解密DLL
国家医保移动支付国密算法SM2签名验签.SM4加解密DLL 支持医保移动支付(国家统一版), 已知省份有广西.贵州.安徽.河北.黑龙江.湖南.吉林.江苏.四川.新疆等各地方. DLL,非.net开发, ...
- 国密SM9算法C++实现之五:签名验签算法
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
- php dsa 签名,openssl使用DSA算法生成签名实例详解_PHP教程
文章给大家介绍基于openssl使用DSA算法生成签名实例,生成签名方法很简单,我们需要懂得中间的原理就比较复杂了,大家一起来看看吧. 命令: openssl> dgst -dss1 -sign ...
- API接口签名生成算法和签名验证算法
1.参考网上资料和书本资料,实现了API接口签名生成算法和签名验证算法. (1)参考资料:https://www.jianshu.com/p/d47da77b6419 (2)参考书籍:高级软件架构师教 ...
最新文章
- 注意:宝塔曝未授权访问数据库漏洞,尽快升级版本!
- SATA硬盘如何使用GHOST
- AQS.addWaiter
- 区间第K大(划分树)
- java字节数组转换成16进制_Java 将字节数组转化为16进制的多种方案
- JS拖拽,移动与拉伸
- 匿名函数自我调用_Python中的匿名函数及递归思想简析
- 巧设IP路由 实现不同网段互通
- 计算机的发展经历阶段应用领域,手机的发展经历了哪3个阶段?
- 威廉·布莱克《从一颗沙子看世界》(To see a world in a grain of sand)
- java基础总结06-常用api类-System类常用方法
- 【深度学习】CNN算法
- 如何通过搜索计算机共享打印机驱动程序,怎么解决连接共享打印机时“找不到驱动程序”...
- java日志框架JUL、JCL、Slf4j、Log4j、Log4j2、Logback 一网打尽
- 【计算机毕业设计】基于微信小程序的社区疫情防控系统
- JavaScript树形下拉框
- #把一个数把各个位数拆取出来
- n平方的求和公式_1到N的平方和,立方和公式是怎么推导的
- Java初级知识复习-2021.12.27~2022.02.09
- 鲲鹏聚数,华为宣布联合高校发起GaussDB金种子发展计划
热门文章
- MySQL删除SQL慢
- 电大通用计算机考试,电大计算机考试试题
- 4种搜集来的Axure原型上传+在线预览的方法
- 你遇到过哪些高质量的C++面试?
- oracle 分析函数视频教程,Oracle 分析函数使用教程(3)
- 解决Invalid numeric Value:Leading zeroes not allowed问题
- 初学Python-简单的,在图片上加png(logo)
- ASP.NET MVC 單元測試系列 (3):瞭解 Mock 假物件 ( moq )
- 百度地图API计算俩点距离
- 图的建立(邻接矩阵)与其深度优先和广度优先遍历