Я столкнулся со странной проблемой, когда расшифровка зашифрованного текста Chacha20-Poly1305 внутри браузера с использованием @noble/ciphers/chacha завершается неудачно с «неверным тегом».
Я искренне считаю, что моя реализация неверна, поскольку криптографические операции с этим зашифрованным текстом работают как в моих реализациях Go, так и в Dart, и я не очень хорошо знаком с WebCrypto.
Вот соответствующий код:
export function str2ab(str: string) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++)
bufView[i] = str.charCodeAt(i);
return buf;
}
export async function deriveKey(
pub: string,
priv: string,
nonce: number[],
aad: Uint8Array
): Promise {
const publicKey = await crypto.subtle.importKey(
"spki",
str2ab(atob(pub)),
{ name: "X25519" },
false,
[]
);
const privateKey = await crypto.subtle.importKey(
"pkcs8",
str2ab(atob(priv)),
{ name: "X25519" },
false,
["deriveBits"]
);
const secret = new Uint8Array(await crypto.subtle.deriveBits({
name: "X25519",
public: publicKey,
}, privateKey, 256));
const hkdf = await crypto.subtle.importKey(
"raw", secret, "HKDF", false, ["deriveBits"]
);
const okm = new Uint8Array(await crypto.subtle.deriveBits({
name: "HKDF",
hash: "SHA-256",
salt: new Uint8Array(nonce),
info: new TextEncoder().encode("veriscope-seal-cek")
}, hkdf, 256));
return chacha20poly1305(
okm,
new Uint8Array(nonce),
// we only get the content of the aad from the first byte to the first
// NUL
// note to stackoverflow users: I am using this line because I am retrieving the AAD and ciphertext from a buffer with specific formatting where the AAD has 4096 bytes allocated, and it might not fill this space.
aad.slice(0, aad.findIndex(v => v === 0))
);
}
После вызова DecryptKey мне нужно вызвать только .decrypt.
Я столкнулся со странной проблемой, когда расшифровка зашифрованного текста Chacha20-Poly1305 внутри браузера с использованием @noble/ciphers/chacha завершается неудачно с «неверным тегом». Я искренне считаю, что моя реализация неверна, поскольку криптографические операции с этим зашифрованным текстом работают как в моих реализациях Go, так и в Dart, и я не очень хорошо знаком с WebCrypto. Вот соответствующий код: [code]export function str2ab(str: string) { const buf = new ArrayBuffer(str.length); const bufView = new Uint8Array(buf);
for (let i = 0, strLen = str.length; i < strLen; i++) bufView[i] = str.charCodeAt(i); return buf; }
const hkdf = await crypto.subtle.importKey( "raw", secret, "HKDF", false, ["deriveBits"] ); const okm = new Uint8Array(await crypto.subtle.deriveBits({ name: "HKDF", hash: "SHA-256", salt: new Uint8Array(nonce), info: new TextEncoder().encode("veriscope-seal-cek") }, hkdf, 256));
return chacha20poly1305( okm, new Uint8Array(nonce), // we only get the content of the aad from the first byte to the first // NUL // note to stackoverflow users: I am using this line because I am retrieving the AAD and ciphertext from a buffer with specific formatting where the AAD has 4096 bytes allocated, and it might not fill this space. aad.slice(0, aad.findIndex(v => v === 0)) ); } [/code] После вызова DecryptKey мне нужно вызвать только .decrypt.