最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

同時(shí)兼容JS和C#的RSA加密解密算法詳解(對(duì)web提交的數(shù)據(jù)加密傳輸)

 更新時(shí)間:2017年07月31日 11:52:28   作者:JackWang-CUMT  
這篇文章主要給大家介紹了關(guān)于同時(shí)兼容JS和C#的RSA加密解密算法,通過(guò)該算法可以對(duì)web提交的數(shù)據(jù)進(jìn)行加密傳輸,文中通過(guò)圖文及示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。

前言

我們?cè)赪eb應(yīng)用中往往涉及到敏感的數(shù)據(jù),由于HTTP協(xié)議以明文的形式與服務(wù)器進(jìn)行交互,因此可以通過(guò)截獲請(qǐng)求的數(shù)據(jù)包進(jìn)行分析來(lái)盜取有用的信息。雖然https可以對(duì)傳輸?shù)臄?shù)據(jù)進(jìn)行加密,但是必須要申請(qǐng)證書(一般都是收費(fèi)的),成本較高。那么問(wèn)題來(lái)了,如果對(duì)web提交的敏感數(shù)據(jù)進(jìn)行加密呢?web應(yīng)用中,前端的數(shù)據(jù)處理和交互基本上都是靠javascript來(lái)完成,后臺(tái)的邏輯處理可以C#(java)等進(jìn)行處理。

微軟的C#中雖然有RSA算法,但是格式和OpenSSL生成的公鑰/私鑰文件格式并不兼容。這個(gè)也給貫通前后臺(tái)的RSA加密解密帶來(lái)了難度。為了兼容OpenSSL生成的公鑰/私鑰文件格式,貫通javascript和C#的RSA加密解密算法,必須對(duì)C#內(nèi)置的方法進(jìn)行再度封裝。

下面以登錄為例,用戶在密碼框輸入密碼后,javascript發(fā)送ajax請(qǐng)求時(shí),對(duì)密碼先進(jìn)行rsa加密后再發(fā)送,服務(wù)器接收到加密后的密碼后,先對(duì)其進(jìn)行解密, 然后再驗(yàn)證登錄是否成功。

1、為了進(jìn)行RSA加密解密,首先需要用openssl生成一對(duì)公鑰和私鑰(沒(méi)有的先下載openssl):

   1) 打開openssl.exe文件,輸入 genrsa -out openssl_rsa_priv.pem 1024

此命令在openssl.exe同目錄下生成openssl_rsa_private_key.pem文件。

  2) 生成公鑰 rsa  -in openssl_rsa__private.pem -pubout -out openssl_rsa__public.pem

  以上命令會(huì)創(chuàng)建如下的文件:

這個(gè)文件可以用文本編輯器進(jìn)行打開,查看內(nèi)容。

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0w036ClSD0LvxPROMun0u022R
OJlZE6P3m+gjq3gpi4n7lo8jhTqMqgccDbVJqnIfMzWS9O3lnlQXWTxJ3B4XJ52F
AcriY5brOXUVgBLx5QMHLLd1gtJnmG4i7r4ytgX7XVKRnojR6zca1YnS0lbGGDF1
CGllB1riNrdksSQP+wIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQC0w036ClSD0LvxPROMun0u022ROJlZE6P3m+gjq3gpi4n7lo8j
hTqMqgccDbVJqnIfMzWS9O3lnlQXWTxJ3B4XJ52FAcriY5brOXUVgBLx5QMHLLd1
gtJnmG4i7r4ytgX7XVKRnojR6zca1YnS0lbGGDF1CGllB1riNrdksSQP+wIDAQAB
AoGAIOyl6lIxXKULZoBKbEqXfIz0GwxlGg1ywyn5mW2lAGQzKMken0ioBnD9xIVW
rOlHyhkIvBCyuC0jgfE2Avn93MlB3j0WRuXMFlJpCBlEklMilO9Zgmwl+vTB3VZb
8VzdrEEEUBio7LWP/KvSo+IFlNjDTKgAczbLTwAmj4w6g0ECQQDm4yxPdxcU2ywZ
7PyjIMM9qnSah9KcrjU8gjEyHsUpgTjhw1cx7Peo+vRiHqxDy1yaSu1BlwRR52pC
jKNnl0QhAkEAyGx3NxEIiLk2oXGGbIMZ4P6geC8gYu01BiRNWVf0Yi7+sCH68eUP
oI+G5bJ8bvzXpvHjQi0s2OlRfct/qtPQmwJBALa+2DONbxdy4lUi3lO/esk0QVaO
aoTY3gomggnJkQRo4zzOABXkGaIF/6gp3u9J5uG4rFFd1m19XP2Pk0ZK1AECQBYi
lJAKW4zuF7CA3z3AxOzqckKTwdnrJL4G6FwDsMPfONWvCw4IJE+xSk64BbIkTpTr
hhPa9WcHba6c+P6e4h0CQQDWeGMMpkqPG/w4afNCGmvRnM8vNkGUAmDGvCsfkTID
ijpKl5SD55hPHsWE5rsv1TLUpkWtrFBcg61bHwMUP3cv
-----END RSA PRIVATE KEY-----

