Класс KJUR.asn1.tsp.TimeStampReq

Класс KJUR.asn1.tsp.TimeStampReq в библиотеке Jsrsasign реализует формирование ASN.1 структуры запроса временной метки в соответствии с RFC 3161. Этот запрос отправляется в TSA (Time Stamping Authority) для получения криптографически доказанного времени существования данных.

Запрос временной метки представляет собой строго определённую ASN.1 структуру:

TimeStampReq ::= SEQUENCE  {
   version                      INTEGER  { v1(1) },
   messageImprint              MessageImprint,
   reqPolicy                  TSAPolicyId              OPTIONAL,
   nonce                      INTEGER                  OPTIONAL,
   certReq                   BOOLEAN                  DEFAULT FALSE,
   extensions                [0] IMPLICIT Extensions  OPTIONAL
}

В Jsrsasign этот объект инкапсулирует все поля и предоставляет механизм генерации корректно закодированного DER-представления.


Создание экземпляра TimeStampReq

Экземпляр запроса создаётся через конструктор с параметром-объектом, содержащим поля структуры:

var req = new KJUR.asn1.tsp.TimeStampReq({
    version: 1,
    messageImprint: {...},
    reqPolicy: "1.2.3.4.5",
    nonce: "12345678",
    certReq: true
});

Основная идея реализации — декларативное описание ASN.1 структуры через JavaScript-объект, который затем преобразуется в бинарный DER.


Поле version

Поле version определяет версию протокола. В RFC 3161 используется единственное допустимое значение:

  • 1 — соответствует v1

В библиотеке Jsrsasign это значение обычно устанавливается автоматически, но может быть задано явно:

version: 1

messageImprint — криптографический отпечаток данных

Ключевым элементом запроса является messageImprint. Он содержит хешируемые данные и алгоритм хеширования.

ASN.1 структура:

MessageImprint ::= SEQUENCE {
    hashAlgorithm                AlgorithmIdentifier,
    hashedMessage               OCTET STRING
}

В Jsrsasign этот объект формируется через KJUR.asn1.tsp.MessageImprint.

Пример:

messageImprint: {
    hashAlg: "sha256",
    data: "4a656665"
}

Алгоритм хеширования

Поддерживаются стандартные криптографические алгоритмы:

  • SHA-1 (устаревший)
  • SHA-256 (рекомендуемый)
  • SHA-384
  • SHA-512

Алгоритм задаётся либо строкой, либо OID-идентификатором.


reqPolicy — политика TSA

Поле reqPolicy задаёт идентификатор политики временной метки (OID), определяющий правила выдачи меток.

Пример:

reqPolicy: "1.3.6.1.4.1.13762.3"

Если поле не указано, TSA применяет политику по умолчанию.


nonce — защита от повторных атак

nonce — случайное или псевдослучайное число, используемое для защиты от replay-атак.

Особенности:

  • должен быть уникальным для каждого запроса
  • может быть строкой или числом
  • возвращается в ответе TSA для сопоставления

Пример:

nonce: "987654321"

certReq — запрос сертификата TSA

Поле certReq указывает, должен ли TSA включать свой сертификат в ответ.

  • true — сертификат включается
  • false или отсутствие поля — сертификат не требуется

Пример:

certReq: true

Это полезно при валидации подписи ответа.


extensions — расширения запроса

Поле extensions позволяет добавлять дополнительные ASN.1 расширения.

Структура соответствует стандартным X.509 расширениям.

Пример:

extensions: [
    {
        extnID: "1.2.3.4.5",
        critical: false,
        extnValue: "0500"
    }
]

Расширения кодируются как [0] IMPLICIT Extensions.


Внутренняя ASN.1 модель

После создания объекта Jsrsasign строит ASN.1 дерево:

SEQUENCE
 ├─ INTEGER (version)
 ├─ SEQUENCE (messageImprint)
 ├─ OBJECT IDENTIFIER (reqPolicy) [optional]
 ├─ INTEGER (nonce) [optional]
 ├─ BOOLEAN (certReq)
 └─ [0] EXPLICIT Extensions [optional]

Каждый узел представляет собой экземпляр KJUR.asn1.ASN1Object.


Генерация DER-кода

Основная операция класса — кодирование структуры в DER:

var der = req.getEncodedHex();

или

var der = req.getEncoded();

Результат:

  • HEX-строка ASN.1 DER
  • готовый пакет для отправки в TSA через HTTP POST

Пример полного формирования запроса

var req = new KJUR.asn1.tsp.TimeStampReq({
    version: 1,
    messageImprint: {
        hashAlg: "sha256",
        data: KJUR.crypto.Util.hashString("hello", "sha256")
    },
    reqPolicy: "1.2.3.4.5",
    nonce: "123456789",
    certReq: true
});

var der = req.getEncodedHex();

Этот DER-код затем передаётся в TSA endpoint в бинарном виде.


Взаимодействие с другими компонентами Jsrsasign

TimeStampReq тесно связан с другими классами:

  • KJUR.asn1.tsp.MessageImprint — формирование хеша
  • KJUR.crypto.Util — вычисление digest
  • KJUR.asn1.ASN1Object — базовый класс всех ASN.1 структур

В типичной цепочке:

  1. Вычисляется хеш данных
  2. Формируется MessageImprint
  3. Создаётся TimeStampReq
  4. Кодируется DER
  5. Отправляется в TSA

Особенности реализации

Автоматическая нормализация типов

Библиотека приводит входные значения к ASN.1 типам:

  • строки → OCTET STRING или OBJECT IDENTIFIER
  • числа → INTEGER
  • boolean → BOOLEAN

Обработка отсутствующих полей

Опциональные поля полностью исключаются из структуры, а не кодируются как null.

Совместимость с RFC 3161

Реализация строго следует стандарту:

  • корректная DER-энкодировка
  • фиксированный порядок полей
  • поддержка обязательных и optional элементов

Типичные ошибки при формировании запроса

Несовпадение алгоритма хеширования

Если TSA ожидает SHA-256, а передан SHA-1, запрос будет отклонён.

Некорректный nonce

Повторяющиеся значения nonce могут привести к отказу в обработке или невозможности сопоставления ответа.

Ошибки DER-кодирования

Любые ручные модификации HEX-строки после генерации могут привести к нарушению структуры ASN.1.


Практическая роль класса в криптографическом процессе

KJUR.asn1.tsp.TimeStampReq выполняет ключевую роль в построении доверенной временной метки:

  • фиксирует состояние данных через хеш
  • формирует запрос к доверенному источнику времени
  • обеспечивает доказуемость существования данных на момент выдачи TSA-ответа

Этот механизм используется в:

  • цифровых подписях
  • архивировании юридически значимых документов
  • блокчейн-подобных системах аудита
  • PKI-инфраструктурах