前几天发现博客园登录时,对登录的数据进行了加密,在我这种菜鸟看来算是高大上的功能了,于是决定研究一下。

后来发现其实园子里或者网上有类似文章,但好像都是php写的demo,并没有c#的示例,所以在收集了各位大牛的文章后,进行加工,形成了今天的demo,所以严格意义上来说此文并非原创。在这里要感谢@趴在巨人肩上的矮子   @dudu

首先科普一下相关技术:

Openssl 
OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。

SSL是Secure Sockets Layer(安全套接层协议)的缩写,可以在Internet上提供秘密性传输。Netscape公司在推出第一个Web浏览器的同时,提出了SSL协议标准。其目标是保证两个应用间通信的保密性和可靠性,可在服务器端和用户端同时实现支持。已经成为Internet上保密通讯的工业标准。
SSL能使用户/服务器应用之间的通信不被攻击者窃听,并且始终对服务器进行认证,还可选择对用户进行认证。SSL协议要求建立在可靠的传输层协议(TCP)之上。SSL协议的优势在于它是与应用层协议独立无关的,高层的应用层协议(例如:HTTP,FTP,TELNET等)能透明地建立于SSL协议之上。SSL协议在应用层协议通信之前就已经完成加密算法、通信密钥的协商及服务器认证工作。在此之后应用层协议所传送的数据都会被加密,从而保证通信的私密性。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

RSA算法

RSA算法是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。它的安全性是基于大整数素因子分解的困难性,而大整数因子分解问题是数学上的著名难题,至今没有有效的方法予以解决,因此可以确保RSA算法的安全性。

RSA算法实现主要分为三部分:包括公钥和私钥的产生,非对称加密和解密,数字签名和验证,下面将逐个介绍RSA算法的工作原理及我的实现方法。

1.公钥和私钥的产生

随意选择两个大素数p、q,p不等于q,计算n = p * q。

随机选择一个整数e,满足e和( p –1 ) * ( q –1 )互质。(注:e很容易选择,如3, 17, 65537等都可以。.NET Framework中e默认选择的就是65537)

利用Euclid算法计算解密密钥d,满足

e * d ≡1 ( mod ( p - 1 ) * ( q - 1 ) )

其中n和d也要互质。

其中e和n就是公钥,d和n就是私钥。P、q销毁。

jsencrypt官网:http://travistidwell.com/jsencrypt/

在线生成非对称加密公钥私钥对:http://web.chacuo.net/netrsakeypair

做非对称加密时候,经常要生成密钥对,公钥私钥。一般常用openssl命令行生成,每次操作比较复杂,提供在线工具可以选定生成私钥位数以及私钥密码,可以直接在线生成非对称加密密钥对。本工具提供pkcs#1格式公私钥对,还有pkcs#8公私钥对。早期openssl1.0之前版本,一般提供是pkcs#1格式,有很多软件只支持pkcs#1格式(js rsa模块),那么你可以选择生成该种类型。现在一般流行是pkcs#8格式。详细可以上网找找,pkcs#1与pkcs#8区别。

以下是代码实现部分:

 1 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %>
 2
 3 <!DOCTYPE html>
 4
 5 <html xmlns="http://www.w3.org/1999/xhtml">
 6 <head runat="server">
 7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 8     <title></title>
 9     <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
