RecipientInfo: KeyTransRecipientInfo

RecipientInfo в CMS (Cryptographic Message Syntax, PKCS

В jsrsasign работа с CMS реализована через пространство имён KJUR.asn1.cms, где структуры данных соответствуют ASN.1-описанию стандарта RFC 5652.

KeyTransRecipientInfo применяется в случаях, когда отправитель заранее знает публичный ключ получателя и использует его для шифрования содержимого ключа (Content Encryption Key, CEK). В отличие от KeyAgreeRecipientInfo, здесь не выполняется протокол согласования ключа, а происходит прямое шифрование.


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

Формальная структура CMS определяет KeyTransRecipientInfo следующим образом:

KeyTransRecipientInfo ::= SEQUENCE {
    version CMSVersion,  -- integer
    rid RecipientIdentifier,
    keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
    encryptedKey EncryptedKey
}

version

Поле version определяет версию структуры:

  • 0 — используется при IssuerAndSerialNumber
  • 2 — используется при SubjectKeyIdentifier

Это значение зависит от способа идентификации получателя.


RecipientIdentifier (rid)

RecipientIdentifier может быть двух типов:

RecipientIdentifier ::= CHOICE {
    issuerAndSerialNumber IssuerAndSerialNumber,
    subjectKeyIdentifier [0] SubjectKeyIdentifier
}

IssuerAndSerialNumber

Наиболее распространённый вариант в PKI:

  • issuer — DN издателя сертификата
  • serialNumber — серийный номер сертификата

SubjectKeyIdentifier

Используется идентификатор открытого ключа, извлечённый из сертификата.


keyEncryptionAlgorithm

Описывает алгоритм шифрования симметричного ключа.

Чаще всего используется:

  • RSAES-OAEP
  • rsaEncryption (PKCS#1 v1.5)

Пример OID:

  • 1.2.840.113549.1.1.1 — RSA encryption
  • 1.2.840.113549.1.1.7 — RSAES-OAEP

encryptedKey

Содержит симметричный ключ (CEK), зашифрованный публичным ключом получателя.


Представление в jsrsasign

В jsrsasign структура KeyTransRecipientInfo создаётся через ASN.1 конструкторы:

var KJUR = require("jsrsasign");

var ri = new KJUR.asn1.cms.RecipientIdentifier({
    type: "issuerAndSerialNumber",
    issuer: {
        str: "/C=US/O=Test/CN=Test CA"
    },
    serial: { int: 123456 }
});

Формирование KeyTransRecipientInfo

Пример создания структуры KeyTransRecipientInfo с RSA:

var KJUR = require("jsrsasign");

// алгоритм шифрования ключа
var alg = new KJUR.asn1.x509.AlgorithmIdentifier({
    name: "rsaEncryption"
});

// идентификатор получателя
var rid = new KJUR.asn1.cms.RecipientIdentifier({
    type: "issuerAndSerialNumber",
    issuer: {
        str: "/C=RU/O=Example/CN=Recipient"
    },
    serial: {
        int: 10001
    }
});

// зашифрованный симметричный ключ (пример байтов)
var encryptedKeyHex = "a1b2c3d4e5f6";

// KeyTransRecipientInfo
var ktri = new KJUR.asn1.cms.KeyTransRecipientInfo({
    version: 0,
    rid: rid,
    keyEncryptionAlgorithm: alg,
    encryptedKey: {
        hex: encryptedKeyHex
    }
});

Использование SubjectKeyIdentifier

Альтернативный вариант идентификации:

var ridSKI = new KJUR.asn1.cms.RecipientIdentifier({
    type: "subjectKeyIdentifier",
    ski: {
        hex: "1a2b3c4d5e6f"
    }
});

В этом случае версия структуры меняется на 2, поскольку используется SKI вместо IssuerAndSerialNumber.


Встраивание в CMS EnvelopedData

KeyTransRecipientInfo является частью массива RecipientInfos внутри EnvelopedData:

EnvelopedData ::= SEQUENCE {
    version CMSVersion,
    originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL,
    recipientInfos RecipientInfos,
    encryptedContentInfo EncryptedContentInfo,
    ...
}

В jsrsasign:

var env = new KJUR.asn1.cms.EnvelopedData({
    version: 2,
    recipientInfos: [ktri],
    encryptedContentInfo: {
        contentType: "data",
        contentEncryptionAlgorithm: {
            name: "aes-256-cbc",
            iv: { hex: "00112233445566778899aabbccddeeff" }
        },
        encryptedContent: {
            hex: "deadbeef..."
        }
    }
});

Алгоритмическая логика KeyTransRecipientInfo

Процесс формирования структуры включает несколько этапов:

  1. Генерация симметричного ключа CEK
  2. Шифрование данных симметричным алгоритмом (AES, 3DES и др.)
  3. Шифрование CEK открытым RSA-ключом получателя
  4. Формирование структуры RecipientIdentifier
  5. Упаковка зашифрованного ключа в encryptedKey

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

ASN.1 представление

Библиотека строго следует DER-кодированию:

  • обязательная сортировка SEQUENCE
  • фиксированные INTEGER-представления
  • строгая типизация OCTET STRING

Ограничения

KeyTransRecipientInfo в jsrsasign ориентирован на базовые сценарии CMS:

  • RSA как основной механизм key transport
  • ограниченная поддержка современных гибридных схем
  • отсутствие полноценного KEM (Key Encapsulation Mechanism)

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

Несовпадение version и rid

Если используется SKI, но version остаётся 0, структура становится некорректной для строгих CMS-парсеров.

Некорректный формат encryptedKey

encryptedKey должен быть:

  • бинарным значением DER-кодировки результата RSA
  • не строкой ASCII
  • не Base64 без декодирования

Практическая интерпретация CMS-пакета

При разборе CMS в jsrsasign:

var cms = new KJUR.asn1.cms.ContentInfo({ 
    hextStr: cmsHex 
});

var recipientInfos = cms.asn1.recipientInfos;

KeyTransRecipientInfo извлекается как элемент SEQUENCE внутри RecipientInfos, где каждый элемент соответствует отдельному получателю.


Взаимодействие с X.509 сертификатами

RecipientIdentifier напрямую связан с сертификатом:

  • IssuerAndSerialNumber сопоставляется с полями X.509
  • SKI извлекается из расширений SubjectKeyIdentifier

Пример получения SKI из сертификата:

var x509 = new X509();
x509.readCertPEM(certPem);

var ski = x509.getExtSubjectKeyIdentifier();

Совместимость с CMS стандартами

KeyTransRecipientInfo соответствует:

  • RFC 5652 (Cryptographic Message Syntax)
  • PKCS#7 v2.0
  • PKCS#1 для RSA шифрования ключей

Структура остаётся совместимой с OpenSSL, Java CMS, .NET System.Security.Cryptography.Pkcs.


Роль в гибридном шифровании

KeyTransRecipientInfo реализует классическую гибридную схему:

  • симметричное шифрование данных обеспечивает скорость
  • асимметричное шифрование ключа обеспечивает безопасную доставку

В CMS это основная модель для EnvelopedData без использования соглашений о ключах.