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加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...
随机推荐
- Python str byte 互相转换
- AARRR海盗模型简介
整理下AARRR模型的概念.实际应用场景等问题,初步感觉这个模型主要应用在APP应用分析中. 1.什么是AARRR模型 AARRR是Acquisition.Activation.Retention.R ...
- flask 在视图函数里操作数据库
在视图函数里操作数据库 在视图函数里操作数据的方式和在python shell中的联系基本相同,只不过需要一些额外的工作.比如把查询结果作为参数 传入模板渲染出来,或是获取表单的字段值作为提交到数据库 ...
- ajax跨域问题及相关解决方案
1 什么是跨域 所谓的跨域是指浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器施加的安全限制. 所谓同源是指,域名,协议,端口均相同: 2 什么时候会存在跨域的问题 页面访问不同源 ...
- 【awk】提取文件第一列
生信数据文件一般是按列分开的,如果我们只想简单的提取一列而不是费尽周折写个程序提取哪一列的话,awk作为一个非常好用的文档处理工具,我们现在来简单看一下他的一些功能: awk '{print $1}' ...
- flask的简单使用
一.Flask中的CBV from flask import Flask, render_template from flask import views app = Flask(__name__, ...
- 模块 import 与from
什么是模块:就是一系列功能的集合体 模块的来源 :1内置模块 2 第三方模块 3 自定义模块 模块的格式: 1 使用python编写的.py文件 2 已被编译为共享库或DLL的C或C++扩展 ...
- NET的基本用法
NET的基本用法 NET [ ACCOUNTS | COMPUTER | CONFIG | CONTINUE | FILE | GROUP | HELP | HELPMSG | LOCALGROUP ...
- c#查找窗口的两种办法
原文最早发表于百度空间2009-06-17 1.process.MainWindowTitle(这个只能获取一部分窗口)2.EnumWindows(用windows API)
- Shell 变量知识
1.自定义变量:自定义变量不能以数字开头. ()root#a=’cd /etc/’ #设置自定义变量. root#etho $a #使用变量. 2.全局变量:export可设置全局变量不能以数字开头. ...