10     <script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>
11     <script type="text/javascript">
12         // 使用jsencrypt类库加密js方法,
13         function encryptRequest(reqUrl, data, publicKey) {
14             var encrypt = new JSEncrypt();
15             encrypt.setPublicKey(publicKey);
16             // ajax请求发送的数据对象
17             var sendData = new Object();
18             // 将data数组赋给ajax对象
19             for (var key in data) {
20                 sendData[key] = encrypt.encrypt(data[key]);
21             }
22
23             $.ajax({
24                 url: reqUrl,
25                 type: 'post',
26                 data: sendData,
27                 dataType: 'json',
28                 //contentType: 'application/json; charset=utf-8',
29                 success: function (data) {
30                     console.info(data);
31                 },
32                 error: function (xhr) {
33                     //console.error('出错了');
34                 }
35             });
36
37         }
38
39         // Call this code when the page is done loading.
40         $(function () {
41
42             $('#testme').click(function () {
43
44                 var data = [];
45                 data['username'] = $('#username').val();
46                 data['passwd'] = $('#passwd').val();
47
48                 var pkey = $('#pubkey').val();
49                 encryptRequest('/WebForm2.aspx', data, pkey);
50             });
51         });
52     </script>
53 </head>
54 <body>
55     <form id="form1" runat="server">
56         <div>
57             <label for="pubkey">Public Key</label><br />
58             <textarea id="pubkey" rows="15" cols="65">
59 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCC0hrRIjb3noDWNtbDpANbjt5I
60 wu2NFeDwU16Ec87ToqeoIm2KI+cOs81JP9aTDk/jkAlU97mN8wZkEMDr5utAZtMV
61 ht7GLX33Wx9XjqxUsDfsGkqNL8dXJklWDu9Zh80Ui2Ug+340d5dZtKtd+nv09QZq
62 GjdnSp9PTfFDBY133QIDAQAB
63 </textarea><br />
64             <label for="input">Text to encrypt:</label><br />
65             name:<input id="username" name="username" type="text"></input><br />
66             password:<input id="passwd" name="passwd" type="password"></input><br />
67             <input id="testme" type="button" value="submit" /><br />
68         </div>
69     </form>
70 </body>
71 </html>

