OCSP (Online Certificate Status Protocol) используется для проверки статуса X.509-сертификата в режиме реального времени. Запрос OCSP представляет собой ASN.1-структуру, кодируемую в DER-формате и передаваемую обычно через HTTP POST или GET. В библиотеке Jsrsasign формирование OCSP-запроса абстрагируется через высокоуровневые API, однако понимание внутреннего формата необходимо для корректной работы с низкоуровневыми криптографическими механизмами и отладкой.
OCSP-запрос определяется спецификацией RFC 6960 и имеет следующую общую структуру:
OCSPRequest
tbsRequest (to be signed request)
version (по умолчанию v1)
requestorName (опционально)
requestList
Request
reqCert
singleRequestExtensions (опционально)
requestExtensions (опционально)
optionalSignature (опционально)
Ключевым элементом является tbsRequest, который содержит все данные, необходимые для проверки статуса сертификата.
TBSRequest (To Be Signed Request) — это центральная часть OCSP-запроса. Он включает список проверяемых сертификатов и дополнительные параметры.
В Jsrsasign эта структура формируется через внутренние ASN.1-конструкторы:
Каждый запрос OCSP может содержать несколько объектов Request, что позволяет проверять несколько сертификатов одним запросом.
CertID является ключевым элементом, идентифицирующим сертификат, статус которого проверяется. Он состоит из трех компонентов:
В Jsrsasign создание CertID осуществляется через вычисление хешей на основе сертификата издателя:
var cert = new X509();
cert.readCertPEM(pemIssuerCert);
var ocsp = new KJUR.asn1.ocsp.OCSPReqBuilder();
var req = ocsp.makeRequest({
cert: targetCert,
issuerCert: issuerCert,
alg: "sha256"
});
При этом библиотека автоматически извлекает необходимые поля из сертификатов и формирует корректный ASN.1-объект.
requestList представляет собой последовательность объектов Request. Каждый Request включает CertID и дополнительные расширения.
ASN.1-структура:
В Jsrsasign добавление нескольких запросов реализуется через массив сертификатов:
var builder = new KJUR.asn1.ocsp.OCSPReqBuilder();
builder.addRequest({
cert: cert1,
issuerCert: issuerCert
});
builder.addRequest({
cert: cert2,
issuerCert: issuerCert
});
var ocspReq = builder.build();
OCSP поддерживает расширения, определяемые в формате X.509 Extensions. Они могут включаться как на уровне всего запроса, так и на уровне отдельного Request.
Наиболее распространённые расширения:
В Jsrsasign nonce добавляется автоматически или задаётся вручную:
var builder = new KJUR.asn1.ocsp.OCSPReqBuilder({
nonce: "random"
});
Nonce кодируется как OCTET STRING внутри структуры Extensions.
Полный ASN.1 синтаксис OCSPRequest:
OCSPRequest ::= SEQUENCE { tbsRequest TBSRequest, optionalSignature [0] EXPLICIT Signature OPTIONAL }
TBSRequest ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, requestorName [1] EXPLICIT GeneralName OPTIONAL, requestList SEQUENCE OF Request, requestExtensions [2] EXPLICIT Extensions OPTIONAL }
Signature ::= SEQUENCE { signatureAlgorithm AlgorithmIdentifier, signature BIT STRING, certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
В большинстве случаев OCSP-запросы не подписываются, и optionalSignature отсутствует.
После формирования структуры Jsrsasign выполняет DER-кодирование. Каждый элемент преобразуется в ASN.1 DER TLV:
Пример итогового бинарного запроса:
SEQUENCE
DER-результат затем преобразуется в Base64 или отправляется в бинарном виде.
OCSP-запрос передаётся через HTTP следующим образом:
Пример формирования запроса:
var req = builder.build();
var httpBody = req.getContentHex();
fetch(ocspUrl, {
method: "POST",
headers: {
"Content-Type": "application/ocsp-request"
},
body: new Uint8Array(req.getContentByte())
});
В Jsrsasign методы getContentHex и getContentByte предоставляют доступ к бинарному представлению запроса.
Для корректного формирования OCSP-запроса необходимо точное соответствие issuerCert. Ошибки в хешировании приводят к отсутствию валидного ответа от OCSP responder.
Алгоритм формирования:
Jsrsasign выполняет эти операции автоматически через X509-парсер и CryptoJS/forge backend.
На уровне структуры OCSPRequest часто возникают следующие проблемы:
Особое внимание требуется при работе с современными CA, которые требуют SHA-256 CertID.
Jsrsasign предоставляет универсальный ASN.1 API, позволяющий вручную строить OCSP-запрос:
var asn1 = new KJUR.asn1.ASN1Object();
var certId = new KJUR.asn1.ocsp.CertID({
hashAlg: "sha256",
issuerCert: issuerCert,
subjectCert: cert
});
var request = new KJUR.asn1.DERSequence({
array: [
certId.asn1obj
]
});
Такой подход используется при необходимости полного контроля над структурой запроса.
OCSPReqBuilder в Jsrsasign выполняет несколько операций:
Основное преимущество — автоматическое соблюдение RFC 6960 без ручной работы с ASN.1 уровнями.
OCSPRequest должен быть совместим с серверной реализацией OCSP responder. На практике это означает:
Некоторые старые responder требуют только SHA-1 CertID, тогда как современные инфраструктуры используют SHA-256.
Процесс формирования OCSPRequest в Jsrsasign можно представить как последовательность:
Эта модель соответствует RFC-спецификации и обеспечивает совместимость с большинством PKI-инфраструктур.