AI 网关允许您安全地将日志导出到外部存储位置,在那里您可以解密和处理它们。 您可以在 Cloudflare 仪表板 ↗ 设置中开启和关闭 Workers Logpush。此产品在 Workers 付费计划中可用。有关定价信息,请参阅定价。
本指南解释了如何为 AI 网关设置 Workers Logpush,生成用于加密的 RSA 密钥对,以及在接收到日志后如何解密日志。
您每个网关最多可以存储 1000 万条日志。如果达到限制,新日志将停止保存,也不会通过 Workers Logpush 导出。要继续保存和导出日志,您必须删除较旧的日志以为新日志释放空间。Workers Logpush 限制为 4 个作业,每个日志的最大请求大小为 1 MB。
我们采用混合加密模型来提高效率和安全性。首先,为每个日志生成一个 AES 密钥。这个 AES 密钥实际加密您的大部分数据,选择它是因为它在高效处理大型数据集方面的速度和安全性。
现在,为了安全地共享这个 AES 密钥,我们使用 RSA 加密。以下是发生的过程:AES 密钥虽然轻量级,但需要安全地传输给接收者。我们使用接收者的 RSA 公钥加密此密钥。此步骤利用 RSA 在安全密钥分发方面的优势,确保只有拥有相应 RSA 私钥的人才能解密和使用 AES 密钥。
加密后,AES 加密的数据和 RSA 加密的 AES 密钥一起发送。到达后,接收者的系统使用 RSA 私钥解密 AES 密钥。现在可以访问 AES 密钥,解密主数据载荷就很简单了。
此方法结合了两个世界的优点:用于数据加密的 AES 效率与 RSA 的安全密钥交换能力,确保在整个数据生命周期中最佳地维护数据完整性、机密性和性能。
要为 AI 网关配置 Workers Logpush,请按以下步骤操作:
您需要生成一个密钥对来加密和解密日志。此脚本将输出您的 RSA 私钥和公钥。保持私钥安全,因为它将用于解密日志。下面是使用 Node.js 和 OpenSSL 生成密钥的示例脚本。
const crypto = require("crypto");
const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", { modulusLength: 4096, publicKeyEncoding: { type: "spki", format: "pem", }, privateKeyEncoding: { type: "pkcs8", format: "pem", },});
console.log(publicKey);console.log(privateKey);
通过在终端中执行以下代码运行脚本。将 file name
替换为您的 JavaScript 文件名。
node {file name}
-
生成私钥: 使用以下命令生成 RSA 私钥:
Terminal window openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:4096 -
生成公钥: 生成私钥后,您可以使用以下命令提取相应的公钥:
Terminal window openssl rsa -pubout -in private_key.pem -out public_key.pem
生成密钥对后,将公钥上传到您的 AI 网关设置。此密钥将用于加密您的日志。要启用 Workers Logpush,您需要为该网关启用日志记录。
要设置 Logpush,请参阅 Logpush 快速开始。
配置 Workers Logpush 后,日志将使用您上传的公钥进行加密发送。要访问数据,您需要使用私钥对其进行解密。日志将发送到您选择的对象存储提供商。
要解密来自 AI 网关的加密日志正文和元数据,您可以使用以下 Node.js 脚本或 OpenSSL:
要解密来自 AI 网关的加密日志正文和元数据,请将日志下载到一个文件夹,在本例中名为 my_log.log.gz
。
然后将此 JavaScript 文件复制到同一文件夹中,并将您的私钥放在顶部变量中。
const privateKeyStr = `-----BEGIN RSA PRIVATE KEY-----....-----END RSA PRIVATE KEY-----`;
const crypto = require("crypto");const privateKey = crypto.createPrivateKey(privateKeyStr);
const fs = require("fs");const zlib = require("zlib");const readline = require("readline");
async function importAESGCMKey(keyBuffer) { try { // 确保密钥长度对 AES 有效 if ([128, 192, 256].includes(256)) { return await crypto.webcrypto.subtle.importKey( "raw", keyBuffer, { name: "AES-GCM", length: 256, }, true, // 密钥是否可提取(在此情况下为 true,以便稍后需要时允许导出) ["encrypt", "decrypt"], // 用于加密和解密 ); } else { throw new Error("无效的 AES 密钥长度。必须是 128、192 或 256 位。"); } } catch (error) { console.error("导入密钥失败:", error); throw error; }}
async function decryptData(encryptedData, aesKey, iv) { const decryptedData = await crypto.subtle.decrypt( { name: "AES-GCM", iv: iv }, aesKey, encryptedData, ); return new TextDecoder().decode(decryptedData);}
async function decryptBase64(privateKey, data) { if (data.key === undefined) { return data; }
const aesKeyBuf = crypto.privateDecrypt( { key: privateKey, oaepHash: "SHA256", }, Buffer.from(data.key, "base64"), ); const aesKey = await importAESGCMKey(aesKeyBuf);
const decryptedData = await decryptData( Buffer.from(data.data, "base64"), aesKey, Buffer.from(data.iv, "base64"), );
return decryptedData.toString();}
async function run() { let lineReader = readline.createInterface({ input: fs.createReadStream("my_log.log.gz").pipe(zlib.createGunzip()), });
lineReader.on("line", async (line) => { line = JSON.parse(line);
const { Metadata, RequestBody, ResponseBody, ...remaining } = line;
console.log({ ...remaining, Metadata: await decryptBase64(privateKey, Metadata), RequestBody: await decryptBase64(privateKey, RequestBody), ResponseBody: await decryptBase64(privateKey, ResponseBody), }); console.log("--"); });}
run();
通过在终端中执行以下代码运行脚本。将 file name
替换为您的 JavaScript 文件名。
node {file name}
The script reads the encrypted log file (my_log.log.gz)
, decrypts the metadata, request body, and response body, and prints the decrypted data.
Ensure you replace the privateKey
variable with your actual private RSA key that you generated in step 1.
- Decrypt the encrypted log file using the private key.
Assuming that the logs were encrypted with the public key (for example public_key.pem
), you can use the private key (private_key.pem
) to decrypt the log file.
For example, if the encrypted logs are in a file named encrypted_logs.bin
, you can decrypt it like this:
openssl rsautl -decrypt -inkey private_key.pem -in encrypted_logs.bin -out decrypted_logs.txt
-decrypt
tells OpenSSL that we want to decrypt the file.-inkey private_key.pem
specifies the private key that will be used to decrypt the logs.-in encrypted_logs.bin
is the encrypted log file.-out decrypted_logs.txt
decrypted logs will be saved into this file.
- View the decrypted logs Once decrypted, you can view the logs by simply running:
cat decrypted_logs.txt
This command will output the decrypted logs to the terminal.
- @2025 Cloudflare Ubitools
- Cf Repo