先说下RSA概率:

公钥和私钥是通过本地openssl软件生成。

正常:

公钥加密=》私钥解密;

私钥签名=》公钥校验签名

最近做一个项目,对方用java公钥去校验签名,这边java的Demo使用私钥来加密的。

代码如下:

public class SignAccess {

    public String REQ_SERIAL_NO="";
public String REQ_TIME="";
public String ENV_FLAG="";
public String APP_ID="";
public String PRIVATE_KEY=""; public SignAccess(String REQ_SERIAL_NO, String REQ_TIME, String ENV_FLAG, String APP_ID,String PRIVATE_KEY) {
this.REQ_SERIAL_NO = REQ_SERIAL_NO;
this.REQ_TIME = REQ_TIME;
this.ENV_FLAG = ENV_FLAG;
this.APP_ID = APP_ID;
this.PRIVATE_KEY = PRIVATE_KEY;
} /**
* 获取对应的sign值
* @return
*/
public String getSign(){
//组装输入参数map
Map<String,Object> map = new HashMap<>();
map.put("REQ_SERIAL_NO", REQ_SERIAL_NO);
map.put("REQ_TIME", REQ_TIME);
map.put("ENV_FLAG", ENV_FLAG);
map.put("APP_ID", APP_ID);
//给map排序后转换为字符串
StringBuilder sb = new StringBuilder();
final Map<String,Object> sortMap = new TreeMap(new Comparator<String>() { @Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
});
sortMap.putAll(map);
for (final Map.Entry<String,Object> entry : sortMap.entrySet()) {
sb = sb.append(entry.getKey()).append(entry.getValue());
}
String dest = sb.toString();
//sha256加密
String strDes=encrypt(dest);
//私钥加密
byte[] enBytes = null;
byte[] data;
try {
data = strDes.getBytes("UTF-8");
final Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, getPrivateKey(PRIVATE_KEY));
for (int i = ; i < data.length; i += ) {
final byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + ));
enBytes = ArrayUtils.addAll(enBytes, doFinal);
}
try {
return Base64.encodeBase64String(enBytes);
} catch (final Exception e) {
System.err.println("Base64出错");
}
} catch (final Exception e) {
System.err.println("私钥加密出错");
}
return "";
} /**
* 秘钥转换方法
* @param key
* @return
*/
public PrivateKey getPrivateKey(String key){
java.security.Security.addProvider(
new org.bouncycastle.jce.provider.BouncyCastleProvider()
);
byte[] keyBytes;
keyBytes = Base64.decodeBase64(key);
final PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory;
try {
keyFactory = KeyFactory.getInstance("RSA");
final PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
} catch (final Exception e) {
System.err.println("获取私钥出错");
}
return null;
} private String encrypt(final String strSrc) { MessageDigest md = null;
String strDes = null;
try {
// byte[] bt = strSrc.getBytes();
md = MessageDigest.getInstance("SHA-256");
// md.update(bt);
try {
strDes = bytesToHexString(md.digest(strSrc.getBytes("UTF-8")));
} catch (final UnsupportedEncodingException e) {
System.err.println("编码失败");
}
} catch (final NoSuchAlgorithmException e) {
System.err.println("编码失败"); }
return strDes;
}
/**
* 转16进制
*
* @param src
* @return
*/
private String bytesToHexString(final byte[] src) { final StringBuilder stringBuilder = new StringBuilder("");
if (src == null || src.length <= ) {
return null;
}
for (int i = ; i < src.length; i++) {
final int v = src[i] & 0xFF;
final String hv = Integer.toHexString(v);
if (hv.length() < ) {
stringBuilder.append();
}
stringBuilder.append(hv);
}
return stringBuilder.toString();
} public static void main(String args[])
{ String privateKey="MIICWwIBAAKBgQC2TSwydOrZ0Ija3YbloMWXQP6xOIn1DUOiOHCYJkRYTk+FviR+
P6EOOSwPLFcd91k65jHZOF91pifQf6tHzFQjhc0phTGWsjpHPhGeJ6tgzSZr5xIQ
mCp4xPW4x7N0Y1vciz3ZBfTZyMu2k3iHgbxT8uPeKDKD2vZhC0FEOVU0oQIDAQAB
AoGAarwma2he9KaO6i4XxCxsY9GPDW3///UDK2CGM9771wQKtVCNh0lz36MDs+KP
IyFmIgETII5L/dMJrp6BRylP/PsWWQAZqfoI7FQbKFWKnvTGhDxCtW7FvZOq9MhG
VMA5BfdE4zBgauo9kYdqzsKxIzndE5EJg4j86pFZwn6BWb0CQQDjWnoh25AXEHhw
Fo5Gd0N5aceK4uFQ5DukTUSH1y5b/z4Q5OvC3JopjUMVfDYk32C+sSw3zF9PuCK8
XmIE476rAkEAzUV/P6onzngqIiXPtpd5EuDKDM+4pvxJine7+2onY3rCtA1LFaLn
laIrAQ//b0Ub4cJMNxID4v1WDfBYo1p4wJADe2qE87uuesBZeSL3NdLo/GODv0t
TpZc7QjqzOOq7GnrtH9BzlNTgn4sAPH2IzYoKCaUjeqQYELopd+mY6RMNwJAJO8s
RjhHkU7txdcn2KLIliz8LfHyN5mNYezJViNzkuKzxdHegLYfFT1on3hP6LfsxWR2
suPv01xLeOQPV7w6IQJAO/bB2Ul7hRAgyHzlBMZoVEMY4LGfd41yDzrrpNjr2JUT
dsrXPbduLGGEdqE4M4uM/T+Vg3elAWM+eW7tGD2v5w==";
String reqSerialNo="";
String reqTime="";
String envFlag="";
String appId="";
SignAccess signAccess=new SignAccess(reqSerialNo,reqTime,envFlag,appId,privateKey);
System.out.println(signAccess.getSign());
}
}

