Я искренне считаю, что моя реализация неверна, поскольку криптографические операции с этим зашифрованным текстом работают как в моих реализациях 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))
);
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... ently-fail