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