欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中對稱加密算法的踩坑日常記錄

 更新時間:2019年06月24日 08:34:23   作者:ixysy  
這篇文章主要給大家介紹了關(guān)于C#中對稱加密算法的踩坑日常記錄,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

1|0前言

有幸接觸了一下傳說中的對稱加密算法3DES

感覺這些加密算法與我的工作是想去甚遠的,一般沒什么機會接觸這些東西

今次了解了一下3DES這個對稱算法

原理算不上明白,算是踩了C#中的一些坑吧

C#中對于密鑰的處理比較奇怪,花費了一晚上一早上的時間才弄明白

期間偷窺了不少C#的源代碼

下面由我娓娓道來

2|0簡介

2|13DES算法命名

定義算法最早期的標準被放在ANS X9.52中并在1998年發(fā)布并將其描述為三重數(shù)據(jù)加密算法(簡稱TDEA),在ANSI X3.92中定義了該算法的三個操作但是并沒有使用DES或者3DES,直到1999年發(fā)布的FIPS PUB 46-3在正式命名三重數(shù)據(jù)加密算法,大概在2004到2005的樣子才正式引入三重數(shù)據(jù)加密算法,之前一直以TDEA存在著,也就是說TDEA就是3DES,但是沒有使用3DES作為標準術(shù)語。

2|2基本邏輯

三重數(shù)據(jù)加密算法使用包括密鑰K1,密鑰K2和密鑰約束K3,每一個包含56位不包含奇偶校驗,算法實現(xiàn)公式如下:

ciphertext = EK3(DK2(EK1(plaintext)))

密文 = EK3(DK2(EK1(平文)))

用K1對數(shù)據(jù)進行加密,用K2對數(shù)據(jù)進行解密,用K3對數(shù)據(jù)再加密。

解密公式為如下:

plaintext = DK1(EK2(DK3(ciphertext)))

平文 = DK1(EK2(DK3(密文)))

用K3j對數(shù)據(jù)進行解密,用K2對數(shù)據(jù)進行加密,用K1對數(shù)據(jù)進行加密。每次加密都處理64位數(shù)據(jù)并形成一塊。

2|33DES加密選項

定義了三種密鑰選項。

(1)三個密鑰相互獨立。

(2)K1和K2密鑰獨立,但K1 = K3。

(3)三個密鑰相等。

密鑰選項1的強度最高,擁有3 x 56 = 168個獨立的密鑰位。

密鑰選項2的安全性稍低,擁有2 x 56 = 112個獨立的密鑰位。該選項比簡單的應(yīng)用DES兩次的強度較高,即使用K1和K2,因為它可以防御中途相遇攻擊。

密鑰選項3等同與DES,只有56個密鑰位。這個選項提供了與DES的兼容性,因為第1和第2次DES操作相互抵消了。該選項不再為國家標準科技協(xié)會(NIST)所推薦,亦不為ISO/IEC 18033-3所支持。

2|4C#實現(xiàn)

講真簡介里用來湊字數(shù)的這些內(nèi)容我其實沒怎么看明白

