openssl+前端jsrsa签名+后端nodejs验签
内容如标题所示,总体分为三个部分:
一、win10下安装openssl,然后通过openssl工具生成RSA的公钥和私钥
(1)win10下安装openssl需要的工具有:VS2013,Perl,nasm,openssl源码
其中,VS2013的安装、注册和激活请自行百度,ActivePerl、nasm和openssl源码也请自行下载安装,ActivePerl好说(执行perl example.pl,若提示:Hello from ActivePerl! 则说明Perl安装成功),nasm我选的是nasm-2.11.02-installer.exe,openssl的部分版本在后面配置的时候会报错,我最后选的是openssl-1.0.2j.tar.gz (SHA256) (PGP sign) (SHA1)。
(2)设置环境变量
打开我的电脑->属性->高级系统设置->环境变量,找到Path系统变量,点击编辑,添加C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin;C:/Perl64/bin;C:/nasm;c:/windows/system32
我是按默认指示全都放在C盘,可以根据情况自己修改安装路径,安装Perl的时候它会在Path中添加C:/Perl64/site/bin,里面有一个dmake.exe运行文件,这里我把它复制到自己手动添加的C:/Perl64/bin目录下面,除此之外,还要将C:/nasm下面的name.exe和ndisasm.exe拷贝至C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin,设置完环境变量记得重启电脑才能生效。
(3)执行命令
打开Visual Studio的开发人员命令提示(找了半天,原来放在C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts),并进入openssl的目录(我的放在C盘根目录),执行命令perl Configure VC-WIN32 --prefix=C:/openssl 注意:这里的prefix是用来指定安装目录。然后运行 ms\do_nasm 来创建Makefile文件,运行 nmake -f ms\ntdll.mak 进行编译生成openssl动态库(如果报错Cannot open include file: 'windows.h',需要先定位到C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin运行 vcvars32.bat 来设置VC命令行编译的环境变量),然后耐心等待。。。接着运行 nmake -f ms/ntdll.mak test 来测试,若显示passed all tests,就可以运行 nmake -f ms\ntdll.mak install 来安装编译后的openssl到之前指定的目录。查看安装结果,即在 C:\openssl 下有三个文件夹bin、lib和include,其中bin目录下包括openssl.exe(openssl指令程序)、ssleay32.dll(ssl协议动态库)、libeay32.dll(密码算法库),lib目录下包括ssleay32.lib,libeay32.lib,include目录则包括了OpenSSL开发设计的头文件。另外,如果之前你已经编译出错了,请先清除:nmake -f ms\ntdll.mak clean。
(4)生成RSA的公钥和私钥
打开bin文件夹下面的openssl.exe,运行 genrsa -out rsa_private_key.pem 1024 在当前目录下生成一个名为rsa_private_key的pem格式文件,用记事本方式打开它,可以看到-----BEGIN RSA PRIVATE KEY-----开头,-----END RSA PRIVATE KEY-----结尾的没有换行的字符串,这个就是原始的私钥;
接着运行 pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt -out PKCS8_rsa_private_key.pem 把刚才的私钥转换成PKCS8格式,转换后的结果可以在命令行中看到,也可以在当前目录下生成的一个名为PKCS8_rsa_private_key的pem格式文件里看到;
最后运行 rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 生成公钥,可以在当前目录下生成的一个名为rsa_public_key的pem格式文件里看到,注意这里依据的是转换之前的原始私钥。
二、前端jsrsa签名
文字看得累,还是直接上代码吧。。。
// 引入非对称加密rsa的前台签名文件(github上有,我下的版本是6.2.2)
import Jsrsasign from "jsrsasign";
// 导入的Jsrsasign模块里面有很多实用的对象,对应不同的方法
console.log(Jsrsasign) // 引入私钥文件(一般java后台产生密匙对中的私钥是放在pem文件里,可以把里面的内容(字符串格式,带有头和尾,换行用\)取出来放进js文件,然后用module.exports导出来)
import PrivateKey from "privateKey.js"; // 实例化rsa
var rsa=new Jsrsasign.RSAKey(); // 传入私钥
// 默认传入的私钥是PKCS#1的格式,所以采用readPrivateKeyFromPEMString(keyPEM)这个方法
// rsa.readPrivateKeyFromPEMString(PrivateKey);
// 如果后台生产出来的私钥是PKCS#8的格式,就不能用readPrivateKeyFromPEMString(keyPEM)这个方法
rsa=Jsrsasign.KEYUTIL.getKey(key); // 对要签名的json数据进行排序、拼接成用=和&连接起来的URL的参数形式,参数依次是要排序的json对象、是否倒序(默认为false)
function jsonURLParams(json,reverse){
// 创建一个空数组
var jsonArr = [];
// 往空数组里面导入json对象
for(var i in json){
var obj = {}
obj[i] = json[i];
jsonArr.push(obj);
}
// 数组长度小于2 或 不是json格式数据
if(jsonArr.length < 2 || typeof jsonArr[0] !== "object") return jsonArr;
// 数字类型排序
if(typeof getKey(jsonArr[0]) === "number") {
jsonArr.sort(function(x, y) { return getKey(x) - getKey(y)});
}
// 字符串类型排序
if(typeof getKey(jsonArr[0]) === "string") {
// 按字符编码的顺序来排序
jsonArr.sort(function(x, y) {
var lenX = getKey(x).length,lenY = getKey(y).length,len = (lenX <= lenY) ? lenX : lenY;
for (var i = 0; i < len; i++) {
if (getKey(x).charCodeAt(i) != getKey(y).charCodeAt(i)) {
return getKey(x).charCodeAt(i) - getKey(y).charCodeAt(i);
}
if (i == len - 1) {
return getKey(x).length - getKey(y).length;
}
}
}
}
// 倒序
if(reverse) {
jsonArr.reverse();
}
// 创建一个空字符串
var jsonString = "";
for(var i in jsonArr){
if(i < jsonArr.length - 1){
jsonString += getKey(jsonArr[i]) + "=" + jsonArr[i][getKey(jsonArr[i])] + "&"
}else{
jsonString += getKey(jsonArr[i]) + "=" + jsonArr[i][getKey(jsonArr[i])]
}
}
// 封装函数获取json的key
function getKey(json){
for(var i in json){
return i;
}
}
return jsonString;
}
var signParams = jsonURLParams(data) // 选择哪种hash算法(散列生成一个报文摘要,目的是防篡改)
var hashAlg="sha1"; // 进行签名(对生成的报文摘要进行私钥加密,目的是身份验证)
var sign=rsa.signString(signParams,hashAlg); // 将签名结果转成base64编码格式
sign=Jsrsasign.hex2b64(sign); // 一般是将签名后的参数放进需要传递的json数据的末尾,对应的字段名为signture
data["signature"]=sign;
三、后端nodejs签名(使用的express框架4.14.0)
(1)先简单地封装了两个函数,记得要先引入JavaScript加密库crypto.js:
// 封装公钥单行字符串转换成PEM编码格式字符串的函数
function keyPem(str, insert_str, sn) {
var newstr = "";
for (var i = 0; i < str.length; i += sn) {
var tmp = str.substring(i, i + sn);
newstr += tmp + insert_str;
}
return newstr;
} // 封装验签函数,data是前端传上来的json数据,sign是前端生成的签名字符串,key是验签用的公钥
function verifySign(data,sign,key){
// 注意如果传上来的json数据里包含签名键值对,需要先将其剔除
delete data["signature"];
// 如果前端签名之前对上传数据进行了排序和字符串拼接,那么这里也要作同样操作,即要保持签名和验签的源数据相同,继续调用前面封装好的jsonURLParams函数
var data = jsonURLParams(data); // 如果sign取的是公钥文件头尾之间的一段字符串,需要先将其拼接回原来的PEM编码格式
// var key = keyPem(key,"\n",64);
// key = '-----BEGIN PUBLIC KEY-----\n' + key + '-----END PUBLIC KEY-----'; console.log("需要验证签名的数据:"+ data);
console.log("进行验证签名的公钥:\n" + key); // 选择与前端签名相匹配的hash算法
var verifier = crypto.createVerify('RSA-SHA1'); // 防止中文乱码
verifier.update(new Buffer(data, 'utf-8')); // 输出验签结果,如果前端签名后使用base64编码,这里也要作同样操作
return verifier.verify(key, sign, 'base64');
}
(2)在需要验签的地方调用上述函数
// 获取上传json数据
var data = req.body;
// 获取上传json数据中的签名字符串
var sign = data["signature"];
// 获取openssl生成的PEM编码格式的公钥
var key = "-----BEGIN PUBLIC KEY-----\n"+
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAH6/6+YVYA2FmF6H8uBmivR20\n"+
"ZbArDlDj1xG12w52XC47xTHrVp+PRufOUnUG58oNRO1SyD3ViZ6EzUclfVC/e8SS\n"+
"6y6/4wDYAsNke1tWH+M52O7S5ICfiULm6fLULc9rXxbZz6AT1PtD/JdRUKBtAGTx\n"+
"C+sR6OyH2UaqLra3qQIDAQAB\n"+
"-----END PUBLIC KEY-----";
// var key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAH6/6+YVYA2FmF6H8uBmivR20ZbArDlDj1xG12w52XC47xTHrVp+PRufOUnUG58oNRO1SyD3ViZ6EzUclfVC/e8SS6y6/4wDYAsNke1tWH+M52O7S5ICfiULm6fLULc9rXxbZz6AT1PtD/JdRUKBtAGTxC+sR6OyH2UaqLra3qQIDAQAB";
// 将三个参数传入封装好的验签函数
var result = verifySign(data,sign,key);
openssl+前端jsrsa签名+后端nodejs验签的更多相关文章
- java RSA实现私钥签名、公钥验签、私钥加密数据、公钥解密数据
通过OpenSSL生成公私钥文件(如果没有OpenSSL工具建议下载Cmder工具自带OpenSSL指令) 1.生成RSA密钥的方法 genrsa -out private-rsa.key 2048 ...
- java/php/c#版rsa签名以及java验签实现--转
在开放平台领域,需要给isv提供sdk,签名是Sdk中需要提供的功能之一.由于isv使用的开发语言不是单一的,因此sdk需要提供多种语言的版本.譬如java.php.c#.另外,在电子商务尤其是支付领 ...
- RSA后台签名前台验签的应用(前台采用jsrsasign库)
写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...
- RSA - 原理、特点(加解密及签名验签)及公钥和私钥的生成
Wiki - RSA加密演算法 Wiki - 欧拉函数 Wiki - 模反元素 ASN.1 格式标准 RSA算法原理(二) 注意: RSA 加密或签名后的结果是不可读的二进制,使用时经常会转为 BAS ...
- php 实现签名验签
本人php菜鸟,主要使用php实现简单的签名验签功能 以下php代码使用的密钥格式为pem格式,其他证书格式可以使用openssl进行转换(未安装请实现安装): 以下是.p12文件导出pem格式公私钥 ...
- SHA256withRSA证书签名,私钥签名/公钥验签
证书签名 package test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundE ...
- RSA加密、解密、签名、验签的原理及方法
一.RSA加密简介 RSA加密是一种非对称加密.可以在不直接传递密钥的情况下,完成解密.这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险.是由一对密钥来进行加解密的过程,分别称为公钥和私 ...
- RSA密钥生成、加密解密、签名验签
RSA 非对称加密公钥加密,私钥解密 私钥签名,公钥验签 下面是生成随机密钥对: //随机生成密钥对 KeyPairGenerator keyPairGen = null; try { keyPair ...
- RSA公钥、私钥、签名和验签
1 RSA加密算法介绍 RSA又叫非对称加密算法,这类加密算法有一对秘钥,其中一个用来加密一个用来解密.这一对秘钥中你可以选择一个作为私钥(自己保存),另一个作为公钥(对外公开).用私钥加密的内容只能 ...
随机推荐
- 设计模式(十一)外观模式(Facade Pattern)
一.引言 在软件开发过程中,客户端程序经常会与复杂系统的内部子系统进行耦合,从而导致客户端程序随着子系统的变化而变化,然而为了将复杂系统的内部子系统与客户端之间的依赖解耦,从而就有了外观模式,也称作 ...
- C# - 集合类
C#的集合类命名空间介绍: // 程序集 mscorlib.dll System.dll System.Core.dll // 命名空间 using System.Collections:集合的接口和 ...
- Struts2框架简介和示例
struts2框架 Struts2是java web的框架,在Java Web开发中,表示层框架,其核心是通过扩展Servlet来帮助处理http请求. Struct2的基本流程 Struct2的框架 ...
- JS 传播事件、取消事件默认行为、阻止事件传播
1.事件处理程序的返回值 通常情况下,返回值false就是告诉浏览器不要执行这个事件相关的默认操作.例如,表单提交按钮的onclick事件处理程序能通过返回false阻止浏览器提交表单,再如a标签的o ...
- IntelliJ IDEA使用(一):创建maven web项目
在公司用eclipse开发maven web项目后,慢慢开始明白大家的那句话"受不了eclipse".的确,在开发大型的web项目,尤其是maven构建的项目,eclipse很不友 ...
- Spring的IOC和AOP之深剖
今天,既然讲到了Spring 的IOC和AOP,我们就必须要知道 Spring主要是两件事: 1.开发Bean:2.配置Bean.对于Spring框架来说,它要做的,就是根据配置文件来创建bean实例 ...
- About 静态代码块,普通代码块,同步代码块,构造代码块和构造函数的纳闷
构造函数用于给对象进行初始化,是给与之对应的对象进行初始化,它具有针对性,函数中的一种.特点:1:该函数的名称和所在类的名称相同.2:不需要定义返回值类型.3:该函数没有具体的返回值.记住:所有对象创 ...
- ES5概述(ECMAScript262/5.1)
ES5概述(ECMAScript262/5.1) 本文参考:ES5概述 ECMAScript 是基于对象的: 基本语言和宿主设施都由对象提供,ECMAScript 程序是一组可通信的对象.ECMASc ...
- 非域客户端的office使用RMS加密服务出现‘介绍“信息权限管理服务”’服务的提示
环境:office2007,需要使用windows RMS服务,客户机处于工作组模式,如图: 出现这个说明客户机没有发现RMS服务,可以通过导入注册表解决,如下: Windows Registry E ...
- android 帧动画,补间动画,属性动画的简单总结
帧动画——FrameAnimation 将一系列图片有序播放,形成动画的效果.其本质是一个Drawable,是一系列图片的集合,本身可以当做一个图片一样使用 在Drawable文件夹下,创建ani ...