引言:
2017年就要到了,想想自己使用阿里云搭的博客 眼看就要到期了。 虽说没写几遍有质量的文章吧,但是放其不管也于心不忍。这几天就琢磨着把几遍有内容的转到博客中。在寻求着落点的时候发现Markdown。看了CSDN中Markdown的范文,再看看自己曾经写的文章。只能呵呵了
想着就借此机会学习一下Markdown的话语。


最近一个项目对接。要使用SHA1WithRSA签名验签。
之前接触过DES、3DES、 AES、 SHA1、 MD5、RSA 看这加密想当然的觉得是就是先对数据做个SHA1摘要再做个RSA加密嘛,简单不是。
man 了一下 openssl 关于RSA加解密。霹雳啪啦几个小时就把 理解的“SHA1WithRSA”实现了。
但是测试时对方就是验签不过。
后面还是问广大的网络。才让我得了解自己的无知。
这不也有人和犯一样的错 哈哈

简单阅读一下就能大概知道实际上可以通过openssl的RSA_sign实现
来看一下RSA_sign

#include <openssl/rsa.h>int RSA_sign(int type, const unsigned char *m, unsigned int m_len,unsigned char *sigret, unsigned int *siglen, RSA *rsa);int RSA_verify(int type, const unsigned char *m, unsigned int m_len,unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

