前段时间做东西做的很杂,现在从新整理归类下,以便于进一步加深知识点。
针对于RSA签名来说,首先需要公钥,私钥
我现在用的是PKCS1格式的公钥私钥,也就是密钥格式为非Java适用的
1:生成公钥私钥,我直接使用的是支付宝官网上下载的RSA签名/验签的工具。
string privateKeyPem = "MIIEpAIBAAKCAQEAxEZE8RRghiP/IKw36x8L9qOX3RE1pU70A+4KirahmUJQrhQ2ow8e09gZkkeRnKKZA5fwq94x8rIW1IN06iAgbAax5H7Q6rUniBp672eEvxbCzp2p6kT7D/lcqlzLDBUO/fCGr2HXHc1L1DHkv4fCS58ac82IzVQ1ZS5S+m+awBXaKstf84MbRIFPcg8YkLGLC7YIqYzGtHWg5ksF1HK8uIEBZUxT9932VuNrR9j/QBB6yT06/BvTrdf0R7iIAklmELbZL8l/IRpNVqMEsvgzw/Tl6KI3FfiN5/kC0oe9dXWn8iwYb4jlu/gSADQNrpd93YoRMQg1i+uGgaIh8yiX/wIDAQABAoIBAFzfr1GwRbhToi6wr0kXiM6tPHgD47GUOYz+f4iBwNfHdGva7rubtQejEv6P1QwcOHFl3SFGY7YmpPzsM09x4kWbqWOoymy1Sb5yYUeVYVAWkhm4qyVKfM5jPYDzpbTS5iQtQ14L2wGkGkSPU2F5+OtVnuu7Dwex2A5HrEYKt1w6Zpv10uT1RLcpYWwRV6c+5RTQIgc92VXdqDZ9fZuqAhO86K2ypNkpalv9+sAzDUKzNyO05qHmbNTAVKmudY4rLfEl9TRqmFMIor5yRNdieX2/QE0kLdUb+gwdiFdgkKg+ERT8RLB878l+jtjtJk6q3MYd5yTmurfnnsRvMHeCtoECgYEA6CoO5KvVoX8dnk3cS57Y6QkqGC/00CoDBJoNse36LYaMu85/W49K5RiZNCB3SLvqKGJkHLaNX4qVj6MScb4yr5ZDlSE2vY5FNgLih8MTbK9stkOLl0ut53fMPlwEmyOm+/mdJxumbskuy90ox50Z3RpDBXUiq2bp1wTUlhT8fEECgYEA2GzsqwE14MIxouGOglixQuvkjSEsgmsNsNwx71GEuKeOlOY+1DP8sh20Pxw9J8l20av8Cv1GJi7bQiDawtN9qWQnai0Rw3eQ5bRxtxSzYUSN4brLoGHXSIkGu3UTnXrBS7czFym4cZhyiu5ici1RQMOV6+dehZMA4zBgkjXVBD8CgYEArR43jtKHcW5dQp8ihw0DB/o6dmDEN7ksGPFbBvPCmtH6/UxE8ZxPJ7gI/bK73/On7sc3iaWik7y+O6ZI6aH/H6l36asjq4N8HoNWMhAH2wKQmPSTEZVwLurI1TM+iAS0zq3aPsBCgdfo2kGm1/pQv+uGUHqBCLir5BcJAoTRpUECgYBHfFsD9Odl8N7STSx0M3WBhEc+snlwLoocI+8+fC+ZiobW+eJA11cdQiB6RAqTLMFZajRbMONN02ZKxm1bst2r6M/4CyD17nVm2h5Bec3yT+GJcNi3hfnFFLWrj3VGK/jS2JVAjmBE7TTQXQMZcYyIFtJbVFXtSuwdHqqXQL62owKBgQCWQcCmRNu8hTve8qUrY/qcpOThAw2jEzW4UYW9PcwaMbv8pffEFBnyUhuEdXI5BP7bEBLgPfYZofinqvDLl+5sMfZt8kvN3AE14T2bAKRU11/25gK+y32wVIwk497UF2G0YtIbozu5HqMHU+elxawJJQ/5C+SrpjEOC6Hj5jrNYg==";
string publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxEZE8RRghiP/IKw36x8L9qOX3RE1pU70A+4KirahmUJQrhQ2ow8e09gZkkeRnKKZA5fwq94x8rIW1IN06iAgbAax5H7Q6rUniBp672eEvxbCzp2p6kT7D/lcqlzLDBUO/fCGr2HXHc1L1DHkv4fCS58ac82IzVQ1ZS5S+m+awBXaKstf84MbRIFPcg8YkLGLC7YIqYzGtHWg5ksF1HK8uIEBZUxT9932VuNrR9j/QBB6yT06/BvTrdf0R7iIAklmELbZL8l/IRpNVqMEsvgzw/Tl6KI3FfiN5/kC0oe9dXWn8iwYb4jlu/gSADQNrpd93YoRMQg1i+uGgaIh8yiX/wIDAQAB";
string signType = "RSA2";
记得要对公钥私钥去空格换行操作哦
2:生成待签字符串
//待签集合
Dictionary<string, string> ParamInfo = new Dictionary<string, string>();
ParamInfo.Add("timestamp","20191112135000");
ParamInfo.Add("noncestr","123sdsf");
ParamInfo.Add("name", "张三");
//对报文中出现签名域(signature)之外的所有数据元按照key的ascii顺序排序,然后以&作为连接符拼接成待签名串。
string signContent = SignUtil.GetSignContent(ParamInfo);
3:签名
string signatureNew = string.Empty;
signatureNew = SignUtil.RSASignCharSet(signContent, privateKeyPem, null, false, signType);
4:验签-不在签名步骤内。。。
bool check = false;
check = SignUtil.RSACheck(signContent, signatureNew, publicKey, null, false, signType);
check 为true 标识验签成功,false 表示 失败。
5:把签名放入报文集合中!这样整个报文才算签名完成。
签名所需要的类SignUtil (支持RSA,RSA2的签名及验签)
public class SignUtil
{
/** 默认编码字符集 */
private static string DEFAULT_CHARSET = "UTF-8";
/// <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 = query.ToString().Substring(0, query.Length - 1);
return content;
}
/// <summary>
/// 签名
/// </summary>
/// <param name="parameters">待签集合</param>
/// <param name="privateKeyPem">私钥 默认为文件</param>
/// <param name="charset">编码类型 默认为UTF-8</param>
/// <param name="signType">签名类型 RSA、RSA2</param>
/// <returns></returns>
public static string RSASign(IDictionary<string, string> parameters, string privateKeyPem, string charset, string signType)
{
string signContent = GetSignContent(parameters);
return RSASignCharSet(signContent, privateKeyPem, charset, signType);
}
/// <summary>
/// 签名
/// </summary>
/// <param name="data">待签字符串</param>
/// <param name="privateKeyPem">私钥</param>
/// <param name="charset">编码类型 默认为UTF-8</param>
/// <param name="signType">签名类型 RSA、RSA2</param>
/// <returns></returns>
public static string RSASign(string data, string privateKeyPem, string charset, string signType)
{
return RSASignCharSet(data, privateKeyPem, charset, signType);
}
/// <summary>
/// 签名
/// </summary>
/// <param name="parameters">待签集合</param>
/// <param name="privateKeyPem">私钥</param>
/// <param name="charset">编码类型 默认为UTF-8</param>
/// <param name="keyFromFile">私钥类型 true:文件读取;false:字符串读取</param>
/// <param name="signType">签名类型 RSA、RSA2</param>
/// <returns></returns>
public static string RSASign(IDictionary<string, string> parameters, string privateKeyPem, string charset, bool keyFromFile, string signType)
{
string signContent = GetSignContent(parameters);
return RSASignCharSet(signContent, privateKeyPem, charset, keyFromFile, signType);
}
public static string RSASignCharSet(string data, string privateKeyPem, string charset, string signType)
{
RSACryptoServiceProvider rsaCsp = LoadCertificateFile(privateKeyPem, signType);
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{