c#试了N多方式,没有做到签名一致。这里贴下c#的加密和签名的代码

加密解密代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks; namespace RSA加密
{
public class RSACSharp
{ public static void test()
{
string de = "iBILuPJFgPMxgpbgN3F2JjD6XjcqRSApjVVbvBBEBDV21Pjj7lTrfhEjSVnJX/MVoZrmX0lxsvoXTMvvVwVF7K7W5hs7Qo+aMN96yWke7wiLEM9M4pPz60A/KSckskiona67tXcqOLXb8N18TKaNCKHv0Ce+GyEKK5+MT7e1vao=";
//string encrypt = RSAEncrypt("", "chenhailong");
byte[] encrypt = RSAEncrypt("APP_IDA2018030910304500031ENV_FLAG0REQ_SERIAL_NO20170310155124REQ_TIME20170310155124");
string name = RSADecrypt(encrypt);
//string name = RSADecrypt(Convert.FromBase64String(de));
Console.WriteLine(encrypt.Length);
Console.WriteLine(Convert.ToBase64String(encrypt));
Console.WriteLine(name);
Console.ReadKey();
} /// <summary>
/// RSA encrypt
/// </summary>
/// <param name="publickey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static byte[] RSAEncrypt(string content)
{
string publickey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>"; string pKey = @"-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2TSwydOrZ0Ija3YbloMWXQP6x
OIn1DUOiOHCYJkRYTk+FviR+P6EOOSwPLFcd91k65jHZOF91pifQf6tHzFQjhc0p
hTGWsjpHPhGeJ6tgzSZr5xIQmCp4xPW4x7N0Y1vciz3ZBfTZyMu2k3iHgbxT8uPe
KDKD2vZhC0FEOVU0oQIDAQAB
-----END PUBLIC KEY-----";
string pk= EncryptionHelper.RSA_KeyJavaToCsharp(pKey, false);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(pk);
cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false); //return Convert.ToBase64String(cipherbytes);
return cipherbytes;
} /// <summary>
/// RSA decrypt
/// </summary>
/// <param name="privatekey"></param>
/// <param name="content"></param>
/// <returns></returns>
public static string RSADecrypt(byte[] content)
{
string privatekey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>"; string priK = @"-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC2TSwydOrZ0Ija3YbloMWXQP6xOIn1DUOiOHCYJkRYTk+FviR+
P6EOOSwPLFcd91k65jHZOF91pifQf6tHzFQjhc0phTGWsjpHPhGeJ6tgzSZr5xIQ
mCp4xPW4x7N0Y1vciz3ZBfTZyMu2k3iHgbxT8uPeKDKD2vZhC0FEOVU0oQIDAQAB
AoGAarwma2he9KaO6i4XxCxsY9GPDW3///UDK2CGM9771wQKtVCNh0lz36MDs+KP
IyFmIgETII5L/dMJrp6BRylP/PsWWQAZqfoI7FQbKFWKnvTGhDxCtW7FvZOq9MhG
VMA5BfdE4zBgauo9kYdqzsKxIzndE5EJg4j86pFZwn6BWb0CQQDjWnoh25AXEHhw
Fo5Gd0N5aceK4uFQ5DukTUSH1y5b/z4Q5OvC3JopjUMVfDYk32C+sSw3zF9PuCK8
XmIE476rAkEAzUV/P6onzngqIiXPtpd5EuDKDM+4pvxJine7+2onY3rCtA1LFaLn
laIrAQ/2/b0Ub4cJMNxID4v1WDfBYo1p4wJADe2qE87uuesBZeSL3NdLo/GODv0t
TpZc7QjqzOOq7GnrtH9BzlNTgn4sAPH2IzYoKCaUjeqQYELopd+mY6RMNwJAJO8s
RjhHkU7txdcn2KLIliz8LfHyN5mNYezJViNzkuKzxdHegLYfFT1on3hP6LfsxWR2
suPv01xLeOQPV7w6IQJAO/bB2Ul7hRAgyHzlBMZoVEMY4LGfd41yDzrrpNjr2JUT
dsrXPbduLGGEdqE4M4uM/T+Vg3elAWM+eW7tGD2v5w==
-----END RSA PRIVATE KEY-----";
string pk = EncryptionHelper.RSA_KeyJavaToCsharp(priK, true);
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(pk);
cipherbytes = rsa.Decrypt(content, false); return Encoding.UTF8.GetString(cipherbytes);
}
}
}