DESCRIPTION
RSA_sign() signs the message digest m of size m_len using the private key rsa as specified in PKCS #1 v2.0. It stores the signature in sigret and the signature size in siglen. sigret must point to RSA_size(rsa) bytes of memory. Note that PKCS #1 adds meta-data, placing limits on the size of the key that can be used. See RSA_private_encrypt for lower-level operations.
type denotes the message digest algorithm that was used to generate m. If type is NID_md5_sha1, an SSL signature (MD5 and SHA1 message digests with PKCS #1 padding and no algorithm identifier) is created.
RSA_verify() verifies that the signature sigbuf of size siglen matches a given message digest m of size m_len. type denotes the message digest algorithm that was used to generate the signature. rsais the signer’s public key.
RETURN VALUES
RSA_sign() returns 1 on success. RSA_verify() returns 1 on successful verification.

简单看看,其实RSA_sing()函数第一为送NID_sha1

通过这篇文章知道需要签名的是SHA1摘要而非所有报文。所以要先对明文数据做SHA1。再调用 RSA_sign()签名。

结论:

对openSSL源码一知半解的我,竟把RSA加密|解密和RSA签名|验证混淆。
最后 私钥加密 ≠ 签名

20170519更新
这几天看了下这文章阅读人数相比还挺多的。空闲之余就把整理下自己以前写的test程序提供给大家参考下。

秘钥对是我是使用openssl命令生产的给出的参考如下。另外秘钥文件格式有很多种,请注意。
生产私钥

openssl genrsa -out userkey.pem 1024   

从私钥中导出公钥

openssl rsa in userkey.pem -pubout -out userpub.key

签名测试代码

#include <string.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>RSA* getPrivateKey(char* in_szKeyPath)
{FILE    *fp = NULL; char    szKeyPath[1024];RSA     *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;memset(szKeyPath, 0 ,sizeof(szKeyPath));if(256 < strlen(in_szKeyPath))strncpy(szKeyPath, in_szKeyPath, 256);elsestrncpy(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));printf("密钥文件路径[%s]", szKeyPath);/*  打开密钥文件 */if(NULL == (fp = fopen(szKeyPath, "rb"))){printf( "打开密钥文件[%s]出错", szKeyPath);return NULL;}/*  获取私密钥 */if(NULL == (priRsa = PEM_read_RSAPrivateKey(fp, &priRsa, NULL,NULL))){printf( "读出私钥内容出错\n");fclose(fp);return NULL;}fclose(fp);printf("提取私钥\n");pOut = priRsa;return pOut;
}RSA* getPublicKey(char* in_szKeyPath)
{FILE    *fp = NULL; char    szKeyPath[1024];RSA     *priRsa = NULL, *pubRsa = NULL, *pOut = NULL;memset(szKeyPath, 0 ,sizeof(szKeyPath));if(256 < strlen(in_szKeyPath))strncpy(szKeyPath, in_szKeyPath, 256);elsestrncpy(szKeyPath, in_szKeyPath, strlen(in_szKeyPath));printf("密钥文件路径[%s]", szKeyPath);/*  打开密钥文件 */if(NULL == (fp = fopen(szKeyPath, "rb"))){printf( "打开密钥文件[%s]出错", szKeyPath);return NULL;}/*  获取公密钥 */if(NULL == (priRsa = PEM_read_RSA_PUBKEY(fp, &priRsa, NULL,NULL))){printf("读出私钥内容出错\n");fclose(fp);return NULL;}fclose(fp);printf("提取公钥\n");pOut = priRsa;return pOut;
}int main(void)
{int     flen,rsa_len, ienLen, iRet;RSA     *prsa = NULL;char    szEnData[]="orderId=01010500201502000004reqTime=20150205012727ext=20151120ext2=1";char    szTmp[10240], szTmp1[10240];if(NULL == (prsa = getPrivateKey("userkey.pem"))){RSA_free(prsa);printf("获取私钥失败\n");return -1;}//  RSA_print_fp(stdout, prsa, 11);flen = strlen(szEnData);printf("待签名数据:[%s]\n", szEnData);memset(szTmp, 0, sizeof(szTmp));memset(szTmp1, 0, sizeof(szTmp1));//  对待签名数据做SHA1摘要SHA1(szEnData, flen, szTmp);//使用私钥对SHA1摘要做签名ienLen = RSA_sign(NID_sha1, (unsigned char *)szTmp, 20, (unsigned char*)szTmp1, &iRet, prsa);if(ienLen != 1 ){printf("签名失败\n");RSA_free(prsa);return -1;}RSA_free(prsa);printf("签名成功\n");//签名串szTmp1二进制数据需要转成base64编码//mac=base64encode(szTmp1)这是伪码,生产MAC值,给对方去校验//验证签名//验证签名的是需要获取MAC值,明文签名数据,对“明文签名数据”做SHA1,获得摘要。在对MAC做basedecode(mac),然后调用函数验证签名if(NULL == (prsa = getPublicKey("userpub.key"))){RSA_free(prsa);printf("获取私钥失败\n");return -1;}flen = strlen(szEnData);printf("待签名数据:[%s]\n", szEnData);//签名数据 和 mac 因该是由通信报文中获得,这里演示直接用使用同一变量memset(szTmp, 0, sizeof(szTmp));memset(szTmp1, 0, sizeof(szTmp1));//  对待签名数据做SHA1摘要SHA1(szEnData, flen, szTmp);ienLen = RSA_verify(NID_sha1, (unsigned char *)szTmp, 20, (unsigned char*)szTmp1, iRet, prsa);if(ienLen != 1 ){printf("签名不合法\n");RSA_free(prsa);return -1;}elseprintf("验签成功\n");RSA_free(prsa);return 0;
}

源码和秘钥文件资源

