fix(crypto): align server-side encrypted format with client-side Web Crypto API
The server-side encrypt function in crypto-server.ts used format `iv + authTag + encrypted`, but the client-side decrypt function in crypto.ts expects `iv + encrypted + authTag` (authTag at the end, matching Web Crypto API convention where ciphertext includes authTag). This mismatch caused all admin API requests to fail with "The operation failed for an operation-specific reason" when NEXT_PUBLIC_ENCRYPTION_SECRET was configured, since the client could not decrypt the server's response. Fix: swap the order of authTag and encrypted in both encrypt and decrypt functions in crypto-server.ts.
This commit is contained in:
@@ -53,8 +53,9 @@ export function encrypt(plaintext: string): string {
|
||||
]);
|
||||
const authTag = cipher.getAuthTag();
|
||||
|
||||
// 格式: iv + authTag + encrypted
|
||||
const combined = Buffer.concat([iv, authTag, encrypted]);
|
||||
// 格式: iv + encrypted + authTag
|
||||
// 与客户端 crypto.ts 的 decrypt 格式一致(Web Crypto API 将 authTag 附在 ciphertext 末尾)
|
||||
const combined = Buffer.concat([iv, encrypted, authTag]);
|
||||
return combined.toString('base64');
|
||||
}
|
||||
|
||||
@@ -66,8 +67,8 @@ export function decrypt(encryptedBase64: string): string {
|
||||
const combined = Buffer.from(encryptedBase64, 'base64');
|
||||
|
||||
const iv = combined.subarray(0, IV_LENGTH);
|
||||
const authTag = combined.subarray(IV_LENGTH, IV_LENGTH + AUTH_TAG_LENGTH);
|
||||
const encrypted = combined.subarray(IV_LENGTH + AUTH_TAG_LENGTH);
|
||||
const authTag = combined.subarray(combined.length - AUTH_TAG_LENGTH);
|
||||
const encrypted = combined.subarray(IV_LENGTH, combined.length - AUTH_TAG_LENGTH);
|
||||
|
||||
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
||||
decipher.setAuthTag(authTag);
|
||||
|
||||
Reference in New Issue
Block a user