
Paseto V3 在 Node.js 中使用 decrypt 时提示“secret key must be 32 bytes long”,常见原因是传入的密钥为十六进制字符串而非 Buffer,需显式转换为 32 字节的 Uint8Array 或 Buffer。
paseto v3 在 node.js 中使用 `decrypt` 时提示“secret key must be 32 bytes long”,常见原因是传入的密钥为十六进制字符串而非 buffer,需显式转换为 32 字节的 uint8array 或 buffer。
在 Paseto V3 Local(对称加密)模式中,decrypt 函数严格要求 secret key 是一个长度恰好为 32 字节的 Uint8Array 或 Buffer,而不能是十六进制字符串(如 "b244ac59...")——即使该字符串由 64 个十六进制字符组成(对应 32 字节),Node.js 仍会将其视为长度为 64 的字符串,从而触发校验失败。
✅ 正确做法:将 hex 字符串解码为二进制 Buffer:
const paseto = require('paseto');
const { V3: { decrypt } } = paseto;
(async () => {
const token = "example_token";
const hexKey = "b244ac595fbe3a6ea8c3fad93f66d15221121428fd03dcccf32203e364f504ed";
// ✅ 关键步骤:将 hex 字符串转为 32-byte Buffer
const secretKey = Buffer.from(hexKey, 'hex');
try {
const payload = await decrypt(token, secretKey);
console.log("Decrypted payload:", payload);
} catch (err) {
console.error("Decryption failed:", err.message);
}
})();⚠️ 注意事项:
-
Buffer.from(hexKey, 'hex')是标准且安全的转换方式;若使用Uint8Array.from(Buffer.from(...))也可,但 Buffer 更简洁。 - 确保 hex 字符串长度为 64 字符(32 字节 × 2),否则
Buffer.from(..., 'hex')会静默截断或抛出TypeError: Invalid hex string。 - PHP 端使用
openssl_random_pseudo_bytes(32)生成的原始二进制密钥,若经bin2hex()转换后传输/存储,则 Node.js 端必须反向hex → binary,不可直接复用 hex 字符串。 - 不要使用
new TextEncoder().encode(hexKey)—— 这会编码字符串本身(UTF-8),得到 64 字节,导致错误。
? 小贴士:为增强可维护性,建议在项目中封装密钥解析逻辑:
function parseSymmetricKey(keyInput) {
if (Buffer.isBuffer(keyInput)) return keyInput;
if (typeof keyInput === 'string' && keyInput.length === 64 && /^[0-9a-f]{64}$/.test(keyInput)) {
return Buffer.from(keyInput, 'hex');
}
throw new TypeError('Invalid Paseto V3 local secret key: must be a 32-byte Buffer or 64-char lowercase hex string');
}使用该函数可统一处理密钥输入,提升健壮性与可读性。


