C#中使用TripleDESCryptoServiceProvider類來實現(xiàn)相關(guān)功能

    public static string DesEncrypt(string input, string key)
    {
      byte[] inputArray = Encoding.UTF8.GetBytes(input);
      TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
      tripleDES.Key = Encoding.UTF8.GetBytes(key);
     
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateEncryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      tripleDES.Clear();
      return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

    public static string DesDecrypt(string input, string key)
    {
      byte[] inputArray = Convert.FromBase64String(input);
      TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
      tripleDES.Key = Encoding.UTF8.GetBytes(key);
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateDecryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      tripleDES.Clear();
      return Encoding.UTF8.GetString(resultArray);
    }

從下面源碼中看出,該類接收的Key為16位或24位

然后對于這個Key,C#似乎有自己的處理方式

以下為個人理解:

這個24位的key會被處理成3個8字節(jié)的獨立密鑰參與運算

當(dāng)提供24位key時并沒有什么不妥

但是當(dāng)提供16位的key時 會把提供的key拆分成兩個塊(block) 并以第一個塊作為第三個塊組成一個24位的密鑰

如下:

輸入密鑰:49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 50, 51, 52, 53, 54, 55

實際使用:49, 50, 51, 52, 53, 54, 55, 56, 57, 49, 50, 51, 52, 53, 54, 55, 49, 50, 51, 52, 53, 54, 55, 56

可以看出使用了前8位來進行后面8位的補全

這時候你可能要問,如果提供一個不是16位也不是24位的密鑰時會發(fā)生什么

會拋異常

以上理解都是在.NetFramework中的體現(xiàn)

如果換到NetCore中,效果就又不一樣了

2|5NetCore

在NetCore中不存在TripleDESCryptoServiceProvider 取而代之的是 TripleDES

所以此時我們的代碼需要稍作修改

public static string DesEncrypt(string input, string key)
    {

      byte[] inputArray = Encoding.UTF8.GetBytes(input);
      var tripleDES = TripleDES.Create();
      var byteKey = Encoding.UTF8.GetBytes(key);
      tripleDES.Key = byteKey;
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateEncryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

    public static string DesDecrypt(string input, string key)
    {
      byte[] inputArray = Convert.FromBase64String(input);
      var tripleDES = TripleDES.Create();
      var byteKey = Encoding.UTF8.GetBytes(key);
      tripleDES.Key = byteKey;
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateDecryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      return Encoding.UTF8.GetString(resultArray);
    }

NetCore中同樣要求我們提供24位的Key

但是不在兼容16位的Key,如果你提供一個非24位的Key就會異常

不過沒關(guān)系,對于16位的Key我們可以自行處理一下

同理使用前8位補全后8位

    public static string DesEncrypt(string input, string key)
    {

      byte[] inputArray = Encoding.UTF8.GetBytes(input);
      var tripleDES = TripleDES.Create();
      var byteKey = Encoding.UTF8.GetBytes(key);
      //復(fù)制前8位補全后8位
      byte[] allKey = new byte[24];
      Buffer.BlockCopy(byteKey, 0, allKey, 0, 16);
      Buffer.BlockCopy(byteKey, 0, allKey, 16, 8);
      tripleDES.Key = allKey;
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateEncryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

    public static string DesDecrypt(string input, string key)
    {
      byte[] inputArray = Convert.FromBase64String(input);
      var tripleDES = TripleDES.Create();
      var byteKey = Encoding.UTF8.GetBytes(key);
      //復(fù)制前8位補全后8位
      byte[] allKey = new byte[24];
      Buffer.BlockCopy(byteKey, 0, allKey, 0, 16);
      Buffer.BlockCopy(byteKey, 0, allKey, 16, 8);
      tripleDES.Key = allKey;
      tripleDES.Mode = CipherMode.ECB;
      tripleDES.Padding = PaddingMode.PKCS7;
      ICryptoTransform cTransform = tripleDES.CreateDecryptor();
      byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
      return Encoding.UTF8.GetString(resultArray);
    }

至此就可以正常兼容NetFramework的代碼了

3|0小結(jié)

至此寫下此文,也算是對3DES有了些許了解吧

需要記住

在.NET Core中利用3DES加密和解密必須要給出3個密鑰即24個字節(jié)即使密鑰3和密鑰1相等,它不會像.NET Framework中會重用密鑰1中的位數(shù)。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • C# 設(shè)計模式系列教程-策略模式

    C# 設(shè)計模式系列教程-策略模式

    策略模式是一種定義一系列算法的方法,從概念上來看,所有算法完成的都是相同的工作,只是實現(xiàn)不同,它可以以相同的方式調(diào)用所有的算法,減少了各種算法類與使用算法類之間的耦合。
    2016-06-06
  • C#中foreach循環(huán)對比for循環(huán)的優(yōu)勢和劣勢

    C#中foreach循環(huán)對比for循環(huán)的優(yōu)勢和劣勢

    循環(huán)語句是編程的基本語句,在C#中除了沿用C語言的循環(huán)語句外,還提供了foreach語句來實現(xiàn)循環(huán),下面這篇文章主要給大家介紹了關(guān)于C#中foreach循環(huán)對比for循環(huán)的優(yōu)勢和劣勢,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-09-09
  • c# 控件截圖的簡單實例

    c# 控件截圖的簡單實例

    這篇文章介紹了c# 控件截圖的簡單實例,有需要的朋友可以參考一下
    2013-10-10
  • C#實現(xiàn)快遞api接口調(diào)用方法

    C#實現(xiàn)快遞api接口調(diào)用方法

    這篇文章主要介紹了C#實現(xiàn)快遞api接口調(diào)用方法,主要是通過快遞API網(wǎng)接口的服務(wù),使用的時候直接申請個接口UID即可,有需要的小伙伴來參考下吧。
    2015-03-03
  • Unity 實現(xiàn)鼠標滑過UI時觸發(fā)動畫的操作

    Unity 實現(xiàn)鼠標滑過UI時觸發(fā)動畫的操作

    這篇文章主要介紹了Unity 實現(xiàn)鼠標滑過UI時觸發(fā)動畫的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • C#中IEnumerator<T>和IEnumerable的區(qū)別

    C#中IEnumerator<T>和IEnumerable的區(qū)別

    在C#中,IEnumerator<T>和IEnumerable是用于實現(xiàn)迭代的接口,本文主要介紹了C#中IEnumerator<T>和IEnumerable的區(qū)別,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • 關(guān)于C#中GUI編程的標準事件問題

    關(guān)于C#中GUI編程的標準事件問題

    這篇文章主要介紹了C#中GUI編程的標準事件,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • WPF通過線程使用ProcessBar的方法詳解

    WPF通過線程使用ProcessBar的方法詳解

    這篇文章主要給大家介紹了關(guān)于WPF通過線程使用ProcessBar的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用WPF具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • C#?在PDF中添加墨跡注釋Ink?Annotation的步驟詳解

    C#?在PDF中添加墨跡注釋Ink?Annotation的步驟詳解

    PDF中的墨跡注釋表現(xiàn)為徒手涂鴉式的形狀,該類型的注釋,可任意指定形狀頂點的位置及個數(shù),通過指定的頂點,程序?qū)⑦B接各點繪制成平滑的曲線,下面通過C#程序代碼介紹下在pdf中添加注釋的步驟,感興趣的朋友一起看看吧
    2022-02-02
  • C# 實現(xiàn)QQ式截圖功能實例代碼

    C# 實現(xiàn)QQ式截圖功能實例代碼

    本篇文章主要介紹了C# 實現(xiàn)QQ式截圖功能實例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02

最新評論