Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline coldplay  
#1 Оставлено : 24 февраля 2021 г. 15:43:08(UTC)
coldplay

Статус: Активный участник

Группы: Участники
Зарегистрирован: 16.02.2016(UTC)
Сообщений: 60

Сказал(а) «Спасибо»: 18 раз
Поблагодарили: 2 раз в 2 постах
Цель залить на сервис партнеру зашифрованный подписанный файл. Используя примеры из samples.jar получаю ошибку от сервиса. По доке ошибка значит "Допустимо только шифрование PKCS#7"

Метод подписи:

Код:
.
fun sign(data: ByteArray, key: PrivateKey, cert: Certificate): ByteArray {
       val certStore: Store = JcaCertStore(setOf(cert))
        val generator = CMSSignedDataGenerator()
        val contentSigner: ContentSigner = GostContentSignerProvider(
                key, JCP.PROVIDER_NAME
        )
        val signerInfoGenerator: SignerInfoGenerator =
                JcaSignerInfoGeneratorBuilder(
                        GostDigestCalculatorProvider(key, JCP.PROVIDER_NAME)
                ).build(contentSigner, cert as X509Certificate)
        generator.addSignerInfoGenerator(signerInfoGenerator)
        generator.addCertificates(certStore)

        val content: CMSProcessable = CMSProcessableByteArray(data)
        val signedData =
                generator.generate(content as CMSTypedData, true)
        return signedData.encoded
}


Метод шифрования взял из примера CMS_samples/PKCS7EnvEphTransport:
Код:
fun encryptPkcs7(data: ByteArray, responderCert: X509Certificate): ByteArray {
    val STR_CMS_OID_DATA = "1.2.840.113549.1.7.1"
    val STR_CMS_OID_ENVELOPED = "1.2.840.113549.1.7.3"
    // Параметры шифрования симметричного ключа (по умолчанию)
    // и параметры шифрования данных (по умолчанию).
    val algIdSpec = getAlgIdSpec(responderCert)
    val recipientTransportParameters = algIdSpec.cryptParams // из открытого ключа
    val contentEncryptionParameters = algIdSpec.cryptParams // могут быть другие
    val CIPHER_MODE = "GOST28147/CFB/NoPadding"
    // Генерирование симметричного ключа с параметрами
    // шифрования из контрольной панели.
    val kg = KeyGenerator.getInstance(
            "GOST28147", "Crypto")
    // Инициализация генератора.
    kg.init(contentEncryptionParameters)
    // Симметричный ключ.
    val symmetricKey: SecretKey = kg.generateKey()

    // Зашифрование текста на симметричном ключе.
    val cipher = Cipher.getInstance(CIPHER_MODE, "Crypto")
    cipher.init(Cipher.ENCRYPT_MODE, symmetricKey, null as SecureRandom?)
    val iv = cipher.iv
    val text = cipher.doFinal(data, 0, data.size)

    // Зашифрование симметричного ключа.
    val keyTransport = wrap(symmetricKey, responderCert.publicKey,
            recipientTransportParameters)
    // Формирование CMS-сообщения.
    val all = ContentInfo()
    all.contentType = Asn1ObjectIdentifier(OID(STR_CMS_OID_ENVELOPED).value)

    val cms = EnvelopedData()

    all.content = cms
    cms.version = CMSVersion(0)

    cms.recipientInfos = RecipientInfos(1)
    cms.recipientInfos.elements = arrayOfNulls(1)
    cms.recipientInfos.elements[0] = RecipientInfo()

    val key_trans = KeyTransRecipientInfo()
    key_trans.version = CMSVersion(0)

    val ebuf = Asn1BerEncodeBuffer()

    val id = algIdSpec.decoded as AlgorithmIdentifier
    id.encode(ebuf)
    var dbuf = Asn1BerDecodeBuffer(ebuf.msgCopy)
    key_trans.keyEncryptionAlgorithm = KeyEncryptionAlgorithmIdentifier()
    key_trans.keyEncryptionAlgorithm.decode(dbuf)

    ebuf.reset()
    dbuf.reset()
    key_trans.rid = RecipientIdentifier()
    val issuer = IssuerAndSerialNumber()
    val issuerName: X500Principal = responderCert.getIssuerX500Principal()
    dbuf = Asn1BerDecodeBuffer(issuerName.encoded)

    issuer.issuer = Name()
    val rnd = RDNSequence()
    rnd.decode(dbuf)
    issuer.issuer.set_rdnSequence(rnd)
    issuer.serialNumber = CertificateSerialNumber(responderCert.getSerialNumber())
    key_trans.rid.set_issuerAndSerialNumber(issuer)
    dbuf.reset()
    key_trans.encryptedKey = EncryptedKey(keyTransport)
    ebuf.reset()
    cms.recipientInfos.elements[0].set_ktri(key_trans)
    cms.encryptedContentInfo = EncryptedContentInfo()
    val contentType = OID(STR_CMS_OID_DATA)
    cms.encryptedContentInfo.contentType = ContentType(contentType.value)
    val parameters = Gost28147_89_Parameters()
    parameters.iv = Gost28147_89_IV(iv)
    parameters.encryptionParamSet = Gost28147_89_ParamSet(contentEncryptionParameters.oid.value) // параметры шифрования данных
    cms.encryptedContentInfo.contentEncryptionAlgorithm = ContentEncryptionAlgorithmIdentifier(
            _Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, parameters)

    cms.encryptedContentInfo.encryptedContent = EncryptedContent(text)
    all.encode(ebuf)
    return ebuf.msgCopy
}