客户端

  1 using System;
  2 using System.Collections.Generic;
  3 using System.IO;
  4 using System.Linq;
  5 using System.Security.Cryptography;
  6 using System.Text;
  7 using System.Web;
  8 using System.Web.UI;
  9 using System.Web.UI.WebControls;
 10
 11 namespace WebApplication1
 12 {
 13     public partial class WebForm2 : System.Web.UI.Page
 14     {
 15         private const string privateKey = @"MIICXAIBAAKBgQCC0hrRIjb3noDWNtbDpANbjt5Iwu2NFeDwU16Ec87ToqeoIm2K
 16 I+cOs81JP9aTDk/jkAlU97mN8wZkEMDr5utAZtMVht7GLX33Wx9XjqxUsDfsGkqN
 17 L8dXJklWDu9Zh80Ui2Ug+340d5dZtKtd+nv09QZqGjdnSp9PTfFDBY133QIDAQAB
 18 AoGAJBNTOITaP6LCyKVKyEdnHaKNAz0DS+V9UwjKhyAgfcAxwm3sDdd6FQCEW0TI
 19 JA7Np7rFYrGwcR1UOoKxkNxB10ACl6JX4rE7xKS6NLZumdwxON/KgDb+2SQtWEXD
 20 gBySZ7Znv/FhEp1RmoBDjZ05E99kILWO3ToorUM0Eq2GHQkCQQCnUMXgZa4HS0tu
 21 INzysgB37d7ene9+CIARyJphs079qao2UWCgXqen43Ob6GJUgulz7We+4JOZFld0
 22 TfEi1E5rAkEAyClQAVzafLO3gXgqH7tbRbPPx788+4opxT9QBo2Trzl6/3FlcC1P
 23 IZeqbQ/Oc2wT7jmidFnpyTEnM2p7Yq3U1wJBAILTWaX4W3dAnJ5j+9+Y51zfFiEj
 24 hRwbMWi2XmB+gAlAHOOUBeXfnWBdLQx/TEOgiUIoI7LQjxhoq8E5II+HSjkCQDlK
 25 SdH6B7dFoTJ3eGcYsykiLEiZ3hSJGSeR1Y/qmei/ZQsUI9qVvV56EJeivI6g0puO
 26 94ah7Z5eaT/4LFS0OIUCQDgLn586pGgeidLhQsIe/AR3y9YOCAygTFLxzmeBXOKt
 27 M90q4516KWlTtK2u99442mNi7hNmjryBVwk62foWo8w=";
 28
 29         private const string publicKey = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCC0hrRIjb3noDWNtbDpANbjt5I
 30 wu2NFeDwU16Ec87ToqeoIm2KI+cOs81JP9aTDk/jkAlU97mN8wZkEMDr5utAZtMV
 31 ht7GLX33Wx9XjqxUsDfsGkqNL8dXJklWDu9Zh80Ui2Ug+340d5dZtKtd+nv09QZq
 32 GjdnSp9PTfFDBY133QIDAQAB";
 33
 34         protected void Page_Load(object sender, EventArgs e)
 35         {
 36             if (!IsPostBack)
 37             {
 38                 RSACryptoService rsa = new RSACryptoService(privateKey, publicKey);
 39                 string data = rsa.Encrypt("我是加密");
 40                 Response.Write(rsa.Decrypt(Request.Form["username"]));//解密
 41             }
 42         }
 43
 44     }
 45
 46     public class RSACryptoService
 47     {
 48         private RSACryptoServiceProvider _privateKeyRsaProvider;
 49         private RSACryptoServiceProvider _publicKeyRsaProvider;
 50
 51         public RSACryptoService(string privateKey, string publicKey = null)
 52         {
 53             if (!string.IsNullOrEmpty(privateKey))
 54             {
 55                 _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
 56             }
 57
 58             if (!string.IsNullOrEmpty(publicKey))
 59             {
 60                 _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
 61             }
 62         }
 63
 64         public string Decrypt(string cipherText)
 65         {
 66             if (_privateKeyRsaProvider == null)
 67             {
 68                 throw new Exception("_privateKeyRsaProvider is null");
 69             }
 70             return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(System.Convert.FromBase64String(cipherText), false));
 71         }
 72
 73         public string Encrypt(string text)
 74         {
 75             if (_publicKeyRsaProvider == null)
 76             {
 77                 throw new Exception("_publicKeyRsaProvider is null");
 78             }
 79             return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), false));
 80         }
 81
 82         private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey)
 83         {
 84             var privateKeyBits = System.Convert.FromBase64String(privateKey);
 85
 86             var RSA = new RSACryptoServiceProvider();
 87             var RSAparams = new RSAParameters();
 88
 89             using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
 90             {
 91                 byte bt = 0;
 92                 ushort twobytes = 0;
 93                 twobytes = binr.ReadUInt16();
 94                 if (twobytes == 0x8130)
 95                     binr.ReadByte();
 96                 else if (twobytes == 0x8230)
 97                     binr.ReadInt16();
 98                 else
 99                     throw new Exception("Unexpected value read binr.ReadUInt16()");
100
101                 twobytes = binr.ReadUInt16();
102                 if (twobytes != 0x0102)
103                     throw new Exception("Unexpected version");
104
105                 bt = binr.ReadByte();
106                 if (bt != 0x00)
107                     throw new Exception("Unexpected value read binr.ReadByte()");
108
109                 RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
110                 RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
111                 RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
112                 RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
113                 RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
114                 RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
115                 RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
116                 RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
117             }
118
119             RSA.ImportParameters(RSAparams);
120             return RSA;
121         }
122
123         private int GetIntegerSize(BinaryReader binr)
124         {
125             byte bt = 0;
126             byte lowbyte = 0x00;
127             byte highbyte = 0x00;
128             int count = 0;
129             bt = binr.ReadByte();
130             if (bt != 0x02)
131                 return 0;
132             bt = binr.ReadByte();
133
134             if (bt == 0x81)
135                 count = binr.ReadByte();
136             else
137                 if (bt == 0x82)
138                 {
139                     highbyte = binr.ReadByte();
140                     lowbyte = binr.ReadByte();
141                     byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
142                     count = BitConverter.ToInt32(modint, 0);
143                 }
144                 else
145                 {
146                     count = bt;
147                 }
148
149             while (binr.ReadByte() == 0x00)
150             {
151                 count -= 1;
152             }
153             binr.BaseStream.Seek(-1, SeekOrigin.Current);
154             return count;
155         }
156
157         private RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)
158         {
159             // encoded OID sequence for  PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
160             byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
161             byte[] x509key;
162             byte[] seq = new byte[15];
163             int x509size;
164
165             x509key = Convert.FromBase64String(publicKeyString);
166             x509size = x509key.Length;
167
168             // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------
169             using (MemoryStream mem = new MemoryStream(x509key))
170             {
171                 using (BinaryReader binr = new BinaryReader(mem))  //wrap Memory Stream with BinaryReader for easy reading
172                 {
173                     byte bt = 0;
174                     ushort twobytes = 0;
175
176                     twobytes = binr.ReadUInt16();
177                     if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
178                         binr.ReadByte();    //advance 1 byte
179                     else if (twobytes == 0x8230)
180                         binr.ReadInt16();   //advance 2 bytes
181                     else
182                         return null;
183
184                     seq = binr.ReadBytes(15);       //read the Sequence OID
185                     if (!CompareBytearrays(seq, SeqOID))    //make sure Sequence for OID is correct
186                         return null;
187
188                     twobytes = binr.ReadUInt16();
189                     if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
190                         binr.ReadByte();    //advance 1 byte
191                     else if (twobytes == 0x8203)
192                         binr.ReadInt16();   //advance 2 bytes
193                     else
194                         return null;
195
196                     bt = binr.ReadByte();
197                     if (bt != 0x00)     //expect null byte next
198                         return null;
199
200                     twobytes = binr.ReadUInt16();
201                     if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
202                         binr.ReadByte();    //advance 1 byte
203                     else if (twobytes == 0x8230)
204                         binr.ReadInt16();   //advance 2 bytes
205                     else
206                         return null;
207
208                     twobytes = binr.ReadUInt16();
209                     byte lowbyte = 0x00;
210                     byte highbyte = 0x00;
211
212                     if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
213                         lowbyte = binr.ReadByte();  // read next bytes which is bytes in modulus
214                     else if (twobytes == 0x8202)
215                     {
216                         highbyte = binr.ReadByte(); //advance 2 bytes
217                         lowbyte = binr.ReadByte();
218                     }
219                     else
220                         return null;
221                     byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian order
222                     int modsize = BitConverter.ToInt32(modint, 0);
223
224                     int firstbyte = binr.PeekChar();
225                     if (firstbyte == 0x00)
226                     {   //if first byte (highest order) of modulus is zero, don't include it
227                         binr.ReadByte();    //skip this null byte
228                         modsize -= 1;   //reduce modulus buffer size by 1
229                     }
230
231                     byte[] modulus = binr.ReadBytes(modsize);   //read the modulus bytes
232
233                     if (binr.ReadByte() != 0x02)            //expect an Integer for the exponent data
234                         return null;
235                     int expbytes = (int)binr.ReadByte();        // should only need one byte for actual exponent data (for all useful values)
236                     byte[] exponent = binr.ReadBytes(expbytes);
237
238                     // ------- create RSACryptoServiceProvider instance and initialize with public key -----
239                     RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
240                     RSAParameters RSAKeyInfo = new RSAParameters();
241                     RSAKeyInfo.Modulus = modulus;
242                     RSAKeyInfo.Exponent = exponent;
243                     RSA.ImportParameters(RSAKeyInfo);
244
245                     return RSA;
246                 }
247
248             }
249         }
250
251         private bool CompareBytearrays(byte[] a, byte[] b)
252         {
253             if (a.Length != b.Length)
254                 return false;
255             int i = 0;
256             foreach (byte c in a)
257             {
258                 if (c != b[i])
259                     return false;
260                 i++;
261             }
262             return true;
263         }
264     }
265 }

