iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
Security

走進資安現場: JavaScript資安逆向工程超實戰系列 第 15

Day 15 Node.js 如何生成 AES、DES 加解密

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250914/20169775ktRIpfZtuH.jpg

本系列文章所討論的 JavaScript 資安與逆向工程技術,旨在分享知識、探討防禦之道,並促進技術交流。
所有內容僅供學術研究與學習,請勿用於任何非法或不道德的行為。
讀者應對自己的行為負完全責任。尊重法律與道德規範是所有技術人員應共同遵守的準則。

本文同步發佈:https://nicklabs.cc/node-generate-aes-des

在前面文章我們已經介紹過 AES 與 DES 今天直接實戰使用 CryptoJS 來進行加解密。

這個套件不僅能在 Node.js 執行,也能用於瀏覽器端是常見的跨平台加密工具。

安裝CryptoJS

在開始之前需要先安裝crypto-js

npm install crypto-js

使用 CryptoJS 進行 AES 加解密

加密

const CryptoJS = require('crypto-js');

// 定義明文與金鑰
const plaintext = '這是一段需要加密的訊息';
const key = 'mysecretkey12345';

// AES 加密
const encrypted = CryptoJS.AES.encrypt(plaintext, key).toString();
console.log('AES 加密結果:', encrypted);
// U2FsdGVkX19lJKdBzINe0XHv3u6B7rJR+1sVeBdHSIgHoSTOeiR9tooijiWhPVH1EkhsRvWcv82I8nUOSI+kpw==

解密

const CryptoJS = require('crypto-js');

// 定義明文與金鑰
const encrypted = 'U2FsdGVkX19lJKdBzINe0XHv3u6B7rJR+1sVeBdHSIgHoSTOeiR9tooijiWhPVH1EkhsRvWcv82I8nUOSI+kpw==';
const key = 'mysecretkey12345';

// AES 解密
const decrypted = CryptoJS.AES.decrypt(encrypted, key).toString(CryptoJS.enc.Utf8);
console.log('AES 解密結果:', decrypted);

使用 CryptoJS 進行 DES 加解密

加密

const CryptoJS = require('crypto-js');

// 定義明文與金鑰
const plaintext = '這是一段需要加密的訊息';
const key = 'mysecretkey12345';

// DES 加密
const encrypted = CryptoJS.DES.encrypt(plaintext, key).toString();
console.log('DES 加密結果:', encrypted);
// U2FsdGVkX18ubSrFJTFdrkq1jeOfosvR7mgzeeD+11LJIJNg3jxDH/zaPFFWwqenMug0ypCO7aE=

解密

const CryptoJS = require('crypto-js');

// 定義明文與金鑰
const encrypted = 'U2FsdGVkX18ubSrFJTFdrkq1jeOfosvR7mgzeeD+11LJIJNg3jxDH/zaPFFWwqenMug0ypCO7aE=';
const key = 'mysecretkey12345';

// DES 加密
const decrypted = CryptoJS.DES.decrypt(encrypted, key).toString(CryptoJS.enc.Utf8);
console.log('DES 解密結果:', decrypted);

AES 進階用法

CryptoJS允許自訂加密模式與填充方式

加密

const CryptoJS = require('crypto-js');

const plaintext = '這是一段需要加密的訊息';
const key = 'mysecretkey12345';
const iv = 'myiv1234567890ab';

// AES 加密
const encrypted = CryptoJS.AES.encrypt(plaintext, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
}).toString();
console.log('進階 AES 加密結果:', encrypted);
// NUPcMxB0H5ukiqbEpkq5rdpiPNOIZsl2BJt3Yfh/7oivvtIxljobilpLJxmssjr1

解密

const CryptoJS = require('crypto-js');

const encrypted = 'NUPcMxB0H5ukiqbEpkq5rdpiPNOIZsl2BJt3Yfh/7oivvtIxljobilpLJxmssjr1';
const key = 'mysecretkey12345';
const iv = 'myiv1234567890ab';

// AES 解密
const decrypted = CryptoJS.AES.decrypt(encrypted, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
console.log('進階 AES 解密結果:', decrypted);

DES 進階用法

CryptoJS允許自訂加密模式與填充方式

加密

const CryptoJS = require('crypto-js');

const plaintext = '這是一段需要加密的訊息';
const key = 'mysecretkey12345';
const iv = 'myiv1234567890ab'; // 初始向量,長度需為 16 字元

// DES 加密
const encrypted = CryptoJS.DES.encrypt(plaintext, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
}).toString();
console.log('進階 DES 加密結果:', encrypted);
// LMUmriEqSzUlXLDDl8gCQx5vVXUuvNi9pDj9rOAIJb5wxeZr6+OJBQ==

解密

const CryptoJS = require('crypto-js');

const encrypted = 'LMUmriEqSzUlXLDDl8gCQx5vVXUuvNi9pDj9rOAIJb5wxeZr6+OJBQ==';
const key = 'mysecretkey12345';
const iv = 'myiv1234567890ab';

// DES 解密
const decrypted = CryptoJS.DES.decrypt(encrypted, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
}).toString(CryptoJS.enc.Utf8);
console.log('進階 DES 解密結果:', decrypted);

Mode模式

可控制當「超過一個區塊的資料」該怎麼加密,總共有ECB、CBC、CFB、OFB、CTR五種模式可選擇。

比較常使用的是ECB模式及CBC模式。

ECB

每個區塊獨立加密,相同明文區塊會得到相同密文,容易被模式分析攻擊。

CBC

每個區塊加密前會與前一個密文做 XOR,第一塊用 IV,安全性比 ECB 高。

CFB/OFB/CTR

適合串流或大量資料。

Padding模式

區塊加密演算法要求輸入資料的長度必須是塊大小的整數倍。

如果明文長度不足必須在加密前進行「填充」額外的資料,這就是 padding 的作用。

Pkcs7

最常用的填充方式,在資料後補充若干字節,每個字節的值等於填充的字節數。

NoPadding

不進行填充適用於明文長度已符合塊大小的情況,但需自行確保資料長度正確。

ZeroPadding 用零(0x00)填充剩餘空間但不推薦使用,因為可能與資料中的零混淆。

ISO10126 或 ANSIX923

其他標準填充方式較少使用。


上一篇
Day 14 JSVMP 實戰觀察:逐步還原 switch-case VM 混淆程式
系列文
走進資安現場: JavaScript資安逆向工程超實戰15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言