写应用的时候遇到个服务器返回私钥加密过的数据 ,然后要在客户端用公钥解密的需求 ,一直没找到方法,应用搁置了一个学期,多方搜索,结论就是.net没有实现公钥解密的方法,要自己实现,于是硬着头皮开始看 portable.bouncycastle

关于RSA的原理,这是我从MSDN盗的图,链接在这https://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters.aspx

简单说就是

密文 = (明文 ^privateExponent) mod modulus

明文 = (密文 ^publicExponent) mod modulus

公钥中含有两个参数 一个是modulus ,另一个是publicExponent,私钥中有 modulus和privateExponent两个参数(当然私钥中不止这两个参数,但方法里只用到这两个,其他不管)

由于拿到的公钥和私钥都是PEM格式的,所以要先从PEM格式的公钥和私钥中提取这些参数 ,然后进行大数运算就能得出结果

这里要感谢前辈的努力,详细的解析了PEM文件格式

现在假设假设公钥和私钥分别为

      const string PUBLICKEY =
     @"-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpsDr+W45aFHIkvotZaGK/THlF
FpuZfUtghhWkHAm3H7yvL42J4xHrTr6IeUDCl4eKe6qiIgvYSNoL3u4SERGOeYmV
1F+cocu9IMGnNoicbh1zVW6e8/iGT3xaYQizJoVuWA/TC/zdds2ihCJfHDBDsouO
CXecPapyWCGQNsH5sQIDAQAB
-----END PUBLIC KEY-----";
const string PRIVATEKEY =
@"-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDpsDr+W45aFHIkvotZaGK/THlFFpuZfUtghhWkHAm3H7yvL42J
4xHrTr6IeUDCl4eKe6qiIgvYSNoL3u4SERGOeYmV1F+cocu9IMGnNoicbh1zVW6e
8/iGT3xaYQizJoVuWA/TC/zdds2ihCJfHDBDsouOCXecPapyWCGQNsH5sQIDAQAB
AoGBAM/JbFs4y5WbMncrmjpQj+UrOXVOCeLrvrc/4kQ+zgCvTpWywbaGWiuRo+cz
cXrVQ6bGGU362e9hr8f4XFViKemDL4SmJbgSDa1K71i+/LnnzF6sjiDBFQ/jA9SK
4PYrY7a3IkeBQnJmknanykugyQ1xmCjbuh556fOeRPaHnhx1AkEA/flrxJSy1Z+n
Y1RPgDOeDqyG6MhwU1Jl0yJ1sw3Or4qGRXhjTeGsCrKqV0/ajqdkDEM7FNkqnmsB
+vPd116J6wJBAOuNY3oOWvy2fQ32mj6XV+S2vcG1osEUaEuWvEgkGqJ9co6100Qp
j15036AQEEDqbjdqS0ShfeRSwevTJZIap9MCQCeMGDDjKrnDA5CfB0YiQ4FrchJ7
a6o90WdAHW3FP6LsAh59MZFmC6Ea0xWHdLPz8stKCMAlVNKYPRWztZ6ctQMCQQC8
iWbeAy+ApvBhhMjg4HJRdpNbwO6MbLEuD3CUrZFEDfTrlU2MeVdv20xC6ZiY3Qtq
/4FPZZNGdZcSEuc3km5RAkApGkZmWetNwDJMcUJbSBrQMFfrQObqMPBPe+gEniQq
Ttwu1OULHlmUg9eW31wRI2uiXcFCJMHuro6iOQ1VJ4Qs
-----END RSA PRIVATE KEY-----";

于是获取公钥参数的方法为

  // 获取modulus和publicExponent
string publicKey = PUBLICKEY.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
byte[] btPem = Convert.FromBase64String(publicKey);
int pemModulus = , pemPublicExponent = ;
byte[] btPemModulus = new byte[];
byte[] btPemPublicExponent = new byte[];
for (int i = ; i < pemModulus; i++)
{
btPemModulus[i] = btPem[ + i];
}
for (int i = ; i < pemPublicExponent; i++)
{
btPemPublicExponent[i] = btPem[ + i];
}