服务端

Demo下载

http://pan.baidu.com/s/1i31vfI9

Tips

貌似目前jsencrypt密钥格式只支持pkcs#1格式,所以在生成时请生成pkcs#1格式

转载于:https://www.cnblogs.com/jrsnd/p/4786767.html

RSA加密解密在jsencrypt+c#的实现-博客园加密登录相关推荐

  1. 博客园登录 php,博客园加密登录--jsencrypt

    博客园加密登录--jsencrypt 问题由来 前几天在做项目的时候,发现一般做登录的时候只是一个非常简单的`form`表单,但是这样肯定是不安全的!所以想去看看其他比较流行的网站是怎么实现的.说到安 ...

  2. php 原理 淘口令 解密_淘口令解析 - VX_super19911115 - 博客园

    淘口令解析 通过程序解析淘口令,无需联盟开发者权限,只需几行代码就可实现自动识别淘口令: def query_password(sign_server, share_password): data = ...

  3. php怎么魔方加密,深度解析php混淆加密解密的手段,希望对大家解读魔方加密有所帮助 [tihuan]...

    深度解析php混淆加密解密的手段,希望对大家解读魔方加密有所帮助 [tihuan] 2018-12-31 php做为一门当下非常流行的web语言,常常看到有人求解密php文件,想当年的asp也是一样. ...

  4. 搜集博客园邀月工作室的有关加密对称加密的文章

    SQL Server 2008中的代码安全(五):非对称密钥加密 SQL Server 2008中SQL应用系列--目录索引 非对称密钥包含数据库级的内部公钥和私钥,它可以用来加密和解密SQL Ser ...

  5. android java代码加密,Android中AES256加密的实现 – Leo Chin – 博客园

    AES加密是我们在工作中常用到一种加密方式,并且在java中也已经实现好了其相应的接口. 但是Java自带的JDK默认最多实现128位及其以下的加密.如果使用java自带的api实现aes256将会报 ...

  6. security工作笔记009---spring security BCryptPasswordEncoder加密解密,不错的随机盐,不错的加密解密方法

    JAVA技术交流QQ群:170933152 项目中用这个加密感觉不错啊,推荐: 1.先大体看看,了解一下 浅谈使用springsecurity中的BCryptPasswordEncoder方法对密码进 ...

  7. php 易语言md5加密解密,详解易语言调用js实现md5加密方法

    易语言调用js需要用到拓展组件的脚本组件, 在窗口创建完毕的事件里给脚本组件初始化设置下脚本组件的语言属性,在这里以JScript为例: 脚本组件执行脚本的简单方法是:  脚本组件1.执行 ()  然 ...

  8. MacOS下使用C语言基于openssl库进行RSA加密解密

    MacOS下使用C语言基于openssl库进行RSA加密解密 1 安装openssl并生成密钥 首先当然要安装openssl(这里记得看一下安装路径,应该是/usr/local/Cellar/open ...

  9. RSA、MD5加密解密算法全套解析安装教程

    第一部分介绍加密解密算法, 第二部分介绍我小组成功应用的RSA.MD5两种加密解密算法,以及心得体会. 1.加密解密算法介绍 应用的开发中安全很重要,所以信息加密技术显得尤为重要.我们需要对应用中的多 ...

最新文章

  1. aws python sdk send sns_AWS:boto3订阅SNS时的空SQS队列
  2. 那些年我们追过的网络库(PartI)
  3. 用“黑科技”产放心粮,种地竟然和想象中有点不一样
  4. php新闻列表排序,javascript 新闻列表排序简单封装
  5. python不正确的关系字符_Python系列之 - 字符编码问题
  6. 【效率工具合集】Win10镜像迅雷快速安装
  7. WD西部数据2TB,2.5寸移动硬盘,因为磁头坏了,长时间通电导致划片划伤,维修过程通过反复更换磁头
  8. 软件测试常见的风险,软件测试中常见的风险分析
  9. 论文翻译:2021_MetricGAN+: An Improved Version of MetricGAN for Speech Enhancement
  10. 青云科技上市:云计算企业的另一种最优解
  11. yum是干什么的_yum 安装是什么
  12. h5页面中android与ios返回上一级并强制刷新的方式
  13. relative会脱离文档流吗_position:absolute会使元素脱离文档流
  14. 深度强化学习——actor-critic算法(4)
  15. VIVADO时序约束之Input Delay(set_input_delay)
  16. pytorch earlystopping使用
  17. 分布式系统服务单点问题的探讨
  18. CISP-PTE/CISP-PTS认证考试要点整理
  19. 干货 || 分析9款常用视觉软件
  20. 全国聋人乒乓球锦标赛

热门文章

  1. 请使用 WITH MOVE 选项来标识该文件的有效位置。
  2. Oracle下绝对文件号和相对文件号区别
  3. VC++大数据量绘图时无闪烁刷屏技术实现
  4. Apr.2010 Microsoft MVP连任
  5. 转贴:cg(c for graphic)编程语言
  6. SpringCloud微服务注册中心如何承载大型系统的千万级访问?源码及原理分析
  7. STL——vector
  8. 一张图说明 函数, 实例(对象), 原型之间的关系
  9. 洛谷P1613 跑路
  10. hibnate 创建表的时候type=innodb报错