В расширении Authority Information Access (AIA) сертификата X.509 содержится информация о том, где можно получить дополнительные данные, связанные с удостоверяющим центром (CA). Обычно это ссылки на:
Структура AIA представляет собой набор AccessDescription, где каждый элемент описывает тип доступа и соответствующий URI.
На уровне ASN.1 это выглядит как последовательность:
На практике наиболее часто встречаются два OID:
1.3.6.1.5.5.7.48.11.3.6.1.5.5.7.48.2Работа с расширением AIA в Jsrsasign основана на разборе структуры сертификата X.509 и извлечении соответствующего расширения из списка extensions.
В библиотеке используется объект X509, который
предоставляет методы для декодирования сертификата и доступа к его
полям.
const certPEM = `-----BEGIN CERTIFICATE-----
MIID...
-----END CERTIFICATE-----`;
const x = new X509();
x.readCertPEM(certPEM);
После загрузки сертификата доступ к расширениям осуществляется через внутреннюю ASN.1 структуру:
const info = x.getInfo();
console.log(info);
Однако для работы именно с AIA требуется более низкоуровневый разбор
через getExtInfo() или анализ расширений вручную.
Каждое расширение в X.509 представлено в виде структуры:
В Jsrsasign доступ к ним осуществляется следующим образом:
const exts = x.getExtInfo();
console.log(exts);
Внутри результата будет массив объектов, среди которых можно найти AIA по OID:
const AIA_OID = "1.3.6.1.5.5.7.1.1";
После декодирования AIA содержит массив accessDescription:
AuthorityInfoAccessSyntax ::=
SEQUENCE SIZE (1..MAX) OF AccessDescription
AccessDescription ::= SEQUENCE {
accessMethod OBJECT IDENTIFIER,
accessLocation GeneralName }
В Jsrsasign это обычно представлено как массив объектов:
[
{
accessMethod: "1.3.6.1.5.5.7.48.1",
accessLocation: "http://ocsp.example.com"
},
{
accessMethod: "1.3.6.1.5.5.7.48.2",
accessLocation: "http://ca.example.com/issuer.crt"
}
]
Jsrsasign не всегда предоставляет прямой высокоуровневый API только для AIA, поэтому используется комбинированный подход через ASN.1 парсер:
const hex = x.hex;
const asn1 = ASN1HEX.getVbyList(
hex,
0,
["tbsCertificate", "extensions", "extnValue"],
"30"
);
Далее выполняется декодирование структуры AIA:
const aiaAsn1 = ASN1HEX.parseHex(asn1);
console.log(aiaAsn1);
Для извлечения OCSP URL необходимо отфильтровать accessMethod:
const exts = x.getExtInfo();
let ocspURL = null;
exts.forEach(ext => {
if (ext.extname === "authorityInfoAccess") {
const aia = ext.value;
aia.forEach(item => {
if (item.accessMethod === "1.3.6.1.5.5.7.48.1") {
ocspURL = item.accessLocation;
}
});
}
});
console.log(ocspURL);
Аналогично OCSP, но используется другой OID:
const CA_ISSUERS_OID = "1.3.6.1.5.5.7.48.2";
let issuerURL = null;
exts.forEach(ext => {
if (ext.extname === "authorityInfoAccess") {
ext.value.forEach(item => {
if (item.accessMethod === CA_ISSUERS_OID) {
issuerURL = item.accessLocation;
}
});
}
});
console.log(issuerURL);
При построении цепочки доверия AIA используется для:
В сценариях TLS-клиентов AIA играет ключевую роль при отсутствии полного набора промежуточных сертификатов.
Jsrsasign поддерживает оба формата сертификатов. AIA извлекается одинаково после парсинга:
const x = new X509();
x.readCertPEM(pemString);
или
x.readCertHex(hexString);
После этого структура расширений остается одинаковой.
Для более глубокого контроля используется ASN1HEX:
const aiaIdx = ASN1HEX.getIdxbyList(
x.hex,
0,
["tbsCertificate", "extensions"]
);
Затем выполняется итерация по расширениям:
const extSeq = ASN1HEX.getChildIdx(x.hex, aiaIdx);
extSeq.forEach(idx => {
const oid = ASN1HEX.getVbyList(x.hex, idx, [0], "06");
if (oid === "1.3.6.1.5.5.7.1.1") {
const value = ASN1HEX.getVbyList(x.hex, idx, [1], "04");
console.log(value);
}
});
Значение accessLocation почти всегда представлено как GeneralName типа uniformResourceIdentifier:
Иногда встречаются LDAP-ссылки в корпоративных PKI:
ldap://ca.example.com/cn=IntermediateCA,dc=example,dc=com
Расширение может содержать несколько записей, и порядок имеет значение:
Пример структуры:
[
{ method: "OCSP", url: "http://ocsp1.example.com" },
{ method: "OCSP", url: "http://ocsp2.example.com" },
{ method: "CA_ISSUERS", url: "http://ca.example.com/1.crt" }
]
В логике построения цепочки сертификатов AIA используется как fallback механизм:
При работе с AIA следует учитывать:
Поэтому AIA обычно используется совместно с внешними HTTP-клиентами (fetch, axios).
async function parseAIA(certPEM) {
const x = new X509();
x.readCertPEM(certPEM);
const exts = x.getExtInfo();
const result = {
ocsp: [],
issuers: []
};
exts.forEach(ext => {
if (ext.extname === "authorityInfoAccess") {
ext.value.forEach(item => {
if (item.accessMethod === "1.3.6.1.5.5.7.48.1") {
result.ocsp.push(item.accessLocation);
}
if (item.accessMethod === "1.3.6.1.5.5.7.48.2") {
result.issuers.push(item.accessLocation);
}
});
}
});
return result;
}