公钥解密的方法为

 BigInteger biModulus = new BigInteger(, btPemModulus);
BigInteger biExponent = new BigInteger(, btPemPublicExponent);
RsaKeyParameters publicParameters = new RsaKeyParameters(false, biModulus, biExponent);
IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());
eng.Init(false, publicParameters);
// 解密已加密的数据
byte[] encryptedData = Convert.FromBase64String(rawData);
encryptedData = eng.ProcessBlock(encryptedData, , encryptedData.Length);
string result = Encoding.UTF8.GetString(encryptedData, , encryptedData.Length);

公钥加密的方法为

 BigInteger biModulus = new BigInteger(, btPemModulus);
BigInteger biExponent = new BigInteger(, btPemPublicExponent);
RsaKeyParameters publicParameters = new RsaKeyParameters(false, biModulus, biExponent);
IAsymmetricBlockCipher eng = new Pkcs1Encoding(new RsaEngine());
eng.Init(true, publicParameters);
// 加密数据
byte[] encryptData = Encoding.UTF8.GetBytes(rawData);
encryptData = eng.ProcessBlock(encryptData, , encryptData.Length);
string result = Convert.ToBase64String(encryptData);

私钥的通过PEM文件格式详细解析里的图也可以方便的写出来,mark下以后写……( ̄o ̄) . z Z

顺便贴上WP 8.1里自带的RSA公钥加密 私钥解密

      /// <summary>
/// WPRT的RSA公钥加密
/// </summary>
/// <param name="rawData">源数据</param>
/// <returns>加密后的数据</returns>
public static string PublicEncrypt(string rawData)
{
try
{
/*将文本转换成IBuffer*/
IBuffer bufferRawData = CryptographicBuffer.ConvertStringToBinary(rawData, BinaryStringEncoding.Utf8); /*加密算法提供程序*/
AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm
(AsymmetricAlgorithmNames.RsaPkcs1); /*导入公钥*/
string PUBLIC_KEY = PUBLICKEY.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
CryptographicKey publicKey = provider.ImportPublicKey(CryptographicBuffer.DecodeFromBase64String(PUBLIC_KEY)); //加密
IBuffer result = CryptographicEngine.Encrypt(publicKey, bufferRawData, null);
byte[] res;
CryptographicBuffer.CopyToByteArray(result, out res);
Debug.WriteLine("WinRT公钥加密后:" + Convert.ToBase64String(res));
return Convert.ToBase64String(res);
}
catch (Exception e)
{
Debug.WriteLine("Encrypt Exception:" + e.StackTrace);
return rawData;
}
} /// <summary>
/// WPRT的RSA私钥解密
/// </summary>
/// <param name="rawData"></param>
/// <returns></returns>
public static string PrivateDecrypt(string rawData)
{
try
{
/*将文本转换成IBuffer*/
IBuffer bufferRawData = CryptographicBuffer.ConvertStringToBinary(rawData, BinaryStringEncoding.Utf8); /*加密算法提供程序*/
AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm
(AsymmetricAlgorithmNames.RsaPkcs1); /*导入私钥*/
string PRIVATE_KEY = PRIVATEKEY.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "");
CryptographicKey privateKey = provider.ImportKeyPair(CryptographicBuffer.DecodeFromBase64String(PRIVATE_KEY)); //解密
IBuffer result = CryptographicEngine.Decrypt(privateKey, bufferRawData, null);
byte[] res;
CryptographicBuffer.CopyToByteArray(result, out res);
Debug.WriteLine("WinRT私钥解密后:" + Encoding.UTF8.GetString(res,,res.Length));
return Encoding.UTF8.GetString(res,,res.Length);
}
catch (Exception e)
{
Debug.WriteLine("Decrypt Exception:" + e.StackTrace);
return rawData;
}
}

参考链接

PEM文件格式详细解析

BouncyCastle