SHA1WithRSA签名使用openssl 实现相关推荐

  1. OpenSSL生成自签名的sha256泛域名证书

    环境: CentOS 6.8 x86_64 安装 openssl openssl-devel cp /etc/pki/tls/openssl.cnf openssl.cnf 修改openssl.cnf ...

  2. asn1 pem pfx格式证书_Linux使用openssl管理自签名证书保障网络安全

    请关注本头条号,每天坚持更新原创干货技术文章. 如需学习视频,请在微信搜索公众号"智传网优"直接开始自助视频学习 1. 前言 本文主要介绍如何在Linux系统上使用OpenSSL命 ...

  3. java openssl_verify_CryptoAPI:如何使用CryptVerifySignature验证来自OpenSSL或Java的DSA签名...

    如果不了解CryptoAPI,这应该是非常困难的. 主要障碍是: 使用CryptStringToBinaryA和CryptDecodeObjectEx解码X509 DSA公钥 转换DSA签名格式 Op ...

  4. 基于 OpenSSL 生成自签名证书,数字签名,泛域名证书,ca证书,PKI等

    基于 OpenSSL 生成自签名证书_qhh0205-CSDN博客_openssl自签名证书 windows 下 nginx 双向认证自签名证书配置 windows 下 nginx 双向认证自签名证书 ...

  5. Ubuntu18.04 使用 openssl制作自签名证书

    执行"openssl verison",判断系统是否已安装openssl,若没有安装,请使用apt安装openssl. 一.图解自签名过程 二.关于 CRT PEM KEY CST ...

  6. 利用Openssl自签名证书生成与单双向认证通信

    文章目录 1.什么是CA? 2.如何生成证书 2.1生成CA key 3.生成服务器私钥/证书 4.生成客户端私钥/证书 5.测试 1.什么是CA? 1.CA(Certificate Authorit ...

  7. 使用 openssl 对文件签名和验签

    这里介绍:文件签名和验签做了什么,openssl 命令行工具进行签名和验签. 文件签名和验签 签名 有文件 test.txt,使用摘要算法(如 SHA256)计算出文件的摘要,再使用私钥(privat ...

  8. OpenSSL创建的自签名证书在chrome端无法信任

    文章目录 问题描述 原因概述 解决方案 修改待用的openssl配置文件 创建证书 对tomcat配置证书(适用于Tomcat 8.5) 问题描述 ArcGIS Enterprise环境下往往需要创建 ...

  9. python3 如何实现RSA加解密 MD5withRSA/SHA1withRSA/SHA256withRSA签名

    java MD5WithRSA 算法 首先我们来看Java中的 MD5withRSA 签名 JAVA private static final String SIGNATURE_ALGORITHM = ...

最新文章

  1. 吴恩达说“将引领下一波机器学习技术”的迁移学习到底好在哪?
  2. MyEclipse 中Access restriction 出现问题的解决
  3. Python的Flask入门
  4. CentOS6中怎样将jdk1.7升级到1.8
  5. CodeForces 258B Little Elephant and Elections 数位DP
  6. 关于Linux路由表的route命令
  7. webpack 4.0 配置文件 webpack.config.js文件的放置位置
  8. laravel8找不到控制器_找一个“靠谱儿”的烟雾探测器方案,难不难?
  9. CS0656 缺少编译器要求的成员“Microsoft.CSharp..........
  10. Binary XML file line #6: Error inflating class xxx
  11. HTTP与HTTPS简介
  12. “你需要TrustedInstaller提供的权限才能对此文件进行更改” 解决方案
  13. html渐变生成,css gradient 在线渐变生成工具
  14. 天下武功唯快不破--速度要快
  15. word中删除多余的空白页
  16. 高考还有几天c语言作业,高考考几天
  17. mount:special device does not exist (a path prefix is not a directory)
  18. 一个领导发给下属的邮件,醍醐灌顶!
  19. 响应式五金机械网站pbootcms模板,蓝色营销型五金配件网站源码下载
  20. ESP8266环境搭建-ESP8266_RTOS_SDK(超详细)

热门文章

  1. 字体样式字体分类字体样式二
  2. 一个清华保送生妈妈对竞赛的感受,自主招生家长都要看看!
  3. 淘宝视频内容标签的结构化分析和管理
  4. ios 故事版 设定UIImageRenderingMode的方式
  5. 2022年上半年韩国移动游戏市场洞察
  6. 115道Java面试题及答案分享,java程序员赶紧收好
  7. JavaScript在表格中实现九九乘法表
  8. cesium实现图片与文字合成新图标
  9. 背阔肌(04):杠铃俯身划船
  10. [Java] 类和对象(简介,封装,内存机制,构造方法)