写应用的时候遇到个服务器返回私钥加密过的数据 ,然后要在客户端用公钥解密的需求 ,一直没找到方法,应用搁置了一个学期,多方搜索,结论就是.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文件格式

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

  1.      const string PUBLICKEY =
  2.      @"-----BEGIN PUBLIC KEY-----
  3. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpsDr+W45aFHIkvotZaGK/THlF
  4. FpuZfUtghhWkHAm3H7yvL42J4xHrTr6IeUDCl4eKe6qiIgvYSNoL3u4SERGOeYmV
  5. 1F+cocu9IMGnNoicbh1zVW6e8/iGT3xaYQizJoVuWA/TC/zdds2ihCJfHDBDsouO
  6. CXecPapyWCGQNsH5sQIDAQAB
  7. -----END PUBLIC KEY-----";
  8. const string PRIVATEKEY =
  9. @"-----BEGIN RSA PRIVATE KEY-----
  10. MIICXQIBAAKBgQDpsDr+W45aFHIkvotZaGK/THlFFpuZfUtghhWkHAm3H7yvL42J
  11. 4xHrTr6IeUDCl4eKe6qiIgvYSNoL3u4SERGOeYmV1F+cocu9IMGnNoicbh1zVW6e
  12. 8/iGT3xaYQizJoVuWA/TC/zdds2ihCJfHDBDsouOCXecPapyWCGQNsH5sQIDAQAB
  13. AoGBAM/JbFs4y5WbMncrmjpQj+UrOXVOCeLrvrc/4kQ+zgCvTpWywbaGWiuRo+cz
  14. cXrVQ6bGGU362e9hr8f4XFViKemDL4SmJbgSDa1K71i+/LnnzF6sjiDBFQ/jA9SK
  15. 4PYrY7a3IkeBQnJmknanykugyQ1xmCjbuh556fOeRPaHnhx1AkEA/flrxJSy1Z+n
  16. Y1RPgDOeDqyG6MhwU1Jl0yJ1sw3Or4qGRXhjTeGsCrKqV0/ajqdkDEM7FNkqnmsB
  17. +vPd116J6wJBAOuNY3oOWvy2fQ32mj6XV+S2vcG1osEUaEuWvEgkGqJ9co6100Qp
  18. j15036AQEEDqbjdqS0ShfeRSwevTJZIap9MCQCeMGDDjKrnDA5CfB0YiQ4FrchJ7
  19. a6o90WdAHW3FP6LsAh59MZFmC6Ea0xWHdLPz8stKCMAlVNKYPRWztZ6ctQMCQQC8
  20. iWbeAy+ApvBhhMjg4HJRdpNbwO6MbLEuD3CUrZFEDfTrlU2MeVdv20xC6ZiY3Qtq
  21. /4FPZZNGdZcSEuc3km5RAkApGkZmWetNwDJMcUJbSBrQMFfrQObqMPBPe+gEniQq
  22. Ttwu1OULHlmUg9eW31wRI2uiXcFCJMHuro6iOQ1VJ4Qs
  23. -----END RSA PRIVATE KEY-----";

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

  1. // 获取modulus和publicExponent
  2. string publicKey = PUBLICKEY.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
  3. byte[] btPem = Convert.FromBase64String(publicKey);
  4. int pemModulus = , pemPublicExponent = ;
  5. byte[] btPemModulus = new byte[];
  6. byte[] btPemPublicExponent = new byte[];
  7. for (int i = ; i < pemModulus; i++)
  8. {
  9. btPemModulus[i] = btPem[ + i];
  10. }
  11. for (int i = ; i < pemPublicExponent; i++)
  12. {
  13. btPemPublicExponent[i] = btPem[ + i];
  14. }

公钥解密的方法为

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

