Subject Key Identifier (SKI) и Authority Key Identifier (AKI) относятся к расширениям сертификатов X.509, которые используются для построения и проверки цепочек доверия в инфраструктуре открытых ключей (PKI). Эти расширения не влияют напрямую на криптографическую стойкость алгоритмов, но критически важны для идентификации ключей и корректной валидации цепочек сертификатов.
SKI представляет собой уникальный идентификатор, связанный с открытым ключом субъекта сертификата. AKI, в свою очередь, указывает на ключ центра сертификации (CA), который подписал данный сертификат. Совместное использование этих двух расширений позволяет однозначно связывать сертификаты между собой и предотвращать неоднозначности при построении цепочки доверия.
Расширения X.509 кодируются в формате ASN.1 и включаются в поле
extensions сертификата.
Subject Key Identifier (SKI):
ASN.1 представление:
SubjectKeyIdentifier ::= KeyIdentifier
KeyIdentifier ::= OCTET STRING
Authority Key Identifier (AKI):
Ссылается на ключ центра сертификации
Может содержать:
ASN.1 представление:
AuthorityKeyIdentifier ::= SEQUENCE {
keyIdentifier [0] KeyIdentifier OPTIONAL,
authorityCertIssuer [1] GeneralNames OPTIONAL,
authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL
}
SKI формируется на основе публичного ключа субъекта. В типичной реализации используется SHA-1 хеширование DER-представления публичного ключа.
В контексте Jsrsasign SKI может быть задан явно при генерации сертификата или вычислен автоматически.
Ключевая особенность SKI — стабильная привязка к ключевой паре. Если ключ не меняется, SKI остаётся тем же, даже если меняются другие параметры сертификата.
AKI позволяет связать сертификат с сертификатом центра сертификации. При валидации цепочки:
Это ускоряет поиск родительского сертификата в больших PKI-системах.
Библиотека Jsrsasign предоставляет инструменты для создания и анализа
X.509 сертификатов через объект X509 и генератор
KEYUTIL / KJUR.asn1.x509.X509Ext.
При создании сертификата через Jsrsasign расширения задаются в поле
ext:
const { KEYUTIL, KJUR } = require("jsrsasign");
// Генерация ключей CA
const caKey = KEYUTIL.generateKeypair("RSA", 2048);
const caPrivateKey = caKey.prvKeyObj;
const caPublicKey = caKey.pubKeyObj;
// Генерация ключей субъекта
const userKey = KEYUTIL.generateKeypair("RSA", 2048);
const userPrivateKey = userKey.prvKeyObj;
const userPublicKey = userKey.pubKeyObj;
// Создание сертификата CA
const caCert = new KJUR.asn1.x509.Certificate({
version: 3,
serial: { int: 1 },
issuer: { str: "/CN=Test CA" },
subject: { str: "/CN=Test CA" },
notbefore: "250101000000Z",
notafter: "260101000000Z",
sbjpubkey: caPublicKey,
sigalg: "SHA256withRSA",
ext: [
{
extname: "basicConstraints",
cA: true
},
{
extname: "subjectKeyIdentifier"
}
],
cakey: caPrivateKey
});
В этом случае SKI для CA может быть сгенерирован автоматически из публичного ключа.
const userCert = new KJUR.asn1.x509.Certificate({
version: 3,
serial: { int: 2 },
issuer: { str: "/CN=Test CA" },
subject: { str: "/CN=User" },
notbefore: "250101000000Z",
notafter: "260101000000Z",
sbjpubkey: userPublicKey,
sigalg: "SHA256withRSA",
ext: [
{
extname: "authorityKeyIdentifier",
cakey: caPrivateKey
},
{
extname: "subjectKeyIdentifier"
}
],
cakey: caPrivateKey
});
Здесь происходит важный момент: AKI вычисляется на основе ключа CA и автоматически включает его идентификатор.
В Jsrsasign SKI может быть вычислен из публичного ключа через SHA-1. Внутри библиотеки это делается примерно по следующей логике:
Пример явного формирования SKI:
{
extname: "subjectKeyIdentifier",
kid: true
}
Флаг kid: true указывает библиотеке использовать ключ
для генерации идентификатора.
При проверке сертификата цепочка строится следующим образом:
Логика сопоставления:
AKI (child certificate) → SKI (CA certificate)
Если AKI отсутствует, используется альтернативный механизм — сравнение issuer/subject, что менее эффективно и более подвержено ошибкам.
Jsrsasign позволяет извлекать расширения из сертификата:
const x = new KJUR.asn1.x509.X509();
x.readCertPEM(userCert.getPEM());
const aki = x.getExtAuthorityKeyIdentifier();
const ski = x.getExtSubjectKeyIdentifier();
console.log("AKI:", aki);
console.log("SKI:", ski);
Результаты обычно представлены в hex или base64 формате в зависимости от конфигурации.
Возникает, если:
Некоторые старые сертификаты могут не содержать AKI, что усложняет построение цепочки.
Если использовать нестандартный алгоритм хеширования, идентификатор перестаёт быть совместимым с RFC 5280.
SKI и AKI активно используются в:
В реальных системах SKI служит первичным ключом индексации сертификатов, а AKI — связующим звеном между уровнями иерархии CA.
Jsrsasign ориентирован на совместимость с OpenSSL-подобными структурами, поэтому:
При необходимости точного контроля можно формировать расширения через
низкоуровневый API KJUR.asn1.x509.Extension.