.net rsa公钥解密

abcde760 2014-04-22 02:27:27
.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;
}
}
}
...全文
336 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
abcde760 2014-04-23
  • 打赏
  • 举报
回复
谢谢,有点不太懂,还要再研究研究,顺便问一下有人知道.net怎么调用PHP里的函数吗?
md5e 2014-04-22
  • 打赏
  • 举报
回复
公钥只能验证私钥的加密不能进行解密
zhujiazhi 2014-04-22
  • 打赏
  • 举报
回复
.net 自带的RSACryptoServiceProvider是不支持私钥加密,公钥进行解密的 网上有自己实现的,不过没有去研究过的 如果LZ找到就分享一下吧
面向工程应用:市面上的一些密码学课程和密码学的书籍,很多都是从考证出发,讲解算法原理并不面向工程应用,而我们现在缺少的是工程应用相关的知识,本课程从工程应用出发,每种技术都主要讲解其在工程中的使用,并演示工程应用的代码。 从零实现部分算法: 课程中实现了base16编解码 ,XOR对称加解密算法,PKCS7 pading数据填充算法,通过对一些简单算法的实现,从而加深对密码学的理解。理论与实践结合: 课程如果只是讲代码,同学并不能理解接口背后的原理,在项目设计中就会留下隐患,出现错误也不容易排查出问题。如果只讲理论,比如对密码学的一些研究,对于大部分从事工程应用的同学并没有必要,而是理论与实践结合,一切为了工程实践。代码现场打出: 代码不放在ppt而是现场打出,更好的让学员理解代码编写的逻辑,老师现场敲出代码正是展示出了工程项目的思考,每个步骤为什么要这么做,考虑了哪些异常,易学不枯燥: 课程为了确保大部分人开发者都学得会,理解算法原理(才能真正理解算法特性),学会工程应用(接口调用,但不局限接口调用,理解接口背后的机制,并能解决工程中会出现的问题),阅读算法源码但不实现密码算法,,并能将密码学投入到实际工程中,如果是想学习具体的加密算法实现,请关注我后面的课程。

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