.net rsa公钥解密
.net 有给定的密文和公钥,怎么用rsa公钥来解密?
给定的密文: string en = "V/5/99ubmARZ0uOT/KOBrOdns/91mm23mAGDvfvgJjhG36/R82QaaEQrD7+vIR7850Hx03wZr7QcdIy2CGiEB+p5lgKDjU8FAQAjwLxqIWNT0T8ugdwGiMI3pC/SKlY3I0mKtoN78YNIgFLWA5QM0xSWvjls5p7hLbs4cZz6Oe4=";
给定的公钥: string toXmlPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6IB26O/Elia0G3ccaQhub2XNQPUfdRolnpNDdfh5mehb0VoOHP3EoVpsRgsVEpPfIFw/XtaZX3CfwC4Dp5aq0uZolTd+Lk7t+EKV/xQ+voDexN3u4MZLsGUW+p/VYAkajING//U8cIkEBws6Rk+ZDZVhrz+p+aBsXAY3XVCpU2QIDAQAB";
解密的代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace RSATest
{
/// <summary>
/// 非对称RSA加密类 可以参考
/// http://www.cnblogs.com/hhh/archive/2011/06/03/2070692.html
/// http://blog.csdn.net/zhilunchen/article/details/2943158
/// 若是私匙加密 则需公钥解密
/// 反正公钥加密 私匙来解密
/// 需要BigInteger类来辅助
/// </summary>
public static class RSAHelper
{
/// <summary>
/// RSA的容器 可以解密的源字符串长度为 DWKEYSIZE/8-11
/// </summary>
public const int DWKEYSIZE = 1024;
/// <summary>
/// RSA加密的密匙结构 公钥和私匙
/// </summary>
public struct RSAKey
{
public string PublicKey { get; set; }
//public string PrivateKey { get; set; }
}
#region 得到RSA的解谜的密匙对
/// <summary>
/// 得到RSA的解谜的密匙对
/// </summary>
/// <returns></returns>
public static RSAKey GetRASKey()
{
string toXmlPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6IB26O/Elia0G3ccaQhub2XNQPUfdRolnpNDdfh5mehb0VoOHP3EoVpsRgsVEpPfIFw/XtaZX3CfwC4Dp5aq0uZolTd+Lk7t+EKV/xQ+voDexN3u4MZLsGUW+p/VYAkajING//U8cIkEBws6Rk+ZDZVhrz+p+aBsXAY3XVCpU2QIDAQAB";
byte[] publicKey = Encoding.Default.GetBytes(toXmlPublicKey);
byte[] exponent = { 1, 0, 1 };
RSACryptoServiceProvider.UseMachineKeyStore = true;
//声明一个指定大小的RSA容器
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(DWKEYSIZE);
//取得RSA容易里的各种参数
RSAParameters RSAKeyInfo = new RSAParameters();
RSAKeyInfo.Modulus = publicKey;
RSAKeyInfo.Exponent = exponent;
rsaProvider.ImportParameters(RSAKeyInfo);
return new RSAKey()
{
PublicKey = ComponentKey(RSAKeyInfo.Exponent, RSAKeyInfo.Modulus),
};
}
#endregion
#region 检查明文的有效性 DWKEYSIZE/8-11 长度之内为有效 中英文都算一个字符
/// <summary>
/// 检查明文的有效性 DWKEYSIZE/8-11 长度之内为有效 中英文都算一个字符
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static bool CheckSourceValidate(string source)
{
return (DWKEYSIZE / 8 - 11) >= source.Length;
}
#endregion
#region 组合解析密匙
/// <summary>
/// 组合成密匙字符串
/// </summary>
/// <param name="b1"></param>
/// <param name="b2"></param>
/// <returns></returns>
private static string ComponentKey(byte[] b1, byte[] b2)
{
List<byte> list = new List<byte>();
//在前端加上第一个数组的长度值 这样今后可以根据这个值分别取出来两个数组
list.Add((byte)b1.Length);
list.AddRange(b1);
list.AddRange(b2);
byte[] b = list.ToArray<byte>();
return Convert.ToBase64String(b);
}
/// <summary>
/// 解析密匙
/// </summary>
/// <param name="key">密匙</param>
/// <param name="b1">RSA的相应参数1</param>
/// <param name="b2">RSA的相应参数2</param>
private static void ResolveKey(string key, out byte[] b1, out byte[] b2)
{
//从base64字符串 解析成原来的字节数组
byte[] b = Convert.FromBase64String(key);
//初始化参数的数组长度
b1=new byte[b[0]];
b2=new byte[b.Length-b[0]-1];
//将相应位置是值放进相应的数组
for (int n = 1, i = 0, j = 0; n < b.Length; n++)
{
if (n <= b[0])
{
b1[i++] = b[n];
}
else {
b2[j++] = b[n];
}
}
}
#endregion
/// <summary>
/// 字符串解密
/// </summary>
/// <param name="encryptString">密文</param>
/// <param name="key">密钥</param>
/// <returns>遇到解密失败将会返回原字符串</returns>
public static string DecryptString(string encryptString, string key)
{
string source = string.Empty;
byte[] e;
byte[] n;
try
{
//解析这个密钥
ResolveKey(key, out e, out n);
BigInteger biE = new BigInteger(e);
BigInteger biN = new BigInteger(n);
source = Decrypt_str(encryptString, biE, biN);
}
catch (Exception exc){
Console.WriteLine(exc.Message);
source = encryptString;
}
return source;
}
#endregion
/// <summary>
/// 用指定的密匙加密
/// </summary>
/// <param name="source">密文</param>
/// <param name="e">可以是RSACryptoServiceProvider生成的Exponent</param>
/// <param name="n">可以是RSACryptoServiceProvider生成的Modulus</param>
/// <returns>返回明文</returns>
private static string Decrypt_str(string encryptString, BigInteger e, BigInteger n)
{
//StringBuilder result = new StringBuilder();
//string[] strarr1 = encryptString.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
//for (int i = 0; i < strarr1.Length; i++)
//{
// string block = strarr1[i];
// BigInteger biText = new BigInteger(block, 16);
// BigInteger biEnText = biText.modPow(e, n);
// string temp = System.Text.Encoding.UTF8.GetString(biEnText.getBytes());
// result.Append(temp);
//}
//return result.ToString();
int len = encryptString.Length;
int len1 = 0;
int blockLen = 0;
if ((len % 256) == 0)
len1 = len / 256;
else
len1 = len / 256 + 1;
string block = "";
string temp = "";
for (int i = 0; i < len1; i++)
{
if (len >= 256)
blockLen = 256;
else
blockLen = len;
block = encryptString.Substring(i * 256, blockLen);
//byte[] bl = Encoding.UTF8.GetBytes(block);
BigInteger biText = new BigInteger(block, 16);
BigInteger biEnText = biText.modPow(e, n);
string temp1 = System.Text.Encoding.Default.GetString(biEnText.getBytes());
temp += temp1;
len -= blockLen;
}
return temp;
}
#endregion
/// <summary>
/// 字符串转16进制
/// </summary>
/// <param name="source">字符串密文</param>
/// <returns>16进制数据</returns>
public static string StrToHex(string str)
{
string strTemp = "";
if (str == "")
return "";
byte[] bTemp = System.Text.Encoding.Default.GetBytes(str);
for (int i = 0; i < bTemp.Length; i++)
{
strTemp += bTemp[i].ToString("X");
}
return strTemp;
}
}
}