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加密及加签的更多相关文章

  1. 微信小程序(17)-- RSA加密 解密 加签 验签

    RSA加密 解密 加签 验签 /** * 注:区分RSA私钥的类型,有pkcs1和pkcs8.pkcs8格式的私钥主要用于Java中 pkcs1格式: -----BEGIN RSA PRIVATE K ...

  2. C# 数字证书 RSA加密解密 加签验签

    KeyValuePair<string, string> keyPair = Encrypter.CreateRSAKey(); string privateKey = keyPair.V ...

  3. 【绝迹篇】RSA加密算法(私钥加签公钥验签)

    对于上上篇博客中我讲的一个故事,本文引用: https://www.cnblogs.com/ButterflyEffect/p/9851403.html 故事中提到的关于加密会出现,私钥加密,公钥解密 ...

  4. C++ 使用openssl库实现 DES 加密——CBC模式 && RSA加密——公加私解——私加公解

    之前工作上需要用C++把软件生成的用户序列号用des加密cbc的模式,加密后为二进制,转化为十六进制,然后提供给java写的授权码管理平台. java平台会根据用户序列号,生成一个授权码,授权码是用r ...

  5. Java RSA加密以及验签

    签名加密以及验签工具类: 一般秘钥分为3个key 1.自己生成的私钥, 2.通过私钥生成的公钥1 3.通过提交公钥1给某宝,获取的公钥2. RSA公钥加密算法简介 非对称加密算法.只有短的RSA钥匙才 ...

  6. rsa 加密 pkcs#1格式秘钥的格式化

    C++调用openssl库生成的秘钥对,通过传输传出来的只有秘钥的内容,没有秘钥的格式.而我们在调用openssl库加密解密时,传入的秘钥是需要包含格式的.C++调用openssl库需要的格式为pkc ...

  7. C++调用openssl库生成RSA加密秘钥对

    直接上代码.默认生成的是pkcs#1格式 // ---- rsa非对称加解密 ---- // #define KEY_LENGTH 1024 // 密钥长度 #define PUB_KEY_FILE ...

  8. ruby的加密方法整理(des rsa加密 加签)

    # coding:utf-8require 'openssl'require 'base64'#des加密并且base64编码def des_encrypt des_key, des_text des ...

  9. RSA加密解密及RSA加签验签

    RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...

随机推荐

  1. 连接mysql数据库,创建用户模型

    1.安装与配置python3.6+flask+mysql数据库 (1)下载安装MySQL数据库 (2)下载安装MySQL-python 中间件 (3)pip install flask-sqlalch ...

  2. js-cookie的用法

    cookie的作用无需多言,自己封装一个cookie,不停地复制黏贴页颇为麻烦,在这里,有npm为我们封装好的插件js-cookie: https://www.npmjs.com/package/js ...

  3. 校验input 修改当前值的校验获取值方式

    <input style="height: 18px; width: 90px;" name="nowQty" value="${ad.nowQ ...

  4. BIOS备忘录之x86硬件编程(寄存器与IO)

    SOC固件(BIOS)开发: 1.熟悉硬件原理图:要弄清楚pin脚的功能: 2.配置GPIO引脚,配置成Native功能还是GPIO功能(如果是配置成GPIO,需要在code里面显式的使用): 3.硬 ...

  5. Kali Day01 --- arpspoof命令进行断网攻击(ARP欺骗)

    root@kali:~/文档# arpspoof -i eth0 -t 172.20.151.* 172.20.151.1 34:64:a9:36:4:b7 0:0:0:0:0:0 0806 42: ...

  6. Qt Windows打开指定文件注意替换双斜杠为单斜杠

    QProcess::startDetached(QString("explorer %1").arg(strFilePath)); 其中,在windows上使用时,strFileP ...

  7. Less、Sass和SCSS

    (一)区别: Less(可在客户端和服务端运行)是一种动态样式语言,对css赋予了动态语言的特性,如:变量.继承.运算.函数. SCSS为Sass的升级版本,兼容Sass功能,又新增功能.SCSS 需 ...

  8. js 数组元素排序

    字母排序 <html> <body> <script type="text/javascript"> ) arr[] = "Georg ...

  9. 误操作yum导致error: rpmdb

    error: cannot open Packages index using db5 -  (-30973) error: cannot open Packages database in /var ...

  10. 【shell脚本】 变量基础学习整理

    1.linux系统环境 echo 'echo /etc/profile ' >> /etc/profile echo 'echo /etc/bashrc' >> /etc/ba ...