OCSP (Online Certificate Status Protocol) используется для получения актуального статуса X.509-сертификата без необходимости скачивать полный CRL. Ответ OCSP представляет собой ASN.1-структуру, содержащую сведения о проверяемом сертификате, статусе его отзыва и криптографической подписи центра сертификации.
В библиотеке Jsrsasign работа с OCSP-ответами реализована через набор ASN.1-парсеров и утилит для обработки криптографических структур. Основной объект, с которым происходит взаимодействие — OCSPResponse, закодированный в DER.
OCSPResponse имеет верхнеуровневую структуру:
OCSPResponse ::= SEQUENCE {
responseStatus OCSPResponseStatus,
responseBytes [0] EXPLICIT ResponseBytes OPTIONAL
}
Поле responseStatus определяет базовый результат
обработки запроса:
Если значение не равно successful, поле
responseBytes отсутствует.
Содержит закодированный ответ центра сертификации:
ResponseBytes ::= SEQUENCE {
responseType OBJECT IDENTIFIER,
response OCTET STRING
}
Для стандартного OCSP используется идентификатор:
id-pkix-ocsp-basic = 1.3.6.1.5.5.7.48.1.1
Внутри response находится структура
BasicOCSPResponse.
Основной контейнер данных OCSP:
BasicOCSPResponse ::= SEQUENCE {
tbsResponseData ResponseData,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING,
certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL
}
Ключевой элемент — ResponseData, содержащий информацию о
статусе сертификата.
ResponseData ::= SEQUENCE {
version Version DEFAULT v1,
responderID ResponderID,
producedAt GeneralizedTime,
responses SEQUENCE OF SingleResponse,
responseExtensions [1] EXPLICIT Extensions OPTIONAL
}
Каждый запрос проверяемого сертификата представлен отдельным блоком:
SingleResponse ::= SEQUENCE {
certID CertID,
certStatus CertStatus,
thisUpdate GeneralizedTime,
nextUpdate GeneralizedTime OPTIONAL,
singleExtensions [0] EXPLICIT Extensions OPTIONAL
}
Статус сертификата представлен одной из трёх форм:
В Jsrsasign обработка OCSP реализуется через пространство имён
KJUR.asn1.ocsp и вспомогательные ASN.1 парсеры.
Основной поток обработки включает:
OCSP-ответ обычно поступает в виде DER (binary) или Base64.
const ocspB64 = "MFMwUTBPME0wSzAJBgUrDgMCGgUABBR2...";
const ocspDer = KJUR.b64tohex(ocspB64);
const ocspResp = KJUR.asn1.ocsp.OCSPResponse.getInstanceFromHex(ocspDer);
После декодирования структура становится доступной как ASN.1 объект.
const status = ocspResp.getResponseStatus();
if (status !== 0) {
// ответ не содержит данных о сертификате
}
const basicResp = ocspResp.getBasicOCSPResponse();
const responseData = basicResp.tbsResponseData;
Внутри responses хранится массив проверок:
const responses = responseData.responses;
Каждый элемент содержит certStatus.
responses.forEach(r => {
const status = r.certStatus.type;
if (status === "good") {
console.log("Сертификат действителен");
}
if (status === "revoked") {
console.log("Сертификат отозван");
const revocationTime = r.certStatus.value.revocationTime;
const reason = r.certStatus.value.revocationReason;
}
if (status === "unknown") {
console.log("Статус неизвестен");
}
});
Для сопоставления ответа с запросом используется структура CertID:
CertID ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier,
issuerNameHash OCTET STRING,
issuerKeyHash OCTET STRING,
serialNumber CertificateSerialNumber
}
Jsrsasign позволяет сравнивать CertID с локально сформированным запросом OCSP:
const certId = r.certID.serialNumber.toString(16);
Криптографическая подпись находится в
BasicOCSPResponse.signature.
Проверка выполняется через публичный ключ OCSP responder:
const verifier = new KJUR.crypto.Signature({ alg: "SHA256withRSA" });
verifier.init(responderPublicKey);
verifier.updateHex(responseDataHex);
const isValid = verifier.verify(signatureHex);
Расширения могут содержать:
Обработка nonce:
const nonceExt = responseData.responseExtensions;
Сравнение nonce запроса и ответа критично для безопасности проверки.
При revoked дополнительно анализируются поля:
Причины могут включать:
OCSP использует:
Проверка актуальности:
const now = new Date();
const nextUpdate = new Date(r.nextUpdate);
if (now > nextUpdate) {
// ответ устарел
}
const ocspHex = KJUR.b64tohex(ocspBase64);
const ocsp = KJUR.asn1.ocsp.OCSPResponse.getInstanceFromHex(ocspHex);
if (ocsp.getResponseStatus() !== 0) {
throw new Error("OCSP response invalid");
}
const basic = ocsp.getBasicOCSPResponse();
const data = basic.tbsResponseData;
data.responses.forEach(r => {
switch (r.certStatus.type) {
case "good":
console.log("OK");
break;
case "revoked":
console.log("REVOKED");
break;
case "unknown":
console.log("UNKNOWN");
break;
}
});
Jsrsasign абстрагирует ASN.1 через объектную модель:
Эта модель позволяет работать с OCSP без ручного парсинга ASN.1-дерева, сохраняя доступ к низкоуровневым полям при необходимости.