将java密钥转换为c#密钥方法:

        ///RSA秘钥
///是否为RSA私钥:true:是|false:否
///
public static string RSA_KeyJavaToCsharp(string rsakeys, bool isPrivateKey)
{
try
{
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var streamReader = new StreamReader(memoryStream))
{
streamWriter.Write(rsakeys);
streamWriter.Flush();
memoryStream.Position = ;
var pemReader = new PemReader(streamReader);
object keys = pemReader.ReadObject();
RSA rsaservice = isPrivateKey ? GetPrivateRSACSharp(keys) : GetPublicRSACsharp(keys);
return rsaservice.ToXmlString(isPrivateKey);
}
}
catch (Exception ex)
{
throw new Exception("Asymmetric cipher key is error");
}
} /// /// 传入RSA秘钥对象返回读取秘钥后的RSA对象
/// ///RSA私钥
///
private static RSA GetPrivateRSACSharp(object rsakeys)
{
//根据传入对象 强制转化为需要的对象 提供已经读取私钥的RSA对象
if ((rsakeys as RsaPrivateCrtKeyParameters) != null)
return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)rsakeys);
var keys = (AsymmetricCipherKeyPair)rsakeys;
return DotNetUtilities.ToRSA((RsaPrivateCrtKeyParameters)keys.Private);
} /// /// 传入RSA秘钥对象返回读取秘钥后的RSA对象
/// ///RSA公钥
///
private static RSA GetPublicRSACsharp(object rsakeys)
{
//提供已经读取公钥钥的RSA对象
var keys = (RsaKeyParameters)rsakeys;
return DotNetUtilities.ToRSA(keys);
}

签名的方法:

        ///

        /// RSA C# 填充签名
