Структура TSTInfo

TSTInfo представляет собой ключевую ASN.1-структуру, используемую в протоколе доверенного времени (Time-Stamp Protocol, RFC 3161). Она входит в состав временной метки, формируемой удостоверяющим центром (Time Stamping Authority, TSA), и содержит всю необходимую информацию для проверки того, что данные существовали в определённый момент времени и не были изменены.

В библиотеке Jsrsasign работа с TSTInfo обычно происходит через ASN.1-парсеры и утилиты пакета KJUR.asn1.tsp, которые позволяют декодировать DER-кодированные структуры и извлекать поля временной метки.


TSTInfo описывается ASN.1-схемой:

TSTInfo ::= SEQUENCE  {
   version                      INTEGER,
   policy                       TSAPolicyId,
   messageImprint              MessageImprint,
   serialNumber                INTEGER,
   genTime                     GeneralizedTime,
   accuracy                    Accuracy OPTIONAL,
   ordering                    BOOLEAN DEFAULT FALSE,
   nonce                       INTEGER OPTIONAL,
   tsa                         [0] GeneralName OPTIONAL,
   extensions                  [1] IMPLICIT Extensions OPTIONAL
}

Каждое поле несёт строго определённую криптографическую и семантическую нагрузку, обеспечивающую проверяемость временной метки.


Версия структуры

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

  • version = 1

В Jsrsasign это поле извлекается как целое число из ASN.1 INTEGER:

const ver = tstinfo.version;

Несмотря на простоту, это поле важно для обратной совместимости при изменениях стандарта.


Политика временной метки

Поле policy содержит OID политики TSA, по которой был сформирован токен.

Пример OID:

  • 1.2.3.4.5.6.7.8.1

В Jsrsasign оно представлено строкой:

const policy = tstinfo.policy;

Этот идентификатор позволяет определить правила формирования и проверки подписи временной метки.


MessageImprint — отпечаток данных

Ключевой элемент структуры — messageImprint, представляющий собой хеш исходных данных.

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

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

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

Поле hashAlgorithm определяет криптографический алгоритм:

  • SHA-256 (2.16.840.1.101.3.4.2.1)
  • SHA-1 (устаревший, но поддерживаемый в старых системах)

В Jsrsasign:

const algo = tstinfo.messageImprint.hashAlgorithm.name;

Хеш сообщения

Поле hashedMessage содержит фактический хеш данных:

const hash = tstinfo.messageImprint.hashedMessage;

Именно это значение сравнивается с вычисленным хешем при проверке временной метки.


Серийный номер

Поле serialNumber — уникальный идентификатор временной метки, присваиваемый TSA.

Обычно это большое целое число:

const serial = tstinfo.serialNumber;

Серийный номер обеспечивает уникальность каждой выпущенной метки в рамках политики TSA.


Время генерации

Поле genTime содержит момент формирования временной метки в формате GeneralizedTime.

Пример:

20260101123045Z

В Jsrsasign:

const genTime = tstinfo.genTime;

Это поле является основным доказательством временной фиксации события.


Точность времени

Поле accuracy определяет допустимую погрешность временной метки.

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

Accuracy ::= SEQUENCE {
   seconds        INTEGER OPTIONAL,
   millis         [0] INTEGER OPTIONAL,
   micros         [1] INTEGER OPTIONAL
}

Возможные компоненты:

  • секунды
  • миллисекунды
  • микросекунды

В Jsrsasign:

const acc = tstinfo.accuracy;

Если поле отсутствует, точность считается неопределённой или нулевой.


Флаг порядка

Поле ordering определяет, допускается ли строгий порядок временных меток.

  • TRUE — TSA гарантирует упорядочивание
  • FALSE — порядок не гарантируется

В Jsrsasign:

const ordering = tstinfo.ordering;

Это поле важно для систем, где последовательность событий критична.


Nonce

Поле nonce используется для защиты от повторного воспроизведения (replay attack).

Это случайное число, которое клиент отправляет при запросе временной метки, и TSA возвращает его обратно.

const nonce = tstinfo.nonce;

Совпадение nonce при проверке подтверждает актуальность ответа TSA.


Идентификация TSA

Поле tsa содержит идентификатор удостоверяющего центра.

Тип — GeneralName, который может включать:

  • DNS-имя
  • Distinguished Name (DN)
  • IP-адрес

В Jsrsasign:

const tsa = tstinfo.tsa;

Пример DN:

CN=Trusted Timestamp Authority, O=Example CA, C=US

Расширения структуры

Поле extensions позволяет добавлять дополнительные атрибуты, не входящие в базовый стандарт.

Типично используется для:

  • политик расширенной валидации
  • метаданных сертификата TSA
  • внутренних атрибутов инфраструктуры PKI

В Jsrsasign:

const ext = tstinfo.extensions;

Разбор TSTInfo в Jsrsasign

Декодирование DER-структуры обычно выполняется через:

const asn1 = KJUR.asn1.ASN1Util.newObject({
  "seq": [
    {"int": 1},
    {"oid": "1.2.3.4.5"},
    {"seq": [
      {"oid": "2.16.840.1.101.3.4.2.1"},
      {"octstr": "abc123..."}
    ]},
    {"int": 123456789},
    {"gentime": "20260102120000Z"}
  ]
});

В реальных сценариях используется:

const tstinfo = new KJUR.asn1.tsp.TSTInfo({asn1: der});

После декодирования структура становится доступной как объект JavaScript.


Взаимосвязь полей

Все элементы TSTInfo образуют связанную систему:

  • messageImprint связывает временную метку с исходными данными
  • genTime фиксирует момент существования этих данных
  • serialNumber обеспечивает уникальность записи
  • policy определяет правила доверия
  • nonce защищает от повторного воспроизведения
  • tsa подтверждает источник

Эта структура позволяет построить криптографически проверяемую цепочку доверия к времени.


Особенности обработки в Jsrsasign

При работе с TSTInfo в Jsrsasign учитываются особенности ASN.1 кодирования:

  • DER обязателен для корректной проверки подписи
  • OCTET STRING часто содержит вложенные структуры
  • GeneralizedTime требует нормализации часового пояса
  • OID декодируются в человекочитаемый формат автоматически

Внутренние функции библиотеки обеспечивают преобразование низкоуровневого ASN.1 в удобные JavaScript-объекты, сохраняя при этом исходную структуру RFC 3161 без потерь.