javascript JS CryptoJS DES加解密CBC模式與C#DES加解密相同互通

咱們只知道不一樣的語言解密要相互通用,就須要遵循相同的加密方式,然而在具體作技術預研的時候,就發現會遇到不少問題,網上找的資料也是比較片面,因此我踩了坑,而且把解決方案和相關資料源碼提供出來,給須要的朋友一些參考。javascript

場景:網頁客戶端(html)頁面經過在發起請求時,將數據加密發送給C#編寫的後端。C#後端接受到數據後須要進行解密,解密後獲得明文,用明文進行業務操做,操做完成後,將結果加密返回。html

由於C#後端使用的是DES CBC模式,因此前端JS也要使用相同的方式。不然加密解密結果不以言,就沒法互通了。前端

 

 

使用技術:java

1.前端javascript 使用CryptoJS進行加解密。jquery

2.使用System.Security.Cryptography 命名空間下的相關類。git

前端核心代碼:後端

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>JS_DES加解密CBC模式與C#DES加解密相同互通</title>
    <script type="text/javascript">
        function CBCJiami() { var key = $("#desKey").val(); var iv = $("#desIV").val(); var msg = $("#source").val(); var dd = encryptByDES(msg, key, iv); $("#JiaMiHou").val(dd); $("#target").val(toBase641(dd)); } function CBCJiemi() { var key = $("#desKey").val(); var iv = $("#desIV").val(); var msg = $("#JiaMiHou").val(); var dd = decryptByDESModeEBC(msg, key, iv); $("#CBCJiemi").val(dd); } // DES CBC模式加密
        //加密內容、祕鑰、向量
        function encryptByDES(message, key, iv) { var keyHex = CryptoJS.enc.Utf8.parse(key); var ivHex = CryptoJS.enc.Utf8.parse(iv); encrypted = CryptoJS.DES.encrypt(message, keyHex, { iv: ivHex, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ); return encrypted.ciphertext.toString(); } //DES CBC模式解密
        function decryptByDESModeEBC(ciphertext, key, iv) { //把私鑰轉換成UTF - 8編碼的字符串
            var keyHex = CryptoJS.enc.Utf8.parse(key); var ivHex = CryptoJS.enc.Utf8.parse(iv); // direct decrypt ciphertext
            var decrypted = CryptoJS.DES.decrypt({ ciphertext: CryptoJS.enc.Hex.parse(ciphertext) }, keyHex, { iv: ivHex, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return decrypted.toString(CryptoJS.enc.Utf8); } //十六進制字符串轉爲base64
        function toBase641(input) { var digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; var base64_rep = ""; var cnt = 0; var bit_arr = 0; var bit_num = 0; for (var n = 0; n < input.length; ++n) { if (input[n] >= 'A' && input[n] <= 'Z') { ascv = input.charCodeAt(n) - 55; } else if (input[n] >= 'a' && input[n] <= 'z') { ascv = input.charCodeAt(n) - 87; } else { ascv = input.charCodeAt(n) - 48; } bit_arr = (bit_arr << 4) | ascv; bit_num += 4; if (bit_num >= 6) { bit_num -= 6; base64_rep += digits[bit_arr >>> bit_num]; bit_arr &= ~(-1 << bit_num); } } if (bit_num > 0) { bit_arr <<= 6 - bit_num; base64_rep += digits[bit_arr]; } var padding = base64_rep.length % 4; if (padding > 0) { for (var n = 0; n < 4 - padding; ++n) { base64_rep += "="; } } return base64_rep; } </script>
    <script src="jquery-3.4.1.min.js"></script>
    <script src="CryptoJS v3.1.2/rollups/tripledes.js"></script>
    <script src="CryptoJS v3.1.2/components/mode-ecb-min.js"></script>
    <script src="Base64Helper.js"></script>
</head>
<body>
    <div>
        <fieldset>
            <legend>DES CBC模式加密</legend>
            Key:<input type="text" id="desKey" value="z9j#$@4D">
            <br />
            IV:<input type="text" id="desIV" value="x34dg!df">
            <br />
            MSG:<input id="source" value="{}" />
            <br />
            <input type="button" onclick="CBCJiami();" name="" value="CBC加密" />
            <br />
            加密後:<input id="JiaMiHou" value="" />
            <br />
            轉base64後:<input id="target" value="" />
            <br />
            <input type="button" onclick="CBCJiemi();" name="" value="CBC解密" />
            <br />
            解密後:<input id="CBCJiemi" value="" />
        </fieldset>
    </div>
</body>
</html>

後端核心代碼:數組

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

namespace WindowsFormsTest
{
    public class DESHelper
    {
        /// <summary>
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密鑰,要求爲8位</param>
        /// <returns>加密成功返回加密後的字符串,失敗返回源串</returns>
        public static string EncryptDES(string encryptString, string encryptKey, string iv)
        {
            try
            {
                //將字符轉換爲UTF - 8編碼的字節序列
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = Encoding.UTF8.GetBytes(iv);
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                //用指定的密鑰和初始化向量建立CBC模式的DES加密標準
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                dCSP.Mode = CipherMode.CBC;
                dCSP.Padding = PaddingMode.PKCS7;
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);//寫入內存流
                cStream.FlushFinalBlock();//將緩衝區中的數據寫入內存流,並清除緩衝區
                return Convert.ToBase64String(mStream.ToArray()); //將內存流轉寫入字節數組並轉換爲string字符
            }
            catch
            {
                return encryptString;
            }
        }

        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密鑰,要求爲8位,和加密密鑰相同</param>
        /// <returns>解密成功返回解密後的字符串,失敗返源串</returns>
        public static string DecryptDES(string decryptString, string decryptKey, string iv)
        {
            try
            {
                //將字符轉換爲UTF - 8編碼的字節序列
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey.Substring(0, 8));
                byte[] rgbIV = Encoding.UTF8.GetBytes(iv);
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                //用指定的密鑰和初始化向量使用CBC模式的DES解密標準解密
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                dCSP.Mode = CipherMode.CBC;
                dCSP.Padding = PaddingMode.PKCS7;
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }


        }
    }
}

  運行效果:網絡

 

 

 

 

 

 其中要注意一點:前端加密後有個轉Base64的操做,加密解密後纔會相同,緣由是C#加密後的數據是轉成base64的。ide

多說無益,直接上代碼: https://pan.baidu.com/s/1albbwY3l2aVakBboVIOCeA

最後感謝網絡上我參考過的文章、博客。有的代碼是直接抄過來改的,參考太多沒法一一列出,但要感謝他們無私精神。

 

原文出處:https://www.cnblogs.com/yuanjiedao/p/11471078.html

相關文章
相關標籤/搜索