В криптографических сертификатах fingerprint (отпечаток) представляет собой короткое хеш-значение, вычисленное от бинарного представления X.509 сертификата. Он используется как компактный идентификатор, позволяющий быстро сравнивать сертификаты без необходимости анализа всей структуры ASN.1.
В контексте работы с Jsrsasign fingerprint обычно вычисляется из DER-представления сертификата с применением криптографических хеш-функций, таких как SHA-1, SHA-256 или SHA-512. На практике наиболее распространены SHA-1 (исторически) и SHA-256 (в современных системах).
X.509 сертификат внутри библиотеки Jsrsasign может быть представлен в PEM или DER формате. Независимо от исходного представления, вычисление отпечатка всегда опирается на DER-байты.
PEM-сертификат предварительно декодируется:
-----BEGIN CERTIFICATE-----Далее применяется хеш-функция:
В библиотеке Jsrsasign работа с сертификатами реализована через класс X509:
const cert = `-----BEGIN CERTIFICATE-----
MIID...
-----END CERTIFICATE-----`;
const x509 = new X509();
x509.readCertPEM(cert);
После загрузки сертификата доступна DER-структура:
const hex = x509.hex; // DER в hex формате
Этот hex-строковый формат используется для вычисления хеша.
SHA-1 отпечаток часто рассматривается как исторический идентификатор сертификата:
const fp = KJUR.crypto.Util.hashHex(x509.hex, 'sha1');
console.log(fp);
Результат представляет собой строку в шестнадцатеричном формате:
a3f1c9e0d2b4...
Для повышения читаемости часто добавляется разделение двоеточиями:
A3:F1:C9:E0:D2:B4:...
SHA-256 считается более устойчивым вариантом:
const fp256 = KJUR.crypto.Util.hashHex(x509.hex, 'sha256');
Отпечаток становится длиннее, но обеспечивает более высокий уровень криптографической надежности.
В Jsrsasign предусмотрены вспомогательные методы для получения отпечатков без явного обращения к утилитам хеширования.
Типовой подход:
const x509 = new X509();
x509.readCertPEM(cert);
const sha1fp = x509.getFingerprint();
В зависимости от версии библиотеки метод может возвращать SHA-1 отпечаток по умолчанию.
Для SHA-256 используется альтернативная логика:
const sha256fp = KJUR.crypto.Util.hashHex(x509.hex, 'sha256');
При сравнении отпечатков важно учитывать форматирование. Одно и то же значение может быть представлено:
Нормализация обычно включает:
function normalize(fp) {
return fp.replace(/:/g, '').toLowerCase();
}
Это позволяет исключить различия представления при сравнении сертификатов.
Fingerprint используется как ключевой механизм идентификации:
const fp1 = KJUR.crypto.Util.hashHex(certHex1, 'sha256');
const fp2 = KJUR.crypto.Util.hashHex(certHex2, 'sha256');
const isSame = (fp1 === fp2);
Такой подход применяется в системах доверия, проверке цепочек сертификатов и кэшировании.
Процесс формирования fingerprint в Jsrsasign сводится к следующим шагам:
Фактически fingerprint не зависит от метаданных сертификата как текстовой структуры, а строго привязан к бинарному содержимому.
Несколько важных технических аспектов:
Отдельный случай — вычисление отпечатка не сертификата, а открытого ключа:
const pubKey = KEYUTIL.getKey(cert);
const pubHex = pubKey.pubKeyHex;
const pubFp = KJUR.crypto.Util.hashHex(pubHex, 'sha256');
Такой fingerprint используется для идентификации ключа независимо от сертификата.
На практике встречаются типовые проблемы:
Корректная схема всегда опирается на DER-представление как источник истины.
Fingerprint становится основой для:
В криптографических системах он выступает как компактный суррогат всей структуры сертификата, позволяющий выполнять сравнение за O(1) по длине строки вместо анализа ASN.1 дерева.