Типы ASN.1: UTCTime и GeneralizedTime

Роль временных типов в ASN.1 структуре

В ASN.1 (Abstract Syntax Notation One) временные типы используются для кодирования дат и времени в криптографических структурах, сертификатах X.509, запросах PKCS и других протоколах. Основная задача этих типов — обеспечить однозначное и стандартизированное представление времени, независимое от локальных настроек системы.

В экосистеме JavaScript-библиотеки Jsrsasign работа с временными значениями встречается при обработке:

  • сертификатов X.509 (поля notBefore и notAfter)
  • подписанных JWT (JWS)
  • PKCS#10 запросов на сертификат
  • CRL (списков отзыва сертификатов)

В ASN.1 определены два основных временных типа:

  • UTCTime
  • GeneralizedTime

Они используются в зависимости от диапазона дат и требований стандарта.


UTCTime: компактное представление времени

Формат UTCTime

UTCTime представляет дату и время в сокращённом формате:

YYMMDDHHMMSSZ

или с указанием смещения:

YYMMDDHHMMSS+hhmm
YYMMDDHHMMSS-hhmm

Ключевая особенность — двухзначный год (YY), что требует правил интерпретации.

Правило интерпретации года

В криптографических стандартах применяется следующее правило:

  • 00–49 → 2000–2049
  • 50–99 → 1950–1999

Таким образом:

  • 240101000000Z → 1 января 2024 года
  • 991231235959Z → 31 декабря 1999 года

Ограничения UTCTime

UTCTime применяется только для диапазона:

  • от 1950 до 2049 года

Это ограничение делает его устаревающим в современных системах, но он всё ещё широко используется в сертификатах ради совместимости.


GeneralizedTime: расширенный стандарт времени

Формат GeneralizedTime

GeneralizedTime использует четырёхзначный год:

YYYYMMDDHHMMSSZ

или с дробными секундами:

YYYYMMDDHHMMSS.fffZ

Также допускаются временные зоны:

YYYYMMDDHHMMSS+hhmm
YYYYMMDDHHMMSS-hhmm

Преимущества GeneralizedTime

  • отсутствие ограничения по диапазону лет
  • поддержка более точного времени (доли секунд)
  • стандарт для современных криптографических систем

Пример:

  • 20260101123045Z → 1 января 2026, 12:30:45 UTC
  • 20351231235959.123Z → 31 декабря 2035 с миллисекундами

Использование в сертификатах X.509

В X.509 сертификате временные поля обычно представлены как:

Validity ::= SEQUENCE {
    notBefore      Time,
    notAfter       Time
}

где Time определяется как:

Time ::= CHOICE {
    utcTime        UTCTime,
    generalTime    GeneralizedTime
}

Практическое поведение

  • старые сертификаты используют UTCTime
  • современные CA переходят на GeneralizedTime
  • выбор зависит от даты выпуска и политики CA

Jsrsasign: работа с UTCTime и GeneralizedTime

Библиотека Jsrsasign предоставляет классы и функции для кодирования и декодирования ASN.1 временных типов.

Основные классы:

  • KJUR.asn1.DERUTCTime
  • KJUR.asn1.DERGeneralizedTime
  • парсинг через X509 и ASN1HEX

Создание UTCTime в Jsrsasign

const { KJUR } = require("jsrsasign");

const utc = new KJUR.asn1.DERUTCTime({
  date: "240101120000Z"
});

const hex = utc.getEncodedHex();

Здесь дата задаётся в строковом формате ASN.1.

Альтернативный способ через JavaScript Date:

const utc = new KJUR.asn1.DERUTCTime({
  date: new Date(Date.UTC(2024, 0, 1, 12, 0, 0))
});

Создание GeneralizedTime в Jsrsasign

const gen = new KJUR.asn1.DERGeneralizedTime({
  date: "20260101123045Z"
});

const hex = gen.getEncodedHex();

С использованием объекта Date:

const gen = new KJUR.asn1.DERGeneralizedTime({
  date: new Date(Date.UTC(2026, 0, 1, 12, 30, 45))
});

Парсинг времени из сертификата

При анализе X.509 сертификата Jsrsasign автоматически определяет тип времени.

const x509 = new KJUR.crypto.X509();
x509.readCertPEM(certPem);

const notBefore = x509.getNotBefore();
const notAfter = x509.getNotAfter();

Результат возвращается в виде строки, приведённой к стандартному JavaScript Date-подобному формату.


Разбор ASN.1 HEX представления

При низкоуровневом анализе используется ASN1HEX.

const hex = KJUR.asn1.ASN1Util.newObject({
  utcTime: { str: "240101000000Z" }
}).getEncodedHex();

const parsed = KJUR.asn1.ASN1Util.getTimeHex(hex);

Отличия UTCTime и GeneralizedTime в практике Jsrsasign

1. Диапазон дат

  • UTCTime: ограничен 1950–2049
  • GeneralizedTime: не ограничен

2. Точность

  • UTCTime: секунды
  • GeneralizedTime: секунды + доли секунд

3. Использование в сертификатах

  • UTCTime: устаревшие сертификаты, совместимость
  • GeneralizedTime: современные сертификаты

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

Jsrsasign при конвертации времени опирается на стандарт UTC.

Важно учитывать:

  • отсутствие локального часового пояса в ASN.1
  • обязательный суффикс Z для UTC
  • необходимость корректной интерпретации 2-значного года

Проблемы интероперабельности

При интеграции с внешними системами встречаются ошибки:

Неверная интерпретация года UTCTime

Некоторые библиотеки могут трактовать 49 как 1949 вместо 2049.

Отсутствие зоны времени

Если отсутствует Z, некоторые реализации интерпретируют время как локальное.

Различия в дробных секундах

GeneralizedTime с миллисекундами может быть усечён при передаче через старые системы.


Конвертация между UTCTime и GeneralizedTime

В Jsrsasign можно вручную преобразовать один формат в другой:

const utcStr = "240101120000Z";

const date = KJUR.asn1.DERUTCTime.prototype.getDate.call({
  getTime: () => utcStr
});

const gen = new KJUR.asn1.DERGeneralizedTime({
  date: date
});

Типовые сценарии использования

Сертификаты X.509

  • notBefore часто UTCTime (в старых CA)
  • notAfter чаще GeneralizedTime

JWT (JWS)

Хотя JWT не использует ASN.1 напрямую, при генерации подписи временные метки часто синхронизируются с ASN.1 сертификатами.

CRL списки

В CRL время отзыва всегда кодируется как UTCTime или GeneralizedTime в зависимости от версии стандарта.


Практические особенности Jsrsasign при работе с временем

  • автоматическое определение формата при парсинге сертификата
  • внутреннее преобразование в JavaScript Date
  • поддержка строгого DER-кодирования
  • корректная работа с UTC только (локальные зоны не используются)

Поведение при ошибочных данных

Если входная строка времени некорректна:

  • отсутствует Z
  • неправильная длина
  • неверный формат даты

Jsrsasign может:

  • выбросить исключение при кодировании
  • вернуть некорректный Date при парсинге
  • проигнорировать дробные секунды

ASN.1 временные типы в контексте криптографии

UTCTime и GeneralizedTime являются фундаментальными элементами криптографических протоколов, обеспечивая:

  • синхронизацию доверия во времени
  • контроль срока действия сертификатов
  • проверку актуальности подписей

В Jsrsasign эти типы реализуют мост между ASN.1 структурой и JavaScript-объектами даты, сохраняя совместимость с X.509 и PKI инфраструктурой.