2、用jsencrypt對(duì)密碼進(jìn)行加密:

首先需要導(dǎo)入js包文件

<script src="dist/js/jsencrypt.js"></script>
var encrypt = new JSEncrypt();
var pubkey = "-----BEGIN PUBLIC KEY----- \
 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAj0dPnBMf3Z4VT1B8Ee6bjKNs \
 hlYj7xvGijAa8RCdmGR7mrtrExnk8mdUlwdcS05gc4SSFOyWJcYtKUHpWn8/pkS0 \
 vgGOl9Bzn0Xt9hiqTb3pZAfykNrMDGZMgJgfD6KTnfzVUAOupvxjcGkcoj6/vV5I \
 eMcx8mT/z3elfsDSjQIDAQAB \
 -----END PUBLIC KEY-----";
encrypt.setPublicKey(pubkey);
var encrypted = encrypt.encrypt($('#txtpwd').val());
//console.log(encrypted);
$.ajax({
 type: "POST",
 url: "http://localhost:24830/services/rsa_pem.ashx",
 data: { "pwd": encrypted },
 dataType: "Json",
 error: function (xhr, status, error) {
  // alert(error);
  $("#txtInfo").text(' 請(qǐng)求服務(wù)器失?。?);
  $(that).text('登 錄');
  $(that).attr('disabled', false);
 },
 success: function (json) {
 
 if (uid == "admin" && json.data=="000") {
  window.location.href = "index.html";
 }
 else {
  $("#txtInfo").text(' 用戶名或者密碼錯(cuò)誤!');
  $(that).text('登 錄');
  $(that).attr('disabled', false);
 }
 }
});

3、后臺(tái)用C#進(jìn)行解密

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CMCloud.SaaS
{
 public class RSACryptoService
 {
 private RSACryptoServiceProvider _privateKeyRsaProvider;
 private RSACryptoServiceProvider _publicKeyRsaProvider;

 /// <summary>
 /// RSA解密
 /// </summary>
 /// <param name="cipherText"></param>
 /// <returns></returns>
 public string Decrypt(string cipherText)
 {
  if (_privateKeyRsaProvider == null)
  {
  throw new Exception("_privateKeyRsaProvider is null");
  }
  return Decrypt2(cipherText);
 }
 /// <summary>
 /// RSA加密
 /// </summary>
 /// <param name="text"></param>
 /// <returns></returns>
 public string Encrypt(string text)
 {
  if (_publicKeyRsaProvider == null)
  {
  throw new Exception("_publicKeyRsaProvider is null");
  }
  return Encrypt2(text);
  //return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), false));

 }
 private string Encrypt2(string text)
 {


  Byte[] PlaintextData = Encoding.UTF8.GetBytes(text);
  int MaxBlockSize = _publicKeyRsaProvider.KeySize / 8 - 11;//加密塊最大長(zhǎng)度限制

  if (PlaintextData.Length <= MaxBlockSize)
  {
  return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(PlaintextData, false));
  }
  else
  {
  using (MemoryStream PlaiStream = new MemoryStream(PlaintextData))
  using (MemoryStream CrypStream = new MemoryStream())
  {
   Byte[] Buffer = new Byte[MaxBlockSize];
   int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);

   while (BlockSize > 0)
   {
   Byte[] ToEncrypt = new Byte[BlockSize];
   Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);

   Byte[] Cryptograph = _publicKeyRsaProvider.Encrypt(ToEncrypt, false);
   CrypStream.Write(Cryptograph, 0, Cryptograph.Length);

   BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
   }

   return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
  }
  }




 }

 private string Decrypt2(string ciphertext)
 {


  Byte[] CiphertextData = Convert.FromBase64String(ciphertext);
  int MaxBlockSize = _privateKeyRsaProvider.KeySize / 8; //解密塊最大長(zhǎng)度限制

  if (CiphertextData.Length <= MaxBlockSize)
  return System.Text.Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(CiphertextData, false));

  using (MemoryStream CrypStream = new MemoryStream(CiphertextData))
  using (MemoryStream PlaiStream = new MemoryStream())
  {
  Byte[] Buffer = new Byte[MaxBlockSize];
  int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);

  while (BlockSize > 0)
  {
   Byte[] ToDecrypt = new Byte[BlockSize];
   Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);

   Byte[] Plaintext = _privateKeyRsaProvider.Decrypt(ToDecrypt, false);
   PlaiStream.Write(Plaintext, 0, Plaintext.Length);

   BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
  }

  return System.Text.Encoding.UTF8.GetString(PlaiStream.ToArray());
  }
 }
 public RSACryptoService(string privateKey, string publicKey = null)
 {
  if (!string.IsNullOrEmpty(privateKey))
  {
  _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
  }

  if (!string.IsNullOrEmpty(publicKey))
  {
  _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
  }
 }

 

 private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey)
 {
  var privateKeyBits = System.Convert.FromBase64String(privateKey);

  var RSA = new RSACryptoServiceProvider();
  var RSAparams = new RSAParameters();

  using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
  {
  byte bt = 0;
  ushort twobytes = 0;
  twobytes = binr.ReadUInt16();
  if (twobytes == 0x8130)
   binr.ReadByte();
  else if (twobytes == 0x8230)
   binr.ReadInt16();
  else
   throw new Exception("Unexpected value read binr.ReadUInt16()");

  twobytes = binr.ReadUInt16();
  if (twobytes != 0x0102)
   throw new Exception("Unexpected version");

  bt = binr.ReadByte();
  if (bt != 0x00)
   throw new Exception("Unexpected value read binr.ReadByte()");

  RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
  RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
  }

  RSA.ImportParameters(RSAparams);
  return RSA;
 }

 private int GetIntegerSize(BinaryReader binr)
 {
  byte bt = 0;
  byte lowbyte = 0x00;
  byte highbyte = 0x00;
  int count = 0;
  bt = binr.ReadByte();
  if (bt != 0x02)
  return 0;
  bt = binr.ReadByte();

  if (bt == 0x81)
  count = binr.ReadByte();
  else
  if (bt == 0x82)
  {
  highbyte = binr.ReadByte();
  lowbyte = binr.ReadByte();
  byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
  count = BitConverter.ToInt32(modint, 0);
  }
  else
  {
  count = bt;
  }

  while (binr.ReadByte() == 0x00)
  {
  count -= 1;
  }
  binr.BaseStream.Seek(-1, SeekOrigin.Current);
  return count;
 }

 private RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)
 {
  // encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
  byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
  byte[] x509key;
  byte[] seq = new byte[15];
  int x509size;

  x509key = Convert.FromBase64String(publicKeyString);
  x509size = x509key.Length;

  // --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------
  using (MemoryStream mem = new MemoryStream(x509key))
  {
  using (BinaryReader binr = new BinaryReader(mem)) //wrap Memory Stream with BinaryReader for easy reading
  {
   byte bt = 0;
   ushort twobytes = 0;

   twobytes = binr.ReadUInt16();
   if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
   binr.ReadByte(); //advance 1 byte
   else if (twobytes == 0x8230)
   binr.ReadInt16(); //advance 2 bytes
   else
   return null;

   seq = binr.ReadBytes(15); //read the Sequence OID
   if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct
   return null;

   twobytes = binr.ReadUInt16();
   if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
   binr.ReadByte(); //advance 1 byte
   else if (twobytes == 0x8203)
   binr.ReadInt16(); //advance 2 bytes
   else
   return null;

   bt = binr.ReadByte();
   if (bt != 0x00) //expect null byte next
   return null;

   twobytes = binr.ReadUInt16();
   if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
   binr.ReadByte(); //advance 1 byte
   else if (twobytes == 0x8230)
   binr.ReadInt16(); //advance 2 bytes
   else
   return null;

   twobytes = binr.ReadUInt16();
   byte lowbyte = 0x00;
   byte highbyte = 0x00;

   if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
   lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus
   else if (twobytes == 0x8202)
   {
   highbyte = binr.ReadByte(); //advance 2 bytes
   lowbyte = binr.ReadByte();
   }
   else
   return null;
   byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order
   int modsize = BitConverter.ToInt32(modint, 0);

   int firstbyte = binr.PeekChar();
   if (firstbyte == 0x00)
   { //if first byte (highest order) of modulus is zero, don't include it
   binr.ReadByte(); //skip this null byte
   modsize -= 1; //reduce modulus buffer size by 1
   }

   byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes

   if (binr.ReadByte() != 0x02)  //expect an Integer for the exponent data
   return null;
   int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values)
   byte[] exponent = binr.ReadBytes(expbytes);

   // ------- create RSACryptoServiceProvider instance and initialize with public key -----
   RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
   RSAParameters RSAKeyInfo = new RSAParameters();
   RSAKeyInfo.Modulus = modulus;
   RSAKeyInfo.Exponent = exponent;
   RSA.ImportParameters(RSAKeyInfo);

   return RSA;
  }

  }
 }

 private bool CompareBytearrays(byte[] a, byte[] b)
 {
  if (a.Length != b.Length)
  return false;
  int i = 0;
  foreach (byte c in a)
  {
  if (c != b[i])
   return false;
  i++;
  }
  return true;
 }
 }
}

