RSA加密及加签
1.对方要求我们的私钥是pkcs8格式,但是实际的公钥没有用pkcs8转换之后的私钥完成,所以是可以不是pkcs8的格式的。我们加签跟格式没有关系。
2.数据格式很重要,to_mpint而非crypto:mpint生成mpint的高精度整型,to_mpint有是自己写的函数,但实际上有很多开源代码里面有,所以要多看开源代码及想到直接调用。
3.RSA加密加签原理:
(1).加密,可以用私钥加密,公钥解密。
(2).加密,也可以用公钥加密,私钥解密。
(3).加签,必须要用私钥加签,公钥验证。
(4).调用的方法不同。原理如下:
RSA数据的hash^私钥 mod M = 签名
签名 ^公钥 mod M = 数据的hash
数据 ^公钥 mod M = 密文
密文 ^私钥 mod M = 数据
4.调用erlang的crypto模块加密
5.生成密钥的方法是一样的。
(1).按装openssl(基础环境中有此软件,无需安装)
(2).输入openssl
生成私钥: genrsa -out private_key.pem 1024
(3).转换成pkcs8格式(可无)pkcs8 -topk8 -inform PEM -in private_key.pem -outform PEM -nocrypt -out rsa_private_key.pem
(4).用私钥生成公钥: rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
6.对于加签,是使用crypto:rsa_sign还是crypto:sign,但是实际上sign是新版本的,我方安装版本跟不上。
7.对于未做过的操作,应该有几步:
(1)确认要使用的方法
(2)对于该方法所要的参数,如果格式不符合,要找到对应的转换方式(可以看开源库)
但是方向要弄对,要先找到解决方法,再找原因。
====================================加密================================================
加密(用私钥加密,公钥解密)
-module(crypto_api).
-include_lib("public_key/include/public_key.hrl").
-include("ewp.hrl").
-include("backend.hrl").
-export([testencode/1,%%测试加密函数
testdecode/1 %%测试解密函数
]).
%%Params为原始内容,数据类型为binary,_Foo为加密后的密文
case Type of
RSA ->
crypttest:testencode(Mobile); crypto_api:testencode()
_ ->
sm:
testencode(Params) ->
{ok, PemBinary} = file:read_file("./public/security/rsa_private_key.pem"),%%读取私钥中的pem二进制码
[Entry] = public_key:pem_decode(PemBinary),%%读取私钥中的pem二进制码,生产一个实体
RSAPrivateKey = public_key:pem_entry_decode(Entry),%%实体生产私钥Key
%%调用erlang的crypto模块加密
PrivKey = [crypto:mpint(RSAPrivateKey#'RSAPrivateKey'.publicExponent), crypto:mpint(RSAPrivateKey#'RSAPrivateKey'.modulus), crypto:mpint(RSAPrivateKey#'RSAPrivateKey'.privateExponent)] ,
_Foo = crypto:rsa_private_encrypt(Params,PrivKey,rsa_pkcs1_padding).
testdecode(Params) ->
{ok, PemBinary} = file:read_file("./public/security/rsa_public_key.pem"),
[Entry] = public_key:pem_decode(PemBinary),
RSAPublicKey = public_key:pem_entry_decode(Entry),
PubKey = [crypto:mpint(RSAPublicKey#'RSAPublicKey'.publicExponent), crypto:mpint(RSAPublicKey#'RSAPublicKey'.modulus)],
_Bar = crypto:rsa_public_decrypt(Params,PubKey,rsa_pkcs1_padding).
============================加签,MD5摘要生成=======================================================
-module(....).
-include("ewp.hrl").
-include("backend.hrl").
-include_lib("public_key/include/public_key.hrl").
-define(URL,"https://jiaofei........html").
-export([
'SN0001'/3, % 第三方配置化
proplist_to_andlist/1
]).
'SN0001'(UserObj, TranID, P) ->
MOBILE_NO = user_obj:get_field('MOBILE_NO', UserObj), %% 手机号
USER_CODE = user_obj:get_field('USER_CODE', UserObj), %% 手机银行客户号
Url = ?URL,
RequestTime = "20170214142901", %%ewp_time:datetime_str()
Version = "2.0", %
App_id = "yfbm70058192e2017021301", %
Merchant_user_no = "43243", %%商户id之后给 USER_CODE
Terminal_type = "03",
Sign_type = "RSA",
Signkey_index = "0001", %%公钥索引 测试
SignMD = list_to_possign([{"request_time",RequestTime},{"version",Version},{"app_id",App_id}, {"merchant_user_no",Merchant_user_no},{"terminal_type",Terminal_type}]), %%数字签名
{ok, Privatekey} = file:read_file("./config/key/private_key.pem"),%%读取私钥中的pem二进制码
SignRSA = rsa_encode(SignMD,Privatekey),
Sign = yaws_api:url_encode(SignRSA),
PostDetail = Sign, %%实际要post给苏宁的参数
[{url,Url},{post,PostDetail}].
rsa_encode(Data,Priv_key) ->
[Entry] = public_key:pem_decode(Priv_key), %%读取私钥中的pem二进制码,生产一个实体
RSAPrivateKey = public_key:pem_entry_decode(Entry), %%实体生产私钥Key 私钥加密 加密的时候传参数为二进制的
PrivKey = [crypto:mpint(RSAPrivateKey#'RSAPrivateKey'.publicExponent),
crypto:mpint(RSAPrivateKey#'RSAPrivateKey'.modulus), crypto:mpint(RSAPrivateKey#'RSAPrivateKey'.privateExponent)],
Result = crypto:rsa_sign('sha',to_mpint(Data),PrivKey), %% crypto:rsa_sign('sha',NumberMpint,PrivKey) crypto:sign(rsa,md5,Number,PrivKey)
ResultBase = base64:encode(Result),
binary_to_list(ResultBase). %% 传回后台使用 变回字符串的类型
to_mpint(String) when is_list(String) ->
to_mpint(list_to_binary(String));
to_mpint(Bin) ->
Size = size(Bin),
<<Size:32/integer, Bin:Size/binary>>.
%% params: Proplist为[{...},.tuple..,{...}]格式。
%% 返回结果:key=value&key1=value1....
proplist_to_andlist(Proplist)->
Str1 = lists:foldl(
fun(X,Acc)->
{Key1,Value1} = X,
Key = atom_to_string(Key1),
Value = atom_to_string(Value1),
case [Key,Value] of
[_,""] ->
Acc; %%如果值为空,不放入该序列
[_," "] ->
Acc;
_ ->
case Acc of
[] ->
Acc ++ Key ++ "=" ++ Value;
" " ->
Acc ++ Key ++ "=" ++ Value;
_ ->
Acc ++ "&" ++ Key ++ "=" ++ Value
end
end
end,"",Proplist),
Str1.
%% params: Proplist为[{...},.tuple..,{...}]格式。
%% 返回结果:数字签名---MD5加密后的大写的16进制(按照微信规则商户支付密钥放置在串最后加密)
list_to_possign(Proplist)->
SortList = lists:keysort(1,Proplist), %%ASC码从小到大排序
Str1 = proplist_to_andlist(SortList), %%拼接成 Key1=value1&Key2=value2 无key商户支付密钥的序列
Res1 = Str1,
MD1 = erlang:md5(Res1), %%
<<Int:128>> = MD1, %% MD2 = backend_util:to_hexstr(MD1)
Str = integer_to_list(Int,16), %%生成大写的16进制
Str.
%% 如果参数A为atom则转换为string,如果本来就是string则还是string
atom_to_string(A)->
case is_atom(A) of
true ->
atom_to_list(A);
false ->
A
end.
RSA加密及加签的更多相关文章
- 微信小程序(17)-- RSA加密 解密 加签 验签
RSA加密 解密 加签 验签 /** * 注:区分RSA私钥的类型,有pkcs1和pkcs8.pkcs8格式的私钥主要用于Java中 pkcs1格式: -----BEGIN RSA PRIVATE K ...
- C# 数字证书 RSA加密解密 加签验签
KeyValuePair<string, string> keyPair = Encrypter.CreateRSAKey(); string privateKey = keyPair.V ...
- 【绝迹篇】RSA加密算法(私钥加签公钥验签)
对于上上篇博客中我讲的一个故事,本文引用: https://www.cnblogs.com/ButterflyEffect/p/9851403.html 故事中提到的关于加密会出现,私钥加密,公钥解密 ...
- C++ 使用openssl库实现 DES 加密——CBC模式 && RSA加密——公加私解——私加公解
之前工作上需要用C++把软件生成的用户序列号用des加密cbc的模式,加密后为二进制,转化为十六进制,然后提供给java写的授权码管理平台. java平台会根据用户序列号,生成一个授权码,授权码是用r ...
- Java RSA加密以及验签
签名加密以及验签工具类: 一般秘钥分为3个key 1.自己生成的私钥, 2.通过私钥生成的公钥1 3.通过提交公钥1给某宝,获取的公钥2. RSA公钥加密算法简介 非对称加密算法.只有短的RSA钥匙才 ...
- rsa 加密 pkcs#1格式秘钥的格式化
C++调用openssl库生成的秘钥对,通过传输传出来的只有秘钥的内容,没有秘钥的格式.而我们在调用openssl库加密解密时,传入的秘钥是需要包含格式的.C++调用openssl库需要的格式为pkc ...
- C++调用openssl库生成RSA加密秘钥对
直接上代码.默认生成的是pkcs#1格式 // ---- rsa非对称加解密 ---- // #define KEY_LENGTH 1024 // 密钥长度 #define PUB_KEY_FILE ...
- ruby的加密方法整理(des rsa加密 加签)
# coding:utf-8require 'openssl'require 'base64'#des加密并且base64编码def des_encrypt des_key, des_text des ...
- RSA加密解密及RSA加签验签
RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...
随机推荐
- vue-awesome-swiper组件不能自动播放和导航器小圆点不显示问题
from: https://blog.csdn.net/osdfhv/article/details/79062427 <template> <div class="swi ...
- mac系统maven spring mvc小试牛刀
转: https://blog.csdn.net/Hitourlee/article/details/77930309和https://www.cnblogs.com/xiaowenbo/p/6980 ...
- Servlet+纯java+MySQL实现课程信息的增删改查
Dbutil: package com.zh.util; import java.sql.Connection; import java.sql.DriverManager; import java. ...
- Docker Kubernetes 容器更新与回滚
Docker Kubernetes 容器更新与回滚 环境: 系统:Centos 7.4 x64 Docker版本:18.09.0 Kubernetes版本:v1.8 管理节点:192.168.1.79 ...
- Python 类的特性讲解
类的特性讲解 类的特性 #定义一个类, class是定义类的语法,Role是类名, (object)是新式类的写法,必须这样 写,以后再讲为什么 class Role(object): #初始化函数, ...
- nmon监控数据分析
性能测试中,各个服务器资源占用统计分析是一个很重要的组成部分,通常我们使用nmon这个工具来进行监控以及监控结果输出. 一. 在监控阶段使用类似下面的命令 ./nmon -f write_3s_20v ...
- Java虚拟机内存分配详解
简介 了解Java虚拟机内存分布的好处 1.了解Java内存管理的细节,有助于程序员编写出性能更好的程序.比如,在新的线程创建时,JVM会为每个线程创建一个专属的栈 (stack),其栈是先进后出的数 ...
- FastJson中JSONObject用法及常用方法总结
本文为博主原创,未经允许不得转载: 最近一直有用到解析各种数据,主要是用FastJson进行数据解析,其中一个重要的类为JSONObject,今天有时间,所以进行总结一下: JSONobject是Fa ...
- 初始Vue
渐进式 JavaScript 框架 通过对框架的了解与运用程度,来决定其在整个项目中的应用范围,最终可以独立以框架方式完成整个web前端项目 走进Vue what -- 什么是Vue 可以独立完成前后 ...
- 《温故而知新》JAVA基础八
集合接口与泛型 定义: 集合接口会操作一系列相同属性数据的对象类型的数据结构,类似于数组,但是相对于数组来说更显得高端大气 集合的接口分为Collention和Map两大类,不直接操作,而是通过子类的 ...