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

詳解DES&3DES算法的原理以及C#和JS的實(shí)現(xiàn)

 更新時(shí)間:2023年03月17日 15:23:50   作者:橙子家  
DES?全稱為?Data?Encryption?Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法。3DES?算法通過對?DES?算法進(jìn)行改進(jìn),增加?DES?的密鑰長度來避免類似的攻擊。本文就來聊聊它們的原理與實(shí)現(xiàn)吧

一、簡介

1、DES 簡介

DES 全稱為 Data Encryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn),是一種使用密鑰加密的塊算法,1977 年被美國聯(lián)邦政府的國家標(biāo)準(zhǔn)局確定為聯(lián)邦資料處理標(biāo)準(zhǔn)(FIPS),并授權(quán)在非密級政府通信中使用,隨后該算法在國際上廣泛流傳開來。

在很長時(shí)間內(nèi),許多人心目中“密碼生成”與 DES 一直是個(gè)同義詞。直到 1997 年 NIST(美國國家標(biāo)準(zhǔn)與技術(shù)研究院)開始公開征集更安全的加密算法以替代 DES,并在 2001 年推出了更加安全的 AES(Advanced Encryption Standard)高級加密標(biāo)準(zhǔn)。

優(yōu)點(diǎn):

  • Feistel 網(wǎng)絡(luò)的輪數(shù)可以任意增加;
  • 解密與輪函數(shù) f 無關(guān),輪函數(shù)f也不需要有逆函數(shù);
  • 輪函數(shù)可以設(shè)計(jì)得足夠復(fù)雜;
  • 加密和解密可以使用完全相同的結(jié)構(gòu)來實(shí)現(xiàn)。

缺點(diǎn):

  • 分組比較短;
  • 密鑰太短;
  • 密碼生命周期短;
  • 運(yùn)算速度較慢。

2、3DES 簡介

其實(shí)并不是直接由 DES 過渡到 AES,還有一個(gè) 3DES 統(tǒng)治時(shí)期。3DES 也稱 Triple DES,它使用 3 條 56 位的密鑰對數(shù)據(jù)進(jìn)行三次加密。

3DES 算法通過對 DES 算法進(jìn)行改進(jìn),增加 DES 的密鑰長度來避免類似的攻擊,針對每個(gè)數(shù)據(jù)塊進(jìn)行三次 DES 加密;因此,3DES 加密算法并非什么新的加密算法,是 DES 的一個(gè)更安全的變形,它以 DES 為基本模塊,通過組合分組方法設(shè)計(jì)出分組加密算法。

相比 DES,3DES 因密鑰長度變長,安全性有所提高,但其處理速度不高。因此又出現(xiàn)了 AES 加密算法,AES 較于 3DES 速度更快、安全性也更高。

加密:

為了兼容普通的 DES,3DES 并沒有直接使用 加密->加密->加密 的方式,而是采用了 加密->解密->加密 的方式。

當(dāng)三重密鑰均相同時(shí),前兩步相互抵消,相當(dāng)于僅實(shí)現(xiàn)了一次加密,因此可實(shí)現(xiàn)對普通 DES 加密算法的兼容。

解密:

3DES 解密過程,與加密過程相反,即逆序使用密鑰。是以密鑰 3、密鑰 2、密鑰 1的順序執(zhí)行 解密->加密->解密。

二、C# 代碼實(shí)現(xiàn)

1、DES