@Throws(java.lang.Exception::class)
fun wrap(secretKey: SecretKey, recipientKey: PublicKey, recipientTransportParameters: ParamsInterface): ByteArray? {
    // Определение алгоритма эфемерного ключа.
    val ephKeyAlgorithm = JCP.GOST_EPH_DH_2012_256_NAME
    // Генерация эфемерной пары.
    val kgp = KeyPairGenerator.getInstance(
            ephKeyAlgorithm)
    // Устанавливаем нужные параметры, как у
    // получателя.
    val spec: AlgorithmParameterSpec = X509PublicKeySpec(recipientKey.encoded)
    kgp.initialize(spec)
    // Генерируем эфемерную пару. Ключи получат
    // параметры recipientKey, а у него параметры
    // - recipientTransportParameters.
    val ephPair = kgp.generateKeyPair()
    val privateKey = ephPair.private
    val publicKey = ephPair.public
    val syncro = ByteArray(8)
    val random = SecureRandom.getInstance(JCP.CP_RANDOM)
    random.nextBytes(syncro)
    val iv = IvParameterSpec(syncro)
    // Выработка ключа согласования.
    val ka = KeyAgreement.getInstance(privateKey.algorithm)
    ka.init(privateKey, iv)
    ka.doPhase(recipientKey, true)
    val dh: Key = ka.generateSecret("GOST28147") // dh получит параметры из privateKey, т.е. recipientTransportParameters

    // Зашифрование симметричного ключа на ключе согласования
    // отправителя. Передаются параметры шифрования ключа, если
    // отличаются от тех, что у dh.
    val cipher = Cipher.getInstance("GOST28147/CFB/NoPadding")
    cipher.init(Cipher.WRAP_MODE, dh, recipientTransportParameters, null as SecureRandom?)
    val wrappedKey = cipher.wrap(secretKey)

    // Упаковка параметров и ключа.
    val encryptedKey = Gost28147_89_EncryptedKey()
    var decoder: Asn1BerDecodeBuffer? = Asn1BerDecodeBuffer(wrappedKey)
    encryptedKey.decode(decoder)
    val imita = encryptedKey.macKey.value
    val wrapperKeyBytes = encryptedKey.encryptedKey.value

    // Кодирование открытого ключа в SubjectPublicKeyInfo.
    val publicKeyBytes = publicKey.encoded
    val publicKeyInfo = SubjectPublicKeyInfo()
    decoder = Asn1BerDecodeBuffer(publicKeyBytes)
    publicKeyInfo.decode(decoder)

    // Кодирование GostR3410_KeyTransport.
    val keyTransport = GostR3410_KeyTransport()
    val encoder = Asn1BerEncodeBuffer()
    keyTransport.sessionEncryptedKey = Gost28147_89_EncryptedKey(wrapperKeyBytes, imita)
    keyTransport.transportParameters = GostR3410_TransportParameters(
            Gost28147_89_ParamSet(recipientTransportParameters.oid.value),  // параметры шифрования ключа
            publicKeyInfo,
            Asn1OctetString(iv.iv))
    keyTransport.encode(encoder)
    return encoder.msgCopy
}


Полученный пример расшифровывается успешно самим JCP и так же через КриптоАРМ. Но сервис все равно дает ту ошибку.
Можно конечно обратиться в ТП сервиса и попросить разъяснить ситуацию, но вот проблема, стандартный контейнер (подписать+зашифровать) собранный в КриптоАРМ успешно потребляется сервисом.
То есть у меня не получается воспроизвести через JCP тоже самое. Отсюда вопрос правильный ли я код использую для требований сервиса ? Как можно точно провалидировать полученное pcks7 сообщение?
Можно ли использовать пример enveloped + sign из cades пакета примеров ?
Offline Санчир Момолдаев  
#2 Оставлено : 26 февраля 2021 г. 12:56:28(UTC)
Санчир Момолдаев

Статус: Сотрудник

Группы: Модератор, Участники
Зарегистрирован: 03.12.2018(UTC)
Сообщений: 1,038
Российская Федерация

Сказал(а) «Спасибо»: 88 раз
Поблагодарили: 223 раз в 211 постах
Добрый день!
попробуйте зашифровать использовав EnvelopedSignature
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Санчир Момолдаев за этот пост.
coldplay оставлено 26.02.2021(UTC)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.