雖然將公鑰暴露在js文件中,但是如果需要解密得到明文,必須需要私鑰(這個(gè)存儲(chǔ)在后臺(tái),不容易獲?。?。

調(diào)試運(yùn)行,可以看到獲取的密碼是加密后的數(shù)據(jù),然后在后臺(tái)可以進(jìn)行解密獲取到明文。

 

總結(jié)

好了,大概就這樣,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持

相關(guān)文章

  • Unity圖形學(xué)之ShaderLab入門基礎(chǔ)

    Unity圖形學(xué)之ShaderLab入門基礎(chǔ)

    Unity中所有Shader文件都通過(guò)一種陳述性語(yǔ)言進(jìn)行描述,稱為“ShaderLab”, 這篇文章主要介紹了Unity圖形學(xué)之ShaderLab入門基礎(chǔ),需要的朋友可以參考下
    2022-01-01
  • DevExpress實(shí)現(xiàn)TreeList父子節(jié)點(diǎn)CheckState狀態(tài)同步的方法

    DevExpress實(shí)現(xiàn)TreeList父子節(jié)點(diǎn)CheckState狀態(tài)同步的方法

    這篇文章主要介紹了DevExpress實(shí)現(xiàn)TreeList父子節(jié)點(diǎn)CheckState狀態(tài)同步的方法,需要的朋友可以參考下
    2014-08-08
  • 詳解.NET 4.0中的泛型協(xié)變(covariant)和反變(contravariant)

    詳解.NET 4.0中的泛型協(xié)變(covariant)和反變(contravariant)

    這篇文章主要介紹了詳解.NET 4.0中的泛型協(xié)變(covariant)和反變(contravariant),本文講解了協(xié)變和反變的背景知識(shí)、.NET 4.0引入的泛型協(xié)變、反變性、協(xié)變和反變的相互作用等內(nèi)容,需要的朋友可以參考下
    2015-06-06
  • Unity接入高德開放API實(shí)現(xiàn)IP定位

    Unity接入高德開放API實(shí)現(xiàn)IP定位

    這篇文章主要為大家介紹了Unity如何接入高德開放API實(shí)現(xiàn)IP定位功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,需要的可以參考一下
    2022-04-04
  • C#基礎(chǔ)之委托詳解(Delegate)

    C#基礎(chǔ)之委托詳解(Delegate)

    這篇文章主要介紹了C#基礎(chǔ)之委托(Delegate),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • 解決C# 截取當(dāng)前程序窗口指定位置截圖的實(shí)現(xiàn)方法

    解決C# 截取當(dāng)前程序窗口指定位置截圖的實(shí)現(xiàn)方法

    本篇文章是對(duì)C#中截取當(dāng)前程序窗口指定位置截圖的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 在winform下實(shí)現(xiàn)左右布局多窗口界面的方法

    在winform下實(shí)現(xiàn)左右布局多窗口界面的方法

    在web頁(yè)面上我們可以通過(guò)frameset,iframe嵌套框架很容易實(shí)現(xiàn)各種導(dǎo)航+內(nèi)容的布局界面,而在winform、WPF中實(shí)現(xiàn)其實(shí)也很容易,通過(guò)本文給大家介紹在winform下實(shí)現(xiàn)左右布局多窗口界面的方法,本文介紹的非常詳細(xì),對(duì)winform布局相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-02-02
  • C#中常見的文件處理操作小結(jié)

    C#中常見的文件處理操作小結(jié)

    這篇文章主要為大家詳細(xì)介紹了C#中常見的一些文件處理操作,例如文件管理,獲取文件信息和控制處理文件,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • C#中+=是什么意思及+=的用法

    C#中+=是什么意思及+=的用法

    這篇文章主要介紹了C#中+=是什么意思及+=的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C#編寫COM組件的方法分析

    C#編寫COM組件的方法分析

    這篇文章主要介紹了C#編寫COM組件的方法,結(jié)合實(shí)例形式分析了C#編寫COM組件的具體步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-06-06

最新評(píng)論

教育| 大同市| 永嘉县| 科技| 黑山县| 宜春市| 蓝山县| 仁怀市| 酒泉市| 墨玉县| 甘泉县| 德昌县| 上林县| 海南省| 台山市| 苏尼特左旗| 于都县| 潜山县| 阿瓦提县| 保亭| 精河县| 高州市| 阿拉尔市| 宜黄县| 固安县| 临湘市| 合肥市| 开鲁县| 化州市| 米泉市| 偏关县| 德庆县| 澎湖县| 建阳市| 武宣县| 冀州市| 遂昌县| 崇阳县| 富宁县| 瓦房店市| 汝阳县|