// 測試(密鑰需要是八位字符)
string jiamihou = DesEncrypt("TestString", "11111222", false); // 57fe567eaa866373f851a526f07d9e26
string jiamiqian = DesDecrypt(jiamihou32, "11111222");
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="deseninstr">待加密的字符串</param>
/// <param name="deskey">加密密鑰,要求為8位</param>
/// <param name="isupper">返回大寫密文,false:小寫</param>
/// <returns>加密成功返回加密后的字符串,失敗返回源串</returns>
public static string DesEncrypt(string deseninstr, string deskey, bool isupper = true)
{
    StringBuilder stringBuilder = new StringBuilder();
    try
    {
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        byte[] inputByteArray = Encoding.UTF8.GetBytes(deseninstr);
        des.Key = Encoding.UTF8.GetBytes(deskey);
        des.IV = Encoding.UTF8.GetBytes(deskey); // 當(dāng) mode 為 CBC 時(shí),偏移量必傳
        des.Mode=CipherMode.ECB; // 為空默認(rèn) CBC
        MemoryStream memoryStream = new MemoryStream();
        CryptoStream cryptoStream = new CryptoStream(memoryStream, des.CreateEncryptor(), CryptoStreamMode.Write);
        cryptoStream.Write(inputByteArray, 0, inputByteArray.Length);
        cryptoStream.FlushFinalBlock();
        foreach (byte bb in memoryStream.ToArray())
        {
            stringBuilder.AppendFormat(isupper ? "{0:X2}" : "{0:x2}", bb);
        }
        return stringBuilder.ToString();
    }
    catch (Exception ex)
    {
        return deseninstr;
    }
}
/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="desdeinstr">待解密的字符串</param>
/// <param name="deskey">解密密鑰,要求為8位</param>
/// <returns>解密成功返回解密后的字符串,失敗返源串</returns>
public static string DesDecrypt(string desdeinstr, string deskey)
{
    MemoryStream memoryStream = new MemoryStream();
    try
    {
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        byte[] inputByteArray = new byte[desdeinstr.Length / 2];
        for (int ii = 0; ii < desdeinstr.Length / 2; ii++)
        {
            int intt = (Convert.ToInt32(desdeinstr.Substring(ii * 2, 2), 16));
            inputByteArray[ii] = (byte)intt;
        }
        des.Key = Encoding.UTF8.GetBytes(deskey);
        des.IV = Encoding.UTF8.GetBytes(deskey); // 當(dāng) mode 為 CBC 時(shí),偏移量必傳
        des.Mode = CipherMode.ECB; // 為空默認(rèn) CBC
        CryptoStream cs = new CryptoStream(memoryStream, des.CreateDecryptor(), CryptoStreamMode.Write);
        cs.Write(inputByteArray, 0, inputByteArray.Length);
        cs.FlushFinalBlock();
        return Encoding.UTF8.GetString(memoryStream.ToArray());
    }
    catch
    {
        return desdeinstr;
    }
}

2、3DES

密文采用 Base64 格式輸出。

疑問解答:三次加解密操作會運(yùn)用三個(gè)不同的 Key,但是我們只傳入了一個(gè)密鑰,怎么回事?

3DES 密鑰必須為 24 位,為 DES 的 3 倍,經(jīng)測試得出結(jié)論:

TripleDESCryptoServiceProvider 內(nèi)部將密鑰分成 3 份,進(jìn)行了加密解密三重操作。

我們把 24 位字符串分成三部分,如果三部分均相等,或前兩部分相等,就會報(bào)錯(cuò):"Specified key is a known weak key for 'TripleDES' and cannot be used."--指定的密鑰是'TripleDES'的已知弱密鑰,不能使用。