/// ///私钥
///待签名字符串
///编码对象
///加密算法
///
public static string RSA_GetSignCsharp(string privateKey, string body, Encoding encoding, EncryptType encryptType = EncryptType.MD5)
{
try
{
using (RSACryptoServiceProvider rsaservice = new RSACryptoServiceProvider())
{
rsaservice.FromXmlString(privateKey);
RSAPKCS1SignatureFormatter rsasignformatter = new RSAPKCS1SignatureFormatter(rsaservice);
rsasignformatter.SetHashAlgorithm(encryptType.ToString());
encoding = encoding ?? Encoding.UTF8;
byte[] hashBytes = GetComputeHash(body, encoding, encryptType);
byte[] signBytes = rsasignformatter.CreateSignature(hashBytes);
return Convert.ToBase64String(signBytes);
}
}
catch (Exception ex)
{
throw ex;
}
} /// /// 根据编码及Hash类型计算Hash值
/// ///待计算Hash值得字符串
///编码对象
///Hash类型
///
public static byte[] GetComputeHash(string body, Encoding encoding, EncryptType encryptType)
{
encoding = encoding ?? Encoding.UTF8;
byte[] sourceBytes = encoding.GetBytes(body);
return GetComputeHash(sourceBytes, encryptType);
}

校验签名方法:

        ///

        /// RSA C# 验证签名
/// ///公钥
///待验证数据
///签名结果
///编码 可传NULL
///签名时加密方式 可传NULL
///
public static bool RSA_GetVerifyCsharp(string publicKey, string body, string signature, Encoding encoding, EncryptType encryptType = EncryptType.MD5)
{
try
{
using (RSACryptoServiceProvider rsaservice = new RSACryptoServiceProvider())
{
rsaservice.FromXmlString(publicKey);//加载公钥
RSAPKCS1SignatureDeformatter rsasignformatter = new RSAPKCS1SignatureDeformatter(rsaservice);
rsasignformatter.SetHashAlgorithm(encryptType.ToString());//设置算法
encoding = encoding ?? Encoding.UTF8;
var dataBytes = GetComputeHash(body, encoding, encryptType);
var signBytes = Convert.FromBase64String(signature);
return rsasignformatter.VerifySignature(dataBytes, signBytes);
}
}
catch (Exception ex)
{
throw ex;
}
}

最后按照java代码来翻译代码也没有成功,就用IKVM将jar包转换为dll终于达到目的。

第一步:将java代码打包,我这里用的idea打的包,百度下都有,这里不重复介绍。

https://www.cnblogs.com/qifengshi/p/6036870.html

https://jingyan.baidu.com/article/7e4409531fbf292fc1e2ef51.html

第二步:将jar包转换为dll。

转的步骤:https://www.cnblogs.com/rucwxb/p/7494586.html

这里要注意下:IKVM一定要用最新版本8.1.7版本,才能转java8,开始用的7.2版本,怎么转引用包都出问题。

第三步:将dll引用。

