C# 实现MD5withRSA签名算法的加密
规则
签名算法:MD5withRSA
1.参数名ASCII码从小到大排序
2.如果参数的值为空(null 或者空字符串)不参与签名
3.参数名区分大小写
4.sign参数不参与签名
实现
1、引入BouncyCastle.Crypto类库

2、参数名ASCII码从小到大排序
使用Newtonsoft.Json序列化的JSON,除非人为指定排序规则,则默认为AsciiAsc排序方式。C# 使用Newtonsoft.Json进行对象序列化、JSON反序列化的方法
我们可以这么实现,示例代码:
2.1 json代码:
{
"nonceStr": "z0o66TGb08u10i8pwk5Rr",
"authAppKey": "Pny5BAdcrZH1KDSU2VbhAF",
"timestamp": "1668783983693"
}2.2 json转Dictionary<string, string>
string json = JSON串 var Attributes = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
使用Newtonsoft.Json的反序列化JsonConvert.DeserializeObject<Dictionary<string, string>>(json)转换为Dictionary<string, string>格式;
2.3 转换Dictionary<string, string>为特定格式
示例格式(AsciiAsc):
authAppKey=Pny5BAdcrZH1KDSU2VbhAF&nonceStr=z0o66TGb08u10i8pwk5Rr×tamp=1668783983693
转换方法(该方法可Ascii排序)
private static String AsciiAsc(Dictionary<String, String> dic)
{
//Ascii升序排序
var sortResult3 = from pair in dic orderby pair.Key ascending select pair;
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<String, String> p in sortResult3)
{
//格式化输出生成串
sb.Append(p.Key).Append("=").Append(p.Value).Append('&');
}
//去除末尾多余字符
string ls_str = sb.ToString();
ls_str = ls_str.Substring(0, ls_str.Length - 1);
return ls_str;
} private static String AsciiDesc(Dictionary<String, String> dic)
{
//Ascii降序排序
var sortResult3 = from pair in dic orderby pair.Key descending select pair;
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<String, String> p in sortResult3)
{
//格式化输出生成串
sb.Append(p.Key).Append("=").Append(p.Value).Append('&');
}
//去除末尾多余字符
string ls_str = sb.ToString();
ls_str = ls_str.Substring(0, ls_str.Length - 1);
return ls_str;
}4、MD5withRSA.cs 类库文件
using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
namespace UnifyPayPlatAPI.MD5withRSA
{
public class md5withRsa
{
public Encoding encoding = Encoding.GetEncoding("GBK");
public string SignerSymbol = "MD5withRSA";
public md5withRsa() { }
public md5withRsa(Encoding e, string s)
{
encoding = e;
SignerSymbol = s;
}
private AsymmetricKeyParameter CreateKEY(bool isPrivate, string key)
{
byte[] keyInfoByte = Convert.FromBase64String(key);
if (isPrivate)
return PrivateKeyFactory.CreateKey(keyInfoByte);
else
return PublicKeyFactory.CreateKey(keyInfoByte);
}
/// <summary>
/// 数据签名
/// </summary>
/// <param name="content">待加密字符串</param>
/// <param name="privatekey">私钥</param>
/// <returns>加密后字符串</returns>
public string SignMD5withRsa(string content, string privatekey)
{
ISigner sig = SignerUtilities.GetSigner(SignerSymbol);
sig.Init(true, CreateKEY(true, privatekey));
var bytes = encoding.GetBytes(content);
sig.BlockUpdate(bytes, 0, bytes.Length);
byte[] signature = sig.GenerateSignature();
//使用Base64转换sig,8-bit
var signedString = Convert.ToBase64String(signature);
return signedString;
}
/// <summary>
/// 验证签名
/// </summary>
/// <param name="content">待签名的字符串</param>
/// <param name="signData">加密后的文本</param>
/// <param name="publickey">公钥文本</param>
/// <returns>是否一致</returns>
public bool VerifyMD5withRsa(string content, string signData, string publickey)
{
ISigner signer = SignerUtilities.GetSigner(SignerSymbol);
signer.Init(false, CreateKEY(false, publickey));
var expectedSig = Convert.FromBase64String(signData);
var msgBytes = encoding.GetBytes(content);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(expectedSig);
}
}
}5、加密方式
using System;
using System.Text;
using System.Windows.Forms;
using UnifyPayPlatAPI.APIModels;
using UnifyPayPlatAPI.MD5withRSA;
namespace UnifyPayPlatAPI
{
public partial class ASCIIasc : Form
{
public ASCIIasc()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
md5withRsa withRsa = new md5withRsa();
richTextBox4.Text = withRsa.SignMD5withRsa(richTextBox2.Text, richTextBox3.Text);
}
}
}5.1 加密密钥
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIja1PySYfiBx5V+EEvJnM1WSI7SgH1QhqWILdgaXdBF2oIjPYURwb4znLuPFwWY11Uf38lWMV6lWjSTj9CqaRTnKHs4UoAGNVsgFqLmdvTkX6pTavm3OfGgozoCwJzCygcHfsCJjoAF1xCjmlyuWxMOvgXg0YxNoDK/eNu8u79lAgMBAAECgYAi2ASOYf7LtM9KApTHlwdzSFqk8neAcHY3wxpZAS2Nj5t4stxA+ypm8OEg5+empyl8JOdnbaiYPmVfKYreR+UE65mupm3IkcYftCV4TB2CW5EcmSOBPSV+8gK6u3k7U090FyII/FRIva0TsFhRjnGq14f/QntKvit/U/CizHKr6QJBAM+wvuby/rnd41SikctYztDPly6pqLsD1hBnixM3Nyx47RsR2hUlG09TSU0YsrZLkge7hso9vcs5DxVas3x+RMcCQQCosBF+/n8Qpl2WC2U/uivziVJZgAOerIxONI2b+86E/7RpGB4MnhfBzzXu8k7TGQbySO+KCMmbruMc+Fe72FZzAkA2BqwiN6O7hdTU91UlqHxkJRwWr1uNCnps2gJ7hSl9EBfdqs8oIPbxs6ClxX73nMDn8ggmI9lzO+yIiYeXIuGRAkB239z0iZQxv4uj+VPYnPHsJZGK0NO8NgyJ8C77BXB7+VbB2OUULzS+t69iPA+gY7qpcwybUaYBuDUEbV4mWkZRAkBRMcqilz+oh337VPfk4ozeHGnHbE7bnrJKTZy05Fb/m05QTkCpaart8UIiYxRJxfHfuHPwGVzaulLqoJCnNOdr
5.2 加密结果
YUZrkpRSuQgUvg4NTG6nzby2RRvaPoOw1D3rl8Co53+nMcYgQWsExHAWLUuSqqBzvtAIS3LolFJxQUAiEWve6syDNo1KAtT6veMRrD0Fjn9gMnrECanKF9otLJuPzsdhVPLDIkMLQxunAlbI2SWaB9H+0q+Rfo9bWS4VbHWJ1A8=
拓展:
在线验证工具
http://www.metools.info/code/c82.html