// 測試
string jiamihou16 = SecurityDES.Des3Encrypt("TestString", "111112222233333444445555", "12345678"); // yJGf3qgWyoAQeaPY2S5Etg==
string jiamihou32 = SecurityDES.Des3Decrypt(jiamihou16, "111112222233333444445555", "12345678");
/// <summary>
/// 3DES 加密
/// </summary>
/// <param name="des3eninstr"></param>
/// <param name="des3key">24 位</param>
/// <param name="des3iv">8 位</param>
/// <returns></returns>
public static string Des3Encrypt(string des3eninstr, string des3key, string des3iv)
{
    string encryptPassword = string.Empty;
    SymmetricAlgorithm algorithm = new TripleDESCryptoServiceProvider();
    algorithm.Key = Encoding.UTF8.GetBytes(des3key);// Convert.FromBase64String(des3key);
    algorithm.IV = Encoding.UTF8.GetBytes(des3iv);
    algorithm.Mode = CipherMode.ECB;
    algorithm.Padding = PaddingMode.PKCS7;
    ICryptoTransform transform = algorithm.CreateEncryptor();
    byte[] data = Encoding.UTF8.GetBytes(des3eninstr);
    MemoryStream memoryStream = new MemoryStream();
    CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
    cryptoStream.Write(data, 0, data.Length);
    cryptoStream.FlushFinalBlock();
    encryptPassword = Convert.ToBase64String(memoryStream.ToArray());
    memoryStream.Close();
    cryptoStream.Close();
    return encryptPassword;
}
/// <summary>
/// 3DES 解密
/// </summary>
/// <param name="des3deinstr">密文 Base64</param>
/// <param name="des3key">24 位</param>
/// <param name="des3iv">8 位</param>
/// <returns></returns>
public static string Des3Decrypt(string des3deinstr, string des3key, string des3iv)
{
    string decryptPassword = string.Empty;
    SymmetricAlgorithm algorithm = new TripleDESCryptoServiceProvider();
    algorithm.Key = Encoding.UTF8.GetBytes(des3key);
    algorithm.IV = Encoding.UTF8.GetBytes(des3iv);
    algorithm.Mode = CipherMode.ECB;
    algorithm.Padding = PaddingMode.PKCS7;
    ICryptoTransform transform = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV);
    byte[] buffer = Convert.FromBase64String(des3deinstr);
    MemoryStream memoryStream = new MemoryStream(buffer);
    CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
    StreamReader reader = new StreamReader(cryptoStream, System.Text.Encoding.ASCII);
    decryptPassword = reader.ReadToEnd();
    reader.Close();
    cryptoStream.Close();
    memoryStream.Close();
    return decryptPassword;
}

三、js 語言實(shí)現(xiàn) 

以下是通過 crypto-js.js 實(shí)現(xiàn)。

1、DES

注意:mode 為空默認(rèn) CBC,此時(shí)偏移量 iv 不可為空。

注意:密鑰可用位數(shù)為 8,如果超過 8 位以后的對加密結(jié)果無影響,且不會報(bào)錯(cuò)。

// 先引入 js 文件
<script src="http://cdn.bootcdn.net/ajax/libs/crypto-js/4.0.0/crypto-js.js"></script>
// npm(Node.js package manager)方式
> npm install crypto-js
 
// 調(diào)用方法 message() 查看測試結(jié)果
function message(){
    var outdata_value = encryptByDES("TestString", "11111222");
    alert(outdata_value) // 57fe567eaa866373f851a526f07d9e26
    console.log("outdata_value-aes_encrypt:", outdata_value);
    outdata_value = decryptByDES(outdata_value, "11111222");
    alert(outdata_value)
    console.log("outdata_value-aes_decrypt:", outdata_value);
}
//DES 加密
function encryptByDES(deseninstr, keystr, ivstr = keystr) {
    var keybyte = CryptoJS.enc.Utf8.parse(keystr);
    var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
    let afterEncrypt = CryptoJS.DES.encrypt(deseninstr, keybyte, {
        iv: ivbyte, // 當(dāng) mode 為 CBC 時(shí),偏移量必傳
        mode: CryptoJS.mode.ECB, // 為空默認(rèn) CBC
        padding: CryptoJS.pad.Pkcs7
    }).ciphertext.toString()
    console.log(afterEncrypt)
    return afterEncrypt
}
//DES 解密
function decryptByDES(desdeinstr, keystr, ivstr = keystr) {
    var keybyte = CryptoJS.enc.Utf8.parse(keystr);
    var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
    var decrypted = CryptoJS.DES.decrypt(
        { ciphertext: CryptoJS.enc.Hex.parse(desdeinstr) },
        keybyte,
        {
            iv: ivbyte, // 當(dāng) mode 為 CBC 時(shí),偏移量必傳
            mode: CryptoJS.mode.ECB, // 為空默認(rèn) CBC
            padding: CryptoJS.pad.Pkcs7
        }
    );
    console.log(decrypted);
    var result_value = decrypted.toString(CryptoJS.enc.Utf8);
    return result_value;
}

2、3DES

