RSA-PSS в Web Crypto API реализуется через алгоритм
"RSA-PSS" и относится к вероятностным схемам подписи, где
каждый вызов подписания использует случайную соль. Это ключевое отличие
от RSASSA-PKCS1-v1_5, где подпись формируется детерминированно на основе
входного сообщения и приватного ключа.
В Web Crypto API алгоритм RSA-PSS задаётся через объект конфигурации:
const algorithm = {
name: "RSA-PSS",
saltLength: 32
};
Этот объект используется как при подписании, так и при проверке подписи:
crypto.subtle.sign(
{
name: "RSA-PSS",
saltLength: 32
},
privateKey,
data
);
crypto.subtle.verify(
{
name: "RSA-PSS",
saltLength: 32
},
publicKey,
signature,
data
);
Критически важно, что параметры sign и
verify должны совпадать, включая saltLength,
иначе проверка подписи завершится неудачей.
saltLength определяет длину случайной соли (salt),
используемой внутри схемы PSS при формировании подписи.
Чаще всего применяются следующие значения:
32 байта — для SHA-25648 байт — для SHA-38464 байта — для SHA-512Это не строгие требования стандарта WebCrypto, но общепринятая практика, основанная на рекомендациях RFC 8017.
RSA-PSS использует схему, в которой сообщение дополняется случайной солью перед возведением в степень по модулю RSA.
Упрощённо процесс выглядит так:
saltLengthСоль делает каждую подпись уникальной даже при одинаковом входном сообщении. Это устраняет один из фундаментальных недостатков PKCS#1 v1.5 — детерминированность.
PKCS1 v1.5:
PSS:
RSA-PSS считается криптографически более устойчивым:
PKCS1 v1.5:
PKCS#1 v1.5:
EM = 0x00 || 0x01 || PS || 0x00 || DigestInfo
где PS — фиксированная последовательность байтов.
PSS:
EM = maskedDB || H || 0xbc
где maskedDB включает соль, маску и служебные биты.
RSA-PSS в WebCrypto предоставляет явный параметр:
saltLength — управляемый разработчикомВ PKCS1 v1.5 таких параметров нет.
Выбор saltLength влияет на:
Если сервер ожидает:
saltLength: 32
а клиент использует:
saltLength: 16
подписи будут несовместимы.
Большая соль:
Общее правило:
saltLength = hashLengthПримеры:
Использование меньших значений допустимо, но снижает криптографический запас стойкости.
const keyPair = await crypto.subtle.generateKey(
{
name: "RSA-PSS",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
Важно, что hash задаётся на уровне ключа, а
saltLength — на уровне операции.
const signature = await crypto.subtle.sign(
{
name: "RSA-PSS",
saltLength: 32
},
keyPair.privateKey,
messageBuffer
);
const isValid = await crypto.subtle.verify(
{
name: "RSA-PSS",
saltLength: 32
},
keyPair.publicKey,
signature,
messageBuffer
);
Одна из наиболее частых проблем:
saltLength: 32saltLength: 0 или другим
значениемРезультат — всегда false.
Хотя WebCrypto не требует строгого соответствия, несогласованность приводит к снижению безопасности и проблемам совместимости с внешними системами.
RSA-PSS и RSASSA-PKCS1-v1_5 — разные алгоритмы:
name: "RSA-PSS" // требует saltLength
name: "RSASSA-PKCS1-v1_5" // saltLength не используется
Смешивание параметров приводит к ошибкам выполнения.
RSA-PSS предпочтителен:
PKCS1 v1.5 встречается в legacy-системах:
RSA-PSS постепенно становится стандартом:
Web Crypto API фактически фиксирует современный криптографический подход:
saltLength становится единственным значимым
настраиваемым параметром, который напрямую влияет на криптографическую
структуру подписи, а не только на формат данных.