公钥加密的方法为

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

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

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

  1.      /// <summary>
  2. /// WPRT的RSA公钥加密
  3. /// </summary>
  4. /// <param name="rawData">源数据</param>
  5. /// <returns>加密后的数据</returns>
  6. public static string PublicEncrypt(string rawData)
  7. {
  8. try
  9. {
  10. /*将文本转换成IBuffer*/
  11. IBuffer bufferRawData = CryptographicBuffer.ConvertStringToBinary(rawData, BinaryStringEncoding.Utf8);
  12.  
  13. /*加密算法提供程序*/
  14. AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm
  15. (AsymmetricAlgorithmNames.RsaPkcs1);
  16.  
  17. /*导入公钥*/
  18. string PUBLIC_KEY = PUBLICKEY.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "");
  19. CryptographicKey publicKey = provider.ImportPublicKey(CryptographicBuffer.DecodeFromBase64String(PUBLIC_KEY));
  20.  
  21. //加密
  22. IBuffer result = CryptographicEngine.Encrypt(publicKey, bufferRawData, null);
  23. byte[] res;
  24. CryptographicBuffer.CopyToByteArray(result, out res);
  25. Debug.WriteLine("WinRT公钥加密后:" + Convert.ToBase64String(res));
  26. return Convert.ToBase64String(res);
  27. }
  28. catch (Exception e)
  29. {
  30. Debug.WriteLine("Encrypt Exception:" + e.StackTrace);
  31. return rawData;
  32. }
  33. }
  34.  
  35. /// <summary>
  36. /// WPRT的RSA私钥解密
  37. /// </summary>
  38. /// <param name="rawData"></param>
  39. /// <returns></returns>
  40. public static string PrivateDecrypt(string rawData)
  41. {
  42. try
  43. {
  44. /*将文本转换成IBuffer*/
  45. IBuffer bufferRawData = CryptographicBuffer.ConvertStringToBinary(rawData, BinaryStringEncoding.Utf8);
  46.  
  47. /*加密算法提供程序*/
  48. AsymmetricKeyAlgorithmProvider provider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm
  49. (AsymmetricAlgorithmNames.RsaPkcs1);
  50.  
  51. /*导入私钥*/
  52. string PRIVATE_KEY = PRIVATEKEY.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "");
  53. CryptographicKey privateKey = provider.ImportKeyPair(CryptographicBuffer.DecodeFromBase64String(PRIVATE_KEY));
  54.  
  55. //解密
  56. IBuffer result = CryptographicEngine.Decrypt(privateKey, bufferRawData, null);
  57. byte[] res;
  58. CryptographicBuffer.CopyToByteArray(result, out res);
  59. Debug.WriteLine("WinRT私钥解密后:" + Encoding.UTF8.GetString(res,,res.Length));
  60. return Encoding.UTF8.GetString(res,,res.Length);
  61. }
  62. catch (Exception e)
  63. {
  64. Debug.WriteLine("Decrypt Exception:" + e.StackTrace);
  65. return rawData;
  66. }
  67. }

参考链接

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. DbMigration使用方法

    1.Enable-Migrations -ContextTypeNameLITCS.Data.gmisContext Enable-Migrations  命令创建了一个新的Migrations文件夹 ...

  2. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

  3. VS2012 Unit Test —— 我对IdleTest库动的大手术以及对Xml相关操作进行测试的方式

    [1]我的IdleTest源码地址:http://idletest.codeplex.com/ [2]IdleTest改动说明:2013年10月份在保持原有功能的情况下对其动了较大的手术,首先将基本的 ...

  4. django 1.10 CSRF验证失败的解决过程

    最近工作闲,没事自学django,感觉这个最烦的就是各版本提供的api函数经常有变化,不是取消了就是参数没有了,网上搜到的帖子也没说明用的是什么版本的django,所以经常出现搬运过来的代码解决不了问 ...

  5. Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead的解决办法

    今天在导入工程进Eclipse的时候竟然出错了,控制台输出的是: [2013-02-04 22:17:13 - takepicture] Android requires compiler compl ...

  6. Java 性能分析工具 , 第 3 部分: Java Mission Control

    引言 本文为 Java 性能分析工具系列文章第三篇,这里将介绍如何使用 Java 任务控制器 Java Mission Control 深入分析 Java 应用程序的性能,为程序开发人员在使用 Jav ...

  7. jTemplates部分语法介绍

    1.{#if} {#if |COND|}..{#elseif |COND|}..{#else}..{#/if} Examples: {#if 2*8==16} good {#else} fail {# ...

  8. sublime 相关配置

    安转插件:案例格式化HTML代码,需要安装插件,具体安装步骤如下: 1.打开菜单->首选项->插件控制,输入 install package 2.等待程序进入插件管理功能,再输入插件名称: ...

  9. Eclipse中JAR System library 没有怎么添加?

    1.打开  >>  Eclipse 2.右击项目   >>  Build path  >>  Configure Build path  如图1: 图1 3.进入 ...

  10. zabbix完整安装

    一.nginx安装 1.必要软件准备: 为了支持rewrite功能,我们需要安装pcre: yum install pcre-* 需要ssl的支持,如果不需要ssl支持,请跳过这一步: yum ins ...