// 調(diào)用方法 message() 查看測試結(jié)果
function message() {
    var outdata_value = encryptByDES("TestString", "111112222233333444445555");
    alert(outdata_value) // yJGf3qgWyoAQeaPY2S5Etg==
        console.log("outdata_value-3des_encrypt:", outdata_value);
    outdata_value = decryptByDES(outdata_value, "111112222233333444445555");
    alert(outdata_value)
        console.log("outdata_value-3des_decrypt:", outdata_value);
}
// 加密 密鑰需為 24 位,偏移量需為 8 位
function encryptByDES(deseninstr, keystr) {
    var keybyte = CryptoJS.enc.Utf8.parse(keystr);
    //var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
    var encrypted = CryptoJS.TripleDES.encrypt(deseninstr, keybyte, {
        // iv: ivbyte, // 當(dāng) mode 為 CBC 時(shí),偏移量必傳
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
        });
    return encrypted.toString();
}
// 解密 密鑰需為 24 位,偏移量需為 8 位
function decryptByDES(desdeinstr, keystr) {
    var keybyte = CryptoJS.enc.Utf8.parse(keystr);
    //var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
    var decrypted = CryptoJS.TripleDES.decrypt(desdeinstr, keybyte, {
        // iv: ivbyte, // 當(dāng) mode 為 CBC 時(shí),偏移量必傳
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.Pkcs7
        });
    return decrypted.toString(CryptoJS.enc.Utf8);
}

到此這篇關(guān)于詳解DES&3DES算法的原理以及C#和JS的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)DES算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Git工作流模式及命令的使用講解

    Git工作流模式及命令的使用講解

    這篇文章主要為大家介紹了Git的工作流模式及命令的使用講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 淺談vscode中task.json和launch.json的關(guān)系

    淺談vscode中task.json和launch.json的關(guān)系

    本文主要介紹了淺談vscode中task.json和launch.json的關(guān)系,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 微信 小程序前端源碼詳解及實(shí)例分析

    微信 小程序前端源碼詳解及實(shí)例分析

    這篇文章主要介紹了微信 小程序前端源碼詳解及實(shí)例分析的相關(guān)資料,需要的朋友可以參考下
    2016-09-09
  • 利用ChatGPT與MindShow制作一個(gè)PPT的方法詳解

    利用ChatGPT與MindShow制作一個(gè)PPT的方法詳解

    PPT制作是商務(wù)、教育和各種場合演講的重要組成部分,然而,很多人會花費(fèi)大量時(shí)間和精力在內(nèi)容生成和視覺設(shè)計(jì)方面,為了解決這個(gè)問題,我們可以利用兩個(gè)強(qiáng)大的工具——ChatGPT和MindShow,來提高制作PPT的效率,感興趣的同學(xué)可以參考閱讀
    2023-06-06
  • 5G頻段闡述

    5G頻段闡述

    這篇文章主要介紹了5G頻段闡述方法的相關(guān)資料,需要的小伙伴可以參考下面
    2021-08-08
  • asp php 清空access mysql mssql數(shù)據(jù)庫的代碼

    asp php 清空access mysql mssql數(shù)據(jù)庫的代碼

    php清空mysql asp情況access或mssql
    2008-12-12
  • VS2019 自定義項(xiàng)目模板的實(shí)現(xiàn)方法

    VS2019 自定義項(xiàng)目模板的實(shí)現(xiàn)方法

    這篇文章主要介紹了VS2019 自定義項(xiàng)目模板的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Xmind8?Pro?最新激活序列號

    Xmind8?Pro?最新激活序列號

    最近需要打開文件后綴名為.xmind的文件,所以下載了Xmind8?。打開以后想要導(dǎo)出,奈何普通版本只能導(dǎo)出.txt文本文檔,所以就總結(jié)出了這篇文章,對Xmind8?Pro破解方法感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • 編程知識點(diǎn)(1)關(guān)鍵詞之存儲類型

    編程知識點(diǎn)(1)關(guān)鍵詞之存儲類型

    這篇文章主要介紹了編程知識點(diǎn)(1)關(guān)鍵詞之存儲類型的相關(guān)知識,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-07-07
  • UTC時(shí)間、GMT時(shí)間、本地時(shí)間、Unix時(shí)間戳的具體使用

    UTC時(shí)間、GMT時(shí)間、本地時(shí)間、Unix時(shí)間戳的具體使用

    本文主要介紹了UTC時(shí)間、GMT時(shí)間、本地時(shí)間、Unix時(shí)間戳的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論