jsrsasign предоставляет полноценный набор инструментов для работы с криптографическими структурами, включая ASN.1-деревья, X.509, PKCS
OCSP-запрос (Online Certificate Status Protocol Request) представляет
собой ASN.1-структуру OCSPRequest, которая включает:
TBSRequest (To Be Signed Request)OptionalSignature (подпись запроса, если
используется)requestList (набор идентификаторов сертификатов)extensions (например, nonce для защиты от
replay-атак)В jsrsasign вся модель разбита на набор конструкторов в
KJUR.asn1.ocsp, где каждая ASN.1-сущность соответствует
отдельному классу.
Пространство имён KJUR.asn1.ocsp содержит ключевые
классы:
OCSPRequestTBSRequestRequestRequestListCertIDSignatureResponseData (используется уже на стороне ответа, но
связан с моделью запроса)Каждый класс строит ASN.1 объект через базовые примитивы
KJUR.asn1.DERSequence, DERInteger,
DEROctetString, DERObjectIdentifier.
Центральный элемент OCSP-запроса — CertID. Он
определяет, какой сертификат проверяется.
Структура CertID:
В jsrsasign это реализуется через:
var certID = new KJUR.asn1.ocsp.CertID({
hashAlg: "sha1",
issuerCert: issuerCertObj,
subjectCert: targetCertObj
});
При этом библиотека автоматически:
RequestList представляет массив запросов к OCSP
responder.
Каждый элемент — это структура Request, содержащая:
reqCert (CertID)singleRequestExtensions (опционально)Пример создания:
var request = new KJUR.asn1.ocsp.Request({
reqCert: certID
});
var requestList = [request];
Внутри RequestList формируется ASN.1 Sequence,
содержащая множество Request.
TBSRequest (To Be Signed Request) является основной
частью запроса до подписи.
Он включает:
Формирование:
var tbsReq = new KJUR.asn1.ocsp.TBSRequest({
reqList: requestList,
extensions: [
{
extname: "nonce",
value: "AUTO"
}
]
});
Nonce используется для предотвращения replay-атак. jsrsasign поддерживает автоматическую генерацию:
ASN.1 структура:
id-pkix-ocsp-nonce OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 }
В jsrsasign:
extensions: [
{ extname: "nonce", value: "hex:01aabbcc" }
]
или автоматический режим:
{ extname: "nonce", value: "AUTO" }
Финальный объект OCSPRequest объединяет все части:
var ocspReq = new KJUR.asn1.ocsp.OCSPRequest({
tbsRequest: tbsReq
});
ASN.1 структура:
OCSPRequest ::= SEQUENCE {
tbsRequest TBSRequest,
optionalSignature [0] EXPLICIT Signature OPTIONAL
}
Хотя многие OCSP-запросы не подписываются, спецификация допускает
Signature.
В jsrsasign:
var signedOCSPReq = new KJUR.asn1.ocsp.OCSPRequest({
tbsRequest: tbsReq,
certs: [signerCert],
sigalg: "SHA256withRSA",
prvkey: privateKey
});
Подпись включает:
Библиотека формирует:
Signature AlgorithmIdentifierВнутренняя структура после сериализации:
OCSPRequest
├── TBSRequest
│ ├── version
│ ├── requestList
│ │ └── Request
│ │ └── CertID
│ └── extensions
└── signature (optional)
var issuerCert = X509.loadCert(issuerPem);
var targetCert = X509.loadCert(targetPem);
var certID = new KJUR.asn1.ocsp.CertID({
hashAlg: "sha256",
issuerCert: issuerCert,
subjectCert: targetCert
});
var request = new KJUR.asn1.ocsp.Request({
reqCert: certID
});
var tbsReq = new KJUR.asn1.ocsp.TBSRequest({
reqList: [request],
extensions: [
{ extname: "nonce", value: "AUTO" }
]
});
var ocspReq = new KJUR.asn1.ocsp.OCSPRequest({
tbsRequest: tbsReq
});
var der = ocspReq.getEncodedHex();
Результат getEncodedHex() возвращает DER-кодировку:
Часто применяется:
var b64 = hextob64(der);
и далее передаётся:
Content-Type: application/ocsp-request
Ключевые особенности:
Hash вычисляется по строгим правилам:
Где H — выбранная хэш-функция.
Ошибки в CertID приводят к:
Помимо nonce, поддерживаются:
Формат:
{
extname: "custom",
extnID: "1.2.3.4.5",
extnValue: "hex:..."
}
KJUR.asn1.ocsp.Request является тонкой обёрткой:
Пример расширения запроса:
{
reqCert: certID,
singleRequestExtensions: [
{ extname: "nonce", value: "AUTO" }
]
}
Генерация OCSP-запросов в jsrsasign:
Основные ограничения:
OCSP-запросы опираются на:
jsrsasign использует внутренние парсеры X.509 для: