C#使用Java的秘钥对进行SHA256withRSA签名验签

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Security.Cryptography;
using System.Text;
using System.Xml;

/// <summary>
/// RSA私钥,从Java格式转.net格式(不依赖第三方包)
/// </summary>
/// <param name="privateKey">私钥</param>
/// <returns></returns>
public static string RSAPrivateKeyJava2DotNet(string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
}

/// <summary>
/// 私钥签名
/// </summary>
/// <param name="contentForSign"></param>
/// <param name="privateKey"></param>
/// <returns></returns>
public static string Sign(string contentForSign, string privateKey)
{
var netKey = RSAPrivateKeyJava2DotNet(privateKey); //转换成适用于.net的私钥

var rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(netKey);

var rsaClear = new RSACryptoServiceProvider();
var paras = rsa.ExportParameters(true);
rsaClear.ImportParameters(paras); //签名返回
using (var sha256 = new SHA256CryptoServiceProvider())
{
var signData = rsa.SignData(Encoding.UTF8.GetBytes(contentForSign), sha256);
return Convert.ToBase64String(signData);
}
}


/// <summary>
/// RSA公钥,从Java格式转.net格式(不依赖第三方包)
/// </summary>
/// <param name="publikKey"></param>
/// <returns></returns>
public static string RSAPublicKeyJava2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
}

/// <summary>
/// RSA公钥格式转换,.net->java
/// </summary>
/// <param name="publicKey">.net生成的公钥</param>
/// <returns></returns>
public string RSAPublicKeyDotNet2Java(string publicKey)
{
XmlDocument doc = new XmlDocument(); doc.LoadXml(publicKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
RsaKeyParameters pub = new RsaKeyParameters(false, m, p);
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
return Convert.ToBase64String(serializedPublicBytes);
}

/// <summary>
/// RSA私钥格式转换,.net->java
/// </summary>
/// <param name="privateKey">.net生成的私钥</param>
/// <returns></returns>
public string RSAPrivateKeyDotNet2Java(string privateKey)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(privateKey);
BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));
RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
return Convert.ToBase64String(serializedPrivateBytes);
}

 

/// <summary>
/// RSA签名验证
/// </summary>
/// <param name="encryptSource">签名</param>
/// <param name="c">验证的字符串</param>
/// <param name="publicKey">公钥</param>
/// <returns>是否相同,true验证成功,false验证失败。</returns>
public static bool VerifySignature(string encryptSource, string compareString, string publicKey)
{
try
{
using (RSACryptoServiceProvider rsa = FromXmlString(RSAPublicKeyJava2DotNet(publicKey)))
{
//rsa.FromXmlString(RSAPrivateKeyJava2DotNet(publicKey)); .net core3.0直接使用,不需要重写
byte[] signature = Convert.FromBase64String(encryptSource);
SHA256Managed sha256 = new SHA256Managed();
RSAPKCS1SignatureDeformatter df = new RSAPKCS1SignatureDeformatter(rsa);
df.SetHashAlgorithm("SHA256");
byte[] compareByte = sha256.ComputeHash(Encoding.UTF8.GetBytes(compareString));

return df.VerifySignature(compareByte, signature);
}
}
catch (Exception)
{
return false;
}
}


/// <summary>
/// 重写FromXmlString方法
/// </summary>
/// <param name="xmlString"></param>
/// <returns></returns>
public static RSACryptoServiceProvider FromXmlString(string xmlString)
{
var rsa = new RSACryptoServiceProvider();
RSAParameters parameters = new RSAParameters();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlString);
if (xmlDoc.DocumentElement.Name.Equals("RSAKeyValue"))
{
foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
{
switch (node.Name)
{
case "Modulus": parameters.Modulus = Convert.FromBase64String(node.InnerText); break;
case "Exponent": parameters.Exponent = Convert.FromBase64String(node.InnerText); break;
case "P": parameters.P = Convert.FromBase64String(node.InnerText); break;
case "Q": parameters.Q = Convert.FromBase64String(node.InnerText); break;
case "DP": parameters.DP = Convert.FromBase64String(node.InnerText); break;
case "DQ": parameters.DQ = Convert.FromBase64String(node.InnerText); break;
case "InverseQ": parameters.InverseQ = Convert.FromBase64String(node.InnerText); break;
case "D": parameters.D = Convert.FromBase64String(node.InnerText); break;
}
}
}
else
{
throw new Exception("Invalid XML RSA key.");
}

rsa.ImportParameters(parameters);
return rsa;
}

//生成.net   xml   公钥  私钥

public string RsaSign(string data, string privatekey)
{
CspParameters CspParameters = new CspParameters();
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048, CspParameters);
byte[] bytes = Encoding.UTF8.GetBytes(data);
privatekey = RSA.ToXmlString(true);
var publickey=RSA.ToXmlString(false);
RSA.FromXmlString(privatekey);
byte[] sign = RSA.SignData(bytes, "SHA256");

return Convert.ToBase64String(sign);
}

 

posted @   L_L-J  阅读(1065)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示