using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
/// <summary>
/// 将参数组成代签名的字符串
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
public static string GetSignContent(IDictionary<string, string> parameters)
{
// 第一步:把字典按Key的字母顺序排序
IDictionary<string, string> sortedParams = new SortedDictionary<string, string>(parameters);
IEnumerator<KeyValuePair<string, string>> dem = sortedParams.GetEnumerator();
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder("");
while (dem.MoveNext())
{
string key = dem.Current.Key;
string value = dem.Current.Value;
if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
{
query.Append(key).Append("=").Append(value).Append("&");
}
}
//第三步:判断参数是否有值
string content = null;
if (query != null)
{
content = query.ToString().Substring(0, query.Length - 1);
}
return content;
}
/// <summary>
/// C#生成私钥加密
/// </summary>
/// <param name="data"></param>
/// <param name="privatekey"></param>
/// <returns></returns>
public static string RSADecrypt(string data, string privatekey)
{
var rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privatekey);
var rsaClear = new RSACryptoServiceProvider();
var paras = rsa.ExportParameters(true);
rsaClear.ImportParameters(paras); //签名返回
using (var sha256 = new SHA256CryptoServiceProvider())
{
var signData = rsa.SignData(Encoding.UTF8.GetBytes(data), sha256);
return Convert.ToBase64String(signData);
}
}
/// RSA签名验证
/// </summary>
/// <param name="encryptSource">签名</param>
/// <param name="c">验证的字符串</param>
/// <param name="publicKey">公钥</param>
/// <returns>是否相同,true验证成功,false验证失败。</returns>
public static bool Signature(string encryptSource, string compareString, string publicKey)
{
try
{
using (RSACryptoServiceProvider rsa = FromXmlString(publicKey))//
//using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
//rsa.FromXmlString(publicKey);.net Core 在3.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;
}
public static void Main(string[] args)
{
Console.WriteLine("你喜欢什么动漫?");
string like = Console.ReadLine();
Console.WriteLine("其中喜欢角色的名字为什么?");
string name = Console.ReadLine();
Console.WriteLine("你喜欢的动漫角色穿黑丝吗?");
string blackSilk = Console.ReadLine();
var content = new Dictionary<string, string>()
{
{"like",$"{like}"},
{"name",$"{name}"},
{"blackSilk",$"{blackSilk}"}
};
//生成待签名字符串
string Data = GetSignContent(content);
//生成秘钥对
RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
string str_Private_Key = RSAalg.ToXmlString(true);
string str_Public_Key = RSAalg.ToXmlString(false);
//生成签名
string netSings = RSADecrypt(Data, str_Private_Key);
//验签
bool attes = Signature(netSings, Data, str_Public_Key);
Console.WriteLine(attes);
Console.WriteLine("Hello World!", attes);
}