[WP8.1开发]RSA 使用BouncyCastle 公钥解密的更多相关文章

  1. [WP8.1]RSA 使用BouncyCastle 公钥解密

    写应用的时候遇到个服务器返回私钥加密过的数据 ,然后要在客户端用公钥解密的需求 ,一直没找到方法,应用搁置了一个学期,多方搜索,结论就是.net没有实现公钥解密的方法,要自己实现,于是硬着头皮开始看  ...

  2. 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!

    最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...

  3. 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#

    前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...

  4. python使用rsa库做公钥解密(网上别处找不到)

    使用RSA公钥解密,用openssl命令就是openssl rsautl -verify -in cipher_text -inkey public.pem -pubin -out clear_tex ...

  5. RSA私钥加密公钥解密、各种密钥格式转换

    此随笔解决RSA加解密相关的3个问题,详情可以查看源码. 1.公钥加密.私钥解密2.各种格式RSA密钥之间的转换3.不限制加密原文的长度

  6. C++利用openssl进行公钥解密

    私钥加密的部分内容,需要用公钥解密下面的实例代码,由于私钥加密后的字符串有不可打印字符,所以程序里面进行了base64,要用的时候先解dec base64 再传递给函数 进行解密 #include & ...

  7. C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

    因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...

  8. NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密

    using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...

  9. RSA,JAVA私钥加密,C#公钥解密

    做这个东西在坑里爬了3天才爬出来,记录下供园友参考.C#程序员一枚,项目需要和Java做数据交互,对方甩了段密文和一个CER证书给我,然后我要对其密文进行解密. RSA 非对称加密,对方用私钥加密,我 ...

随机推荐

  1. getting started with transformjs

    Introduction In the past two years, more and more friends for mobile web development have used the t ...

  2. Laravel大型项目系列教程(三)之发表文章

    Laravel大型项目系列教程(三)之发表文章 一.前言 上一节教程中完成了用户管理,这节教程将大概完成发表Markdown格式文章并展示的功能. 二.Let's go 1.数据库迁移 文章模块中我们 ...

  3. JS 与OC 交互篇

    完美记录交互 CSDN博客: (OC调用JS) http://blog.csdn.net/lwjok2007/article/details/47058101 (JS调用OC) http://blog ...

  4. [Erlang 0113] Elixir 编译流程梳理

    注意:目前Elixir版本还不稳定,代码调整较大,本文随时失效      之前简单演示过如何从elixir ex代码生成并运行Erlang代码,下面仔细梳理一遍elixir文件的编译过程,书接上文,从 ...

  5. Linix登录报"/etc/profile: line 11: syntax error near unexpected token `$'{\r''"

    同事反馈他在一测试服务器(CentOS Linux release 7.2.1511)上修改了/etc/profile文件后,使用source命令不能生效,让我帮忙看看,结果使用SecureCRT一登 ...

  6. Spark——SparkContext简单分析

    本篇文章就要根据源码分析SparkContext所做的一些事情,用过Spark的开发者都知道SparkContext是编写Spark程序用到的第一个类,足以说明SparkContext的重要性:这里先 ...

  7. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  8. ERROR: Unable to globalize '/usr/local/NONE/etc/php-fpm.d/*.conf' 问题的解决

    今天继续作大死,趟php7的配置的坑. 照例,安装了昨天的各种扩展之后,解压php7的压缩文件到 /usr/local/. 然后开始配置config的扩展: ./configure --prefix= ...

  9. 项目实现不同环境不同配置文件-maven profile

    最近接触的项目都是在很多地方都落地的项目,需要支持不同的环境使用不同的配置文件.一直以来都以为是人工的去写不同的配置文件,手动的去修改运用的配置文件.感觉自己还是太low呀.maven的使用的还停留在 ...

  10. PHP求职宝典系列——PHP Web 编程篇

    PHP Web 编程篇 form表单 1.简述 POST 和 GET 传输的最大容量分别是多少? GET 方法提交的表单数据被附加到 URL 上,并作为URL 的一部分发送到服务器端. URL 的长度 ...