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. CentOS 7 系统优化

    系统调优4大子系统 1:找出系统中使用CPU最多的进程 2:找出系统中使用内存最多的进程 3:找出系统中对磁盘读写最多的进程 4:找出系统中使用网络最多的进程 系统调优概述 系统的运行状况:  CPU ...

  2. RNA-seq基本流程

    https://www.2cto.com/net/201801/714420.html

  3. 【转】AI类人工智能产品经理的丛林法则

    本文转载自:https://blog.csdn.net/buptgshengod/article/details/77030338 AI是大家都很关注的领域,然而对于大部分想要入行的同学来讲,AI的算 ...

  4. axios、ajax、fetch三者的区别

    1.ajax:是指一种创建交互式网页应用的网页开发技术,并且可以做到无需重新加载整个网页的情况下,能够更新部分网页,也叫作局部更新 优缺点: 1)局部更新 2)原生支持,不需要任何插件 3)原生支持, ...

  5. 【酷】JS+CSS打造沿Y轴纵深运动的3D球体

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  6. php 根据日期获取星座

    根据日期获取星座 /* * * 获取星座 * 星座是按阳历来计算的 * $month 阳历月份 * $day 阳历日期 * */ public static function get_xingzuo( ...

  7. Springboot 使用PageHelper分页插件实现分页

    一.pom文件中引入依赖 二.application.properties中配置以下内容(二选一方案) 第一种:pagehelper.helper-dialect=mysqlpagehelper.re ...

  8. 内置函数filter()和匿名函数lambda解析

    一.内置函数filter filter()函数是 Python 内置的一个高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回由符合条件迭代器 ...

  9. 清华集训2017 Day 2简要题解

    *注意:这套题目题面请在loj / uoj查看 从这里开始 题目列表(loj) Problem A 小 Y 和地铁 Problem B 小 Y 和二叉树 Problem C 小 Y 和恐怖的奴隶主 训 ...

  10. NSIS控制面板中显示安装包的大小和禁止多个安装程序实例

    转载:http://www.yhxs3344.net/jscript/nsis 转载:http://www.yhxs3344.net/archives/1292 1.控制面板中显示安装包的大小 ;需要 ...