RSA加密、解密、签名、校验签名的更多相关文章

  1. Cryptopp iOS 使用 RSA加密解密和签名验证签名

    Cryptopp 是一个c++写的功能完善的密码学工具,类似于openssl 官网:https://www.cryptopp.com 以下主要演示Cryptopp 在iOS上的RSA加密解密签名与验证 ...

  2. RSA 加密 解密 公钥 私钥 签名 加签 验签

    http://blog.csdn.net/21aspnet/article/details/7249401# http://www.ruanyifeng.com/blog/2013/06/rsa_al ...

  3. openssl 非对称加密 RSA 加密解密以及签名验证签名

    1. 简介 openssl  rsa.h 提供了密码学中公钥加密体系的一些接口, 本文主要讨论利用rsa.h接口开发以下功能 公钥私钥的生成 公钥加密,私钥解密 私钥加密,公钥解密 签名:私钥签名 验 ...

  4. Java使用RSA加密解密签名及校验

    RSA加密解密类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...

  5. iOS使用Security.framework进行RSA 加密解密签名和验证签名

    iOS 上 Security.framework为我们提供了安全方面相关的api: Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,10 ...

  6. C#的RSA加密解密签名,就为了支持PEM PKCS#8格式密钥对的导入导出

    差点造了一整个轮子 .Net Framework 4.5 里面的RSA功能,并未提供简单对PEM密钥格式的支持(.Net Core有咩?),差点(还远着)造了一整个轮子,就为了支持PEM PKCS#8 ...

  7. RSA加密解密及RSA签名和验证及证书

    RSA加密解密及RSA签名和验证及证书 公钥是给别人的 发送密文使用公钥加密 验证签名使用公钥验证 私钥是自己保留的 接受密文使用私钥解密 发送签名使用私钥签名 上述过程逆转是不行的,比如使用私钥加密 ...

  8. 【转】C#中RSA加密解密和签名与验证的实现

    [转]C#中RSA加密解密和签名与验证的实现 RSA加密算法是一种非对称加密算法.在公钥加密标准和电子商业中RSA被广泛使用.RSA是1977年由罗纳德•李维斯特(Ron Rivest).阿迪•萨莫尔 ...

  9. RSA加密解密及RSA签名和验证

    原文:RSA加密解密及RSA签名和验证 1.RSA加密解密: (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密2.RSA签名和验证 (1)获取密钥,这里是 ...

  10. RSA加密解密及数字签名Java实现--转

    RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院 ...

随机推荐

  1. Header Only Library

    什么是Header Only Library Header Only Library把一个库的内容完全写在头文件中,不带任何cpp文件. 这是一个巧合,决不是C++的原始设计. 第一次这么做估计是ST ...

  2. 理解java中的值传递与“引用传递”

    额....java中其实没有引用传递 对于引用类型 ,在调用方法后,直接拷贝了引用的副本,但是它们指向了相同的堆地址,所以看起来像引用传递,但其实是值传递,只不过传递的引用的副本. 说一说为什么Str ...

  3. 【C#】CLR内存那点事(初级)

    最近回头看了一下书,对内存的理解又有新的认识.我所关注的内存里面说没有寄存器的,所以我关注的只有 托管堆(heap),栈(stack), 字符串常量池(string是一个很特殊的对象) 首先我们看两个 ...

  4. Azure SQL作業

    由於要定期去刪除比較久的資料,礙於Azure SQL DB目前無法直接創建作業,目前找到一種方式就是通過local的SQL SERVER來執行AZURE SQL指令. 步驟如下: SQL Server ...

  5. 阿里 vs. 腾讯,谁的收购更有眼光?

    近年来我们国内企业高速发展,各大集团纷纷收购其他公司发展自己,在这么多的集团收购里面尤其以阿里巴巴和腾讯的收购引人注目.在2014年里阿里巴巴先后投资了中信,美国奢侈品电子商务lstdibs,高德,优 ...

  6. C# 操作 MongoDB

    今项目使用Mongodb,C#操作MongoDB使用MongoDB.Driver.dll库(Nuget),写了个小Demo,如下: using System; using System.Collect ...

  7. 从头开始学eShopOnContainers——设置WebSPA单页应用程序

    一.简介 Web SPA单页应用程序需要一些额外的步骤才能使其工作,因为它需要在生成Docker镜像之前构建JavaScript框架依赖项和JS代码. 二.安装基础环境 1.安装NPM 为了能够使用n ...

  8. 倍增求lca(模板)

    定义LCA,最近公共祖先,是指一棵树上两个节点的深度最大的公共祖先.也可以理解为两个节点之间的路径上深度最小的点.我们这里用了倍增的方法求了LCA.我们的基本的思路就是,用dfs遍历求出所有点的深度. ...

  9. 将某个类封装成XML形式返回

    <?xml version="1.0" encoding="GBK" standalone="no"?><package& ...

  10. Google浏览器历史版和下载地址

    Google浏览器历史版本下载地址https://www.slimjet.com/chrome/google-chrome-old-version.php google webdriver下载地址分享 ...