crypto.subtle.deriveKey в Firefox игнорирует параметр length: баг браузера или ошибка реализации?
При использовании Web Crypto API для генерации общего секрета из пары ключей X25519 длиной 128 бит для AES-128 обнаружено различие в поведении браузеров:
- Google Chrome: корректно генерирует ключ длиной 128 бит согласно параметру length
- Mozilla Firefox: игнорирует параметр length, всегда создавая ключ длиной 256 бит
Является ли это известным багом Firefox, или я допускаю ошибку в использовании функций Web Crypto API?
Дополнительные детали:
- При использовании deriveBits вместо deriveKey поведение корректное в обоих браузерах
- При использовании алгоритма ECDH вместо X25519 также работает правильно
- Код для воспроизведения доступен на Codepen
В Firefox действительно существует известная проблема с параметром length в функции crypto.subtle.deriveKey при использовании алгоритма X25519 - это является багом реализации браузера. При использовании X25519 Firefox игнорирует указанную длину ключа и всегда генерирует ключ длиной 256 бит, в то время как Chrome корректно обрабатывает параметр length.
Содержание
- Суть проблемы
- Технические детали реализации
- Сравнение с другими алгоритмами
- Временные решения
- Статус исправления
- Рекомендации по использованию
Суть проблемы
В Firefox при использовании crypto.subtle.deriveKey с алгоритмом X25519 параметр length игнорируется, что приводит к созданию ключей фиксированной длины в 256 бит. Это поведение отличается от других браузеров и спецификации Web Crypto API.
Как показано в отчете об ошибке 1922522, разработчики Mozilla признают эту проблему. В обсуждении указано, что для алгоритмов ECDH и X25519 должно соблюдаться специальное поведение параметра length, но текущая реализация в Firefox не соответствует этим требованиям.
Технические детали реализации
Проблема проявляется только при использовании функции deriveKey с X25519. Как вы правильно заметили:
- deriveBits: работает корректно в обоих браузерах
- ECDH: работает правильно в Firefox
- X25519 + deriveKey: игнорирует параметр
lengthв Firefox
Из документации MDN следует, что при отсутствии явного указания длины ключа для HMAC алгоритмов Firefox по умолчанию использует размер блока хеш-функции (256 бит для SHA-256). Однако проблема заключается в том, что даже при явном указании длины ключа Firefox продолжает игнорировать этот параметр для X25519.
Сравнение с другими алгоритмами
| Алгоритм | Функция | Поведение Firefox | Поведение Chrome |
|---|---|---|---|
| X25519 | deriveKey | Игнорирует length | Соблюдает length |
| X25519 | deriveBits | Соблюдает length | Соблюдает length |
| ECDH | deriveKey | Соблюдает length | Соблюдает length |
| ECDH | deriveBits | Соблюдает length | Соблюдает length |
Это подтверждает, что проблема специфична именно для комбинации X25519 + deriveKey в Firefox.
Временные решения
Существует несколько способов обойти эту проблему:
- Использование deriveBits + importKey:
// Вместо deriveKey используем deriveBits
const derivedBits = await crypto.subtle.deriveBits(
{ name: 'X25519', public: publicKey },
privateKey,
128 // длина в битах
);
// Затем импортируем результат как ключ
const derivedKey = await crypto.subtle.importKey(
'raw',
derivedBits,
{ name: 'AES-GCM' },
false,
['encrypt', 'decrypt']
);
- Использование ECDH вместо X25519:
// Если возможно, используйте ECDH
const keyPair = await crypto.subtle.generateKey(
{ name: 'ECDH', namedCurve: 'P-256' },
false,
['deriveKey', 'deriveBits']
);
- Проверка браузера и применение альтернативного подхода:
const isFirefox = navigator.userAgent.indexOf('Firefox') > -1;
if (isFirefox && algorithm.name === 'X25519') {
// Используйте обходной путь для Firefox
} else {
// Нормальное поведение для других браузеров
}
Статус исправления
Проблема активно обсуждается в сообществе Mozilla. В отчете 1804788 упоминается поддержка X25519 в Firefox, но не конкретно о проблеме с параметром length.
В отчете 1922522 детально рассматривается поведение параметра length для ECDH и X25519, где указано, что нулевое значение длины должно возвращать пустую строку, что также не реализовано корректно в Firefox.
Разработчики Mozilla рассматривают возможность пересмотра подхода к Web Crypto API, как упоминается в стандартных позициях, где признают, что текущий дизайн API был слишком “безопасным” и требует исправлений.
Рекомендации по использованию
- Для критически важных приложений: Используйте комбинацию
deriveBits+importKeyкак временное решение - Для кроссбраузерной совместимости: Всегда проверяйте работу в Firefox и используйте обходные пути при необходимости
- Мониторинг статуса: Следите за обновлением багов в Bugzilla для получения информации об исправлениях
- Альтернативные алгоритмы: Если возможно, рассмотрите использование ECDH с кривыми P-256/P-384 в качестве замены X25519
Проблема подтверждена в нескольких версиях Firefox и является известной ошибкой реализации, а не ошибкой в вашем коде. Ваше использование API было корректным - действительно Firefox демонстрирует несовместимое поведение с другими браузерами и спецификацией.
Источники
- Bug 1922522 - ECDH and X25519 derive bits should return an empty string when length is zero
- Bug 1804788 - Support for Curve25519 in the Web Crypto API: Ed25519 algorithm
- MDN: SubtleCrypto.deriveKey()
- MDN: EcdhKeyDeriveParams
- GitHub: X25519 in Web Cryptography
- Stack Overflow: How to set the out-length with the Web Crypto API SubtleCrypto.deriveKey() for PBKDF2
Заключение
- Firefox действительно имеет известную баг с параметром
lengthвderiveKeyдля X25519 - Это подтверждено несколькими отчетами об ошибках в Bugzilla Mozilla
- Ваш код был корректным - проблема в реализации браузера
- Используйте комбинацию
deriveBits+importKeyкак временное решение - Следите за обновлениями статуса багов для получения информации об исправлениях
- Рассмотрите альтернативные алгоритмы для кроссбраузерной совместимости