Метод verify интерфейса SubtleCrypto
выполняет криптографическую проверку цифровой подписи. Он используется
для подтверждения того, что данные не были изменены и действительно
подписаны соответствующим закрытым ключом.
Promise, возвращаемый методом, резолвится в true или
false в зависимости от результата проверки.
crypto.subtle.verify(algorithm, key, signature, data)
Возвращаемое значение:
Promise<boolean>
Объект, описывающий алгоритм проверки подписи. Структура зависит от выбранного механизма:
RSASSA-PKCS1-v1_5RSA-PSSECDSAHMACПримеры:
{
name: "RSASSA-PKCS1-v1_5"
}
{
name: "ECDSA",
hash: "SHA-256"
}
Для RSA-PSS дополнительно могут задаваться
параметры:
{
name: "RSA-PSS",
saltLength: 32
}
Ключ проверки подписи (CryptoKey), полученный через:
crypto.subtle.importKeycrypto.subtle.generateKeyОсобенность: это всегда публичный ключ для асимметричных алгоритмов или симметричный ключ для HMAC.
Подпись, которую необходимо проверить.
Тип данных:
ArrayBufferTypedArray (передаётся как буфер)DataViewПодпись должна быть в том же формате, в котором она была создана
методом sign.
Исходные данные, которые были подписаны.
Требование:
falseМетод verify математически проверяет соответствие:
Результат не выбрасывает ошибку при неверной подписи — вместо этого
возвращается false.
HMAC является симметричным алгоритмом: один и тот же ключ используется для подписи и проверки.
const key = await crypto.subtle.generateKey(
{
name: "HMAC",
hash: "SHA-256"
},
true,
["sign", "verify"]
);
const data = new TextEncoder().encode("hello world");
const signature = await crypto.subtle.sign(
"HMAC",
key,
data
);
const result = await crypto.subtle.verify(
"HMAC",
key,
signature,
data
);
console.log(result);
const keys = await crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
const data = new TextEncoder().encode("message");
const signature = await crypto.subtle.sign(
"RSASSA-PKCS1-v1_5",
keys.privateKey,
data
);
const valid = await crypto.subtle.verify(
"RSASSA-PKCS1-v1_5",
keys.publicKey,
signature,
data
);
ECDSA требует указания хэш-функции.
const keys = await crypto.subtle.generateKey(
{
name: "ECDSA",
namedCurve: "P-256"
},
true,
["sign", "verify"]
);
const data = new TextEncoder().encode("data");
const signature = await crypto.subtle.sign(
{
name: "ECDSA",
hash: "SHA-256"
},
keys.privateKey,
data
);
const ok = await crypto.subtle.verify(
{
name: "ECDSA",
hash: "SHA-256"
},
keys.publicKey,
signature,
data
);
verify работает только с бинарными данными.
Строки необходимо преобразовывать:
const encoder = new TextEncoder();
const data = encoder.encode("text");
Любое изменение входных байтов делает подпись недействительной:
Подпись должна быть передана в исходном бинарном виде.
Если подпись сериализуется (например, в Base64), её необходимо декодировать:
function base64ToBuffer(base64) {
const binary = atob(base64);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes.buffer;
}
falseСамая частая причина — различие между исходными данными и проверяемыми.
Подпись и проверка должны использовать одинаковые параметры:
Хотя JWT обычно обрабатывается специализированными библиотеками,
механизм проверки подписи основан на verify.
Используется в:
Подпись файла проверяется перед использованием:
const valid = await crypto.subtle.verify(
"RSASSA-PKCS1-v1_5",
publicKey,
signature,
fileBuffer
);
verify как единственный механизм
аутентификацииArrayBuffer напрямую, минимизируя
преобразованияМетод не выбрасывает исключение при неверной подписи.
Ошибки возникают только при:
Во всех остальных случаях возвращается false, что важно
учитывать при построении логики проверки.