From e8888756a24538bca7d1d1f5395c9dbd89467165 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=88=B1=E5=96=9D=E6=B0=B4=E7=9A=84=E6=9C=A8=E5=AD=90?=
<50564847+ice-a@users.noreply.github.com>
Date: Fri, 29 Aug 2025 15:33:42 +0800
Subject: [PATCH] Update 08.aes.md
---
.../08.aes.md" | 298 +++++++++++++++++-
1 file changed, 297 insertions(+), 1 deletion(-)
diff --git "a/docs/03.\350\276\205\345\212\251\346\237\245\350\257\242/04.\345\212\240\345\257\206\347\256\227\346\263\225/08.aes.md" "b/docs/03.\350\276\205\345\212\251\346\237\245\350\257\242/04.\345\212\240\345\257\206\347\256\227\346\263\225/08.aes.md"
index e137c5430..1584ec6f7 100644
--- "a/docs/03.\350\276\205\345\212\251\346\237\245\350\257\242/04.\345\212\240\345\257\206\347\256\227\346\263\225/08.aes.md"
+++ "b/docs/03.\350\276\205\345\212\251\346\237\245\350\257\242/04.\345\212\240\345\257\206\347\256\227\346\263\225/08.aes.md"
@@ -7,6 +7,15 @@ article: false
::: details 关于
+# AES加密核心参数说明表
+| 参数 | 说明 | 可选值(推荐) |
+| ---- | ---- | ---- |
+| 密钥长度 | AES 标准密钥长度,决定加密强度(对称加密中密钥需双方共享,长度需一致) | 128 位、192 位、256 位(推荐 256 位) |
+| 加密模式 | 数据分组的处理方式,需加密 / 解密端保持一致 | CBC(需 IV)、GCM(带认证,更安全) |
+| 填充方式 | 当数据长度不足分组长度(16 字节)时的补全规则 | PKCS#7(通用)、ZeroPadding |
+| 初始向量(IV) | 仅 CBC/GCM 等模式需用,随机生成(每次加密不同),需和密文一起传输 | 16 字节随机数(CBC)、12 字节(GCM) |
+| 密钥格式 | 通常用 Base64 编码存储 / 传输,便于文本格式处理 | Base64 字符串(推荐)、Hex 字符串 |
+
::: right
AES [维基百科]()
:::
@@ -16,9 +25,90 @@ AES [维基百科]()
-
+ ```python
+ import base64
+import os
+from Crypto.Cipher import AES
+from Crypto.Util.Padding import pad, unpad # 处理PKCS#7填充
+
+def generate_aes_key(key_size=256):
+ """生成AES密钥(256位),返回Base64编码的密钥字符串(便于存储/传输)"""
+ if key_size not in [128, 192, 256]:
+ raise ValueError("AES密钥长度仅支持128、192、256位")
+ # 生成对应字节数的随机密钥(1位=8字节,256位=32字节)
+ key_bytes = os.urandom(key_size // 8)
+ return base64.b64encode(key_bytes).decode("utf-8")
+
+def aes_encrypt_gcm(plaintext, aes_key_b64):
+ """
+ AES-GCM模式加密(带认证,防篡改)
+ :param plaintext: 待加密明文(字符串)
+ :param aes_key_b64: Base64编码的AES密钥
+ :return: 字典(包含密文、IV、认证标签,需一起传输给解密端)
+ """
+ # 1. 解码Base64密钥
+ key_bytes = base64.b64decode(aes_key_b64)
+ # 2. 生成GCM模式所需的12字节IV(GCM推荐IV长度12字节,安全性更高)
+ iv = os.urandom(12)
+ # 3. 初始化AES加密器(GCM模式)
+ cipher = AES.new(key_bytes, AES.MODE_GCM, nonce=iv)
+ # 4. 加密(GCM无需额外填充,自动处理分组)
+ ciphertext_bytes, tag = cipher.encrypt_and_digest(plaintext.encode("utf-8"))
+ # 5. 密文、IV、标签均用Base64编码(便于文本传输,如JSON/HTTP)
+ return {
+ "ciphertext": base64.b64encode(ciphertext_bytes).decode("utf-8"),
+ "iv": base64.b64encode(iv).decode("utf-8"),
+ "tag": base64.b64encode(tag).decode("utf-8")
+ }
+
+def aes_decrypt_gcm(encrypted_data, aes_key_b64):
+ """
+ AES-GCM模式解密
+ :param encrypted_data: 加密后的数据字典(ciphertext、iv、tag)
+ :param aes_key_b64: Base64编码的AES密钥
+ :return: 解密后的明文(字符串)
+ """
+ try:
+ # 1. 解码各参数
+ key_bytes = base64.b64decode(aes_key_b64)
+ iv = base64.b64decode(encrypted_data["iv"])
+ ciphertext_bytes = base64.b64decode(encrypted_data["ciphertext"])
+ tag = base64.b64decode(encrypted_data["tag"])
+ # 2. 初始化AES解密器(需传入IV和标签)
+ cipher = AES.new(key_bytes, AES.MODE_GCM, nonce=iv)
+ # 3. 解密并验证标签(标签不匹配会抛异常,说明数据被篡改)
+ plaintext_bytes = cipher.decrypt_and_verify(ciphertext_bytes, tag)
+ return plaintext_bytes.decode("utf-8")
+ except Exception as e:
+ raise ValueError(f"解密失败(数据可能被篡改或参数错误):{str(e)}")
+
+# ------------------------------ 示例:使用流程 ------------------------------
+if __name__ == "__main__":
+ # 1. 生成AES密钥(仅需生成一次,双方保存,切勿泄露)
+ aes_key = generate_aes_key(key_size=256)
+ print(f"AES-256密钥(Base64):\n{aes_key}\n")
+
+ # 2. 加密数据(如敏感信息、长文本)
+ plaintext = "这是需要加密的敏感数据:SpiderAPI - 虫术,包含RSA/AES混合加密场景"
+ encrypted = aes_encrypt_gcm(plaintext, aes_key)
+ print(f"加密后数据:\n{encrypted}\n")
+
+ # 3. 解密数据(解密端需获取加密后的ciphertext、iv、tag)
+ decrypted = aes_decrypt_gcm(encrypted, aes_key)
+ print(f"解密后明文:\n{decrypted}")
+ """
+ AES-256密钥(Base64):
+d2fril3Gq2mvYw1wePmDGoA/sWcosbs/g=
+
+加密后数据:
+{'ciphertext': 'udcsoo1u7740Odjr9584FM8qzfO0jNqOGeYSZ4uNvcsADfl6EcK1Ya1bOwp7swvqnsY/IEX6HkotLz3PefJYEeED2QDdDD+KPHu7snxsFECg==', 'iv': 'wUnusEDh53Qgqull', 'tag': 'XmYBjOZgLXOAPWScjxhLZQ=='}
+
+解密后明文:
+这是需要加密的敏感数据:SpiderAPI - 虫术,包含RSA/AES混合加密场景
+"""
+ ```
## JavaScript
@@ -28,6 +118,85 @@ AES [维基百科]()
+ ```javascript
+ const crypto = require("crypto");
+
+/**
+ * 生成AES密钥(256位),返回Base64编码的密钥
+ * @param {number} keySize - 密钥长度(128/192/256)
+ * @returns {string} Base64编码的AES密钥
+ */
+function generateAesKey(keySize = 256) {
+ if (![128, 192, 256].includes(keySize)) {
+ throw new Error("AES密钥长度仅支持128、192、256位");
+ }
+ // 生成对应字节数的随机密钥(256位=32字节)
+ const keyBytes = crypto.randomBytes(keySize / 8);
+ return keyBytes.toString("base64");
+}
+
+/**
+ * AES-GCM模式加密
+ * @param {string} plaintext - 待加密明文
+ * @param {string} aesKeyB64 - Base64编码的AES密钥
+ * @returns {object} 包含ciphertext(密文)、iv(初始向量)、tag(认证标签)的对象
+ */
+function aesEncryptGcm(plaintext, aesKeyB64) {
+ // 1. 解码Base64密钥
+ const keyBytes = Buffer.from(aesKeyB64, "base64");
+ // 2. 生成12字节IV(GCM推荐长度)
+ const iv = crypto.randomBytes(12);
+ // 3. 初始化加密器(GCM模式,自动处理分组,无需额外填充)
+ const cipher = crypto.createCipheriv("aes-256-gcm", keyBytes, iv);
+ // 4. 加密(分两段处理:update+final,兼容长文本)
+ let ciphertext = cipher.update(plaintext, "utf8", "base64");
+ ciphertext += cipher.final("base64");
+ // 5. 获取认证标签(GCM模式必须,用于解密时验证数据完整性)
+ const tag = cipher.getAuthTag().toString("base64");
+ return { ciphertext, iv: iv.toString("base64"), tag };
+}
+
+/**
+ * AES-GCM模式解密
+ * @param {object} encryptedData - 加密数据({ciphertext, iv, tag})
+ * @param {string} aesKeyB64 - Base64编码的AES密钥
+ * @returns {string} 解密后的明文
+ */
+function aesDecryptGcm(encryptedData, aesKeyB64) {
+ try {
+ // 1. 解码各参数
+ const keyBytes = Buffer.from(aesKeyB64, "base64");
+ const iv = Buffer.from(encryptedData.iv, "base64");
+ const ciphertext = Buffer.from(encryptedData.ciphertext, "base64");
+ const tag = Buffer.from(encryptedData.tag, "base64");
+ // 2. 初始化解密器(需传入IV和标签)
+ const decipher = crypto.createDecipheriv("aes-256-gcm", keyBytes, iv);
+ decipher.setAuthTag(tag); // 设置认证标签,验证数据完整性
+ // 3. 解密(分两段处理)
+ let plaintext = decipher.update(ciphertext, null, "utf8");
+ plaintext += decipher.final("utf8");
+ return plaintext;
+ } catch (error) {
+ throw new Error(`解密失败(数据篡改或参数错误):${error.message}`);
+ }
+}
+
+// ------------------------------ 示例:使用流程 ------------------------------
+(function () {
+ // 1. 生成AES密钥
+ const aesKey = generateAesKey(256);
+ console.log(`AES-256密钥(Base64):\n${aesKey}\n`);
+
+ // 2. 加密数据
+ const plaintext = "这是需要加密的敏感数据:SpiderAPI - 虫术,包含RSA/AES混合加密场景";
+ const encrypted = aesEncryptGcm(plaintext, aesKey);
+ console.log("加密后数据:\n", JSON.stringify(encrypted, null, 2), "\n");
+
+ // 3. 解密数据
+ const decrypted = aesDecryptGcm(encrypted, aesKey);
+ console.log(`解密后明文:\n${decrypted}`);
+})();
+ ```
@@ -38,6 +207,133 @@ AES [维基百科]()
+ ```go
+ package main
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/base64"
+ "encoding/json"
+ "fmt"
+ "io"
+)
+
+// AESKey 封装AES密钥相关操作
+type AESKey struct {
+ KeySize int // 密钥长度(128/192/256)
+ KeyB64 string // Base64编码的密钥
+}
+
+// GenerateAESKey 生成AES密钥(默认256位)
+func GenerateAESKey(keySize int) (*AESKey, error) {
+ if keySize != 128 && keySize != 192 && keySize != 256 {
+ return nil, fmt.Errorf("AES密钥长度仅支持128、192、256位,当前输入:%d", keySize)
+ }
+ // 生成对应字节数的随机密钥(256位=32字节)
+ keyBytes := make([]byte, keySize/8)
+ if _, err := io.ReadFull(rand.Reader, keyBytes); err != nil {
+ return nil, fmt.Errorf("生成密钥失败:%w", err)
+ }
+ return &AESKey{
+ KeySize: keySize,
+ KeyB64: base64.StdEncoding.EncodeToString(keyBytes),
+ }, nil
+}
+
+// AESEncryptGCM AES-GCM模式加密
+func (k *AESKey) AESEncryptGCM(plaintext string) (map[string]string, error) {
+ // 1. 解码Base64密钥
+ keyBytes, err := base64.StdEncoding.DecodeString(k.KeyB64)
+ if err != nil {
+ return nil, fmt.Errorf("密钥解码失败:%w", err)
+ }
+ // 2. 创建AES块
+ block, err := aes.NewCipher(keyBytes)
+ if err != nil {
+ return nil, fmt.Errorf("初始化AES块失败:%w", err)
+ }
+ // 3. 初始化GCM模式(GCM推荐IV长度12字节)
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, fmt.Errorf("初始化GCM模式失败:%w", err)
+ }
+ // 4. 生成IV
+ iv := make([]byte, gcm.NonceSize()) // gcm.NonceSize()返回12(GCM模式)
+ if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+ return nil, fmt.Errorf("生成IV失败:%w", err)
+ }
+ // 5. 加密(GCM自动处理填充和认证标签)
+ ciphertextBytes := gcm.Seal(nil, iv, []byte(plaintext), nil)
+ // 6. 编码返回(密文、IV、标签,标签已包含在ciphertextBytes末尾,无需单独生成)
+ return map[string]string{
+ "ciphertext": base64.StdEncoding.EncodeToString(ciphertextBytes),
+ "iv": base64.StdEncoding.EncodeToString(iv),
+ }, nil
+}
+
+// AESDecryptGCM AES-GCM模式解密
+func (k *AESKey) AESDecryptGCM(encryptedData map[string]string) (string, error) {
+ // 1. 解码各参数
+ keyBytes, err := base64.StdEncoding.DecodeString(k.KeyB64)
+ if err != nil {
+ return "", fmt.Errorf("密钥解码失败:%w", err)
+ }
+ iv, err := base64.StdEncoding.DecodeString(encryptedData["iv"])
+ if err != nil {
+ return "", fmt.Errorf("IV解码失败:%w", err)
+ }
+ ciphertextBytes, err := base64.StdEncoding.DecodeString(encryptedData["ciphertext"])
+ if err != nil {
+ return "", fmt.Errorf("密文解码失败:%w", err)
+ }
+ // 2. 创建AES块和GCM模式
+ block, err := aes.NewCipher(keyBytes)
+ if err != nil {
+ return "", fmt.Errorf("初始化AES块失败:%w", err)
+ }
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return "", fmt.Errorf("初始化GCM模式失败:%w", err)
+ }
+ // 3. 解密(GCM自动验证标签,标签不匹配会抛异常)
+ plaintextBytes, err := gcm.Open(nil, iv, ciphertextBytes, nil)
+ if err != nil {
+ return "", fmt.Errorf("解密失败(数据篡改或参数错误):%w", err)
+ }
+ return string(plaintextBytes), nil
+}
+
+// ------------------------------ 示例:使用流程 ------------------------------
+func main() {
+ // 1. 生成AES-256密钥
+ aesKey, err := GenerateAESKey(256)
+ if err != nil {
+ fmt.Printf("生成密钥失败:%v\n", err)
+ return
+ }
+ fmt.Printf("AES-256密钥(Base64):\n%s\n\n", aesKey.KeyB64)
+
+ // 2. 加密数据
+ plaintext := "这是需要加密的敏感数据:SpiderAPI - 虫术,包含RSA/AES混合加密场景"
+ encryptedData, err := aesKey.AESEncryptGCM(plaintext)
+ if err != nil {
+ fmt.Printf("加密失败:%v\n", err)
+ return
+ }
+ encryptedJSON, _ := json.MarshalIndent(encryptedData, "", " ")
+ fmt.Printf("加密后数据:\n%s\n\n", encryptedJSON)
+
+ // 3. 解密数据
+ decryptedText, err := aesKey.AESDecryptGCM(encryptedData)
+ if err != nil {
+ fmt.Printf("解密失败:%v\n", err)
+ return
+ }
+ fmt.Printf("解密后明文:\n%s\n", decryptedText)
+}
+ ```