logo
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

3 Страницы<123
Опции
К последнему сообщению К первому непрочитанному
Offline Евгений Афанасьев  
#41 Оставлено : 27 июля 2018 г. 8:13:14(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Автор: Denis1499 Перейти к цитате
Проблема, что без инициализации gostKeyManagerFactory я не могу ходить во внешний сервис по https, тк мне нужен sslContext.

Если вначале поднимать кей менеджер, напр.

initGostKeyFactory();
initGostCertStore();

то сертификат я вижу, но не могу создать sslContext.

Если, все таки вначале инициализировать gostCertStore и вытянуть из него сертификаты и сохранить отдельно (напр. в Map),
то я могу шифровать, но подключиться к внешнему ресурсу не могу.
Получаю исключение:

Цитата:

javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: ru.CryptoPro.ssl.pc_4.cl_5: PKIX path validation failed: java.security.GeneralSecurityException: Online certificate verification enabled but com.sun.security.enableCRLDP = false (Sun), com.ibm.security.enableCRLDP = false (Ibm)

Да, KeyManager не проинициализируется без keyStore (с пустым).
На счет ошибки "Online certificate verification enabled" - необходимо либо задать -Dcom.sun.security.enableCRLDP=true, либо отключить проверку цепочки в панели JCP на вкладке "Настройки сервера" - "Проверять сертификаты цепочки на отзыв".

С текущей сборкой JCP, к сожалению, без изменений в коде (разделения на HDImageStore и CertStore) не обойтись, или придется сделать свой менеджер ключей (чтобы избежать keyStore.load()). Постараемся это исправить в следующей сборке (изменения делались в связи с добавлением счетчика ввода пароля).

Отредактировано пользователем 27 июля 2018 г. 8:15:26(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Denis1499  
#42 Оставлено : 27 июля 2018 г. 8:34:46(UTC)
Denis1499

Статус: Участник

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

Отбой пока, я снял галочку в jcp панели.
Удалось зашифровать в новой версии и отправить.

Позже отпишу, какой результат шифрования.
Offline Denis1499  
#43 Оставлено : 31 июля 2018 г. 13:54:59(UTC)
Denis1499

Статус: Участник

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

Добрый день!

Создал я у вас тестовый контейнер, взял в нем сертификат, зашифровал файл,
потом утилитой csptest удалось успешно расшифровать.

Не могли бы вы глянуть верно ли мы все сделали, напр. выпустили сертификат и ключ дл 2012 ГОСТа?

test_cont.zip (7kb) загружен 2 раз(а).

В файле зашифрованый файл *.enc, сернтификат и хранилище с private key.
Offline Евгений Афанасьев  
#44 Оставлено : 3 августа 2018 г. 8:52:03(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Добрый день.
1. С помощью EnvelopedSignature (из CAdES.jar) расшифровался архив успешно (последний 2.0) - 2 файла:
Код:

byte[] bin = Array.readFile("licuha.txt.zip.enc");
KeyStore keyStore = KeyStore.getInstance(JCP.HD_STORE_NAME, JCP.PROVIDER_NAME);

keyStore.load(null, null);
PrivateKey prk = (PrivateKey) keyStore.getKey("8c3c5e39-2a09-4602-b405-2e58eb18a604", null);

509Certificate cert = (X509Certificate) keyStore.getCertificate("8c3c5e39-2a09-4602-b405-2e58eb18a604");

EnvelopedSignature envelopedSignature = new EnvelopedSignature(new ByteArrayInputStream(bin));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

envelopedSignature.decrypt(cert, prk, outputStream);
utputStream.close();

byte[] decrypted = outputStream.toByteArray();
Array.writeFile("licuha.txt.zip", decrypted);

Код:

licuha.txt.zip ->  licuha.txt licuha.txt.sig

Поверю еще иначе.

2. Методом DecryptPKCS7 в PKCS7EnvEphTransport (samples-sources.jar, пакет CMS_samples) тоже расшифровалось сообщение - получил архив.

3. Установил сертификат Denis с привязкой к ключу в My, выполнил команду:
Код:

>"C:\Program Files\Crypto Pro\CSP\csptest" -lowenc -decrypt -in licuha.txt.zip.enc -out out.zip -my Denis

Получил архив.

По поводу load() в cpSSL, "очищающего" список сертификатов в HDImageStore в связи с тем, что тот используется и как хранилище сертификатов, и хранилище контейнеров и передается в spSSL, после чего продолжает использоваться (выполняются операции с сертификатами): в cpSSL сделали load только для контейнеров, даже если HDImageStore используется, в том числе, для сертификатов. Изменение будет в следующем релизе.

Отредактировано пользователем 3 августа 2018 г. 9:21:38(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Denis1499  
#45 Оставлено : 3 августа 2018 г. 12:34:05(UTC)
Denis1499

Статус: Участник

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

Спасибо!!

Для реализации мы использовали пример из CMSSignAndEncrypt

попробую переписать все на PKCS7EnvEphTransport
Offline Евгений Афанасьев  
#46 Оставлено : 3 августа 2018 г. 14:38:01(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Напишите, с какой версией jcp проверить, проверю с другой аналогично.
Техническую поддержку оказываем тут
Наша база знаний
Offline Denis1499  
#47 Оставлено : 3 августа 2018 г. 15:12:32(UTC)
Denis1499

Статус: Участник

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

Тестовый контейнер я создавал в 2.039
Offline BaalPr  
#48 Оставлено : 9 октября 2018 г. 11:09:21(UTC)
BaalPr

Статус: Новичок

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

Добрый день
Возникла такая же проблема, как и у создателя данной темы.
Отправляем зашифрованное сообщение в НБКИ, в ответ приходит, что не могут расшифровать.
Поскольку проблематично все время отправлять на боевой сервер данные сообщения, решили проверить криптоАРМ, но файлы, которые мы шифруем алгоритмом из примеров, криптоАРМ не может расшифровать так же.
Для шифрования и дешифрования нашим кодом использовали пример jcp 2.0.39014 из samples-sources\CMS_samples\PKCS7EnvEphTransport.java практически полный копи-паст.
При расшифровании нашим кодом все отрабатывает корректно. И наш зашифрованный файл и файл зашифрованный АРМом расшифровываются правильно.
Долго рылся в примерах, пришел к выводу, что в методе wrap нужно вместо этого
// Генерация эфемерной пары.
KeyPairGenerator kgp = KeyPairGenerator.getInstance(
JCP.GOST_EL_DH_EPH_NAME,
CRYPT_PROVIDER_NAME
);
передавать алгоритм соответствующий ключу recipientKey
т.е. вот так
final String keyAlgName = recipientKey.getAlgorithm();
String keyPairAlgName;
if (keyAlgName.equalsIgnoreCase(KEY_ALG_NAME_2012_256) ||
keyAlgName.equalsIgnoreCase(KEY_EL_ALG_NAME_2012_256)) {
keyPairAlgName = JCP.GOST_EPH_DH_2012_256_NAME;
} else if (keyAlgName.equalsIgnoreCase(KEY_ALG_NAME_2012_512) ||
keyAlgName.equalsIgnoreCase(KEY_EL_ALG_NAME_2012_512)) {
keyPairAlgName = JCP.GOST_EPH_DH_2012_512_NAME;
} else {
keyPairAlgName = JCP.GOST_EL_DH_EPH_NAME;
}

// Генерация эфемерной пары.
KeyPairGenerator kgp = KeyPairGenerator.getInstance(keyPairAlgName);

Правильно ли это?

Тем не менее, это не помогло, расшифровка криптоАРМом так же дает ошибку.

Error.jpg (67kb) загружен 3 раз(а).

Шифровали криптоАРМом так:
Encode1.jpg (69kb) загружен 1 раз(а). Encode2.jpg (53kb) загружен 1 раз(а).


Мне нужно понять, в чем разница между шифрованием, представленным в примере, и АРМом? Т.к. очевидно, что разница есть.
Версия используемого jcp 2.0.39014
Как корректно зашифровать на сертифкате ГОСТ 2012? На 2001-м госте работает, на 2012-ом нет.


Offline Евгений Афанасьев  
#49 Оставлено : 9 октября 2018 г. 11:36:27(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Здравствуйте.
Попробуйте использовать последнюю сборку jcp, скорее всего, проблема была в передаче параметров шифрования и она исправлена (для сообщений размером > 1Кб).
Техническую поддержку оказываем тут
Наша база знаний
Offline BaalPr  
#50 Оставлено : 10 октября 2018 г. 9:19:57(UTC)
BaalPr

Статус: Новичок

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

Добрый день
Обновил версию jcp до 2.0.39893.
Взял пример из samples-sources\CMS_samples\PKCS7EnvEphTransport.java
Там немного изменился код, по сравнению с сертифицированной версией.
Но это так же не помогло АРМу расшифровать сообщение.
Можете попробовать у себя, используя данный код, зашифровать сообщение, а расшифровать его АРМом?
Offline Евгений Афанасьев  
#51 Оставлено : 10 октября 2018 г. 9:31:22(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Здравствуйте.
Параметры шифрования - CryptParamsSpec.OID_Gost28147_89_Rosstandart_TC26_Z_ParamSet?
Приведите, пожалуйста, свой пример для анализа и, если не трудно, создайте с помощью тестового ключевого контейнера (выпустить его можно тут - http://cryptopro.ru/certsrv/) сообщение и прикрепите архив с ним и ключевым контейнером для расшифровки, для воспроизведения проблемы.
Схожие проблемы:
https://www.cryptopro.ru...aspx?g=posts&t=13422
https://www.cryptopro.ru...aspx?g=posts&t=13409

Отредактировано пользователем 10 октября 2018 г. 9:32:40(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline BaalPr  
#52 Оставлено : 12 октября 2018 г. 12:13:00(UTC)
BaalPr

Статус: Новичок

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

Добрый день
Действительно помогло.
В примерах samples-sources\CMS_samples\PKCS7EnvEphTransport.java есть метод wrap
там строки:

IvParameterSpec iv = new IvParameterSpec(syncro);
OID oid = CryptParamsSpec.OID_Crypt_VerbaO;

// Выработка ключа согласования.

Мы заменили этот параметр на OID oid = CryptParamsSpec.OID_Gost28147_89_Rosstandart_TC26_Z_ParamSet;

И все заработало.
Спасибо!
Offline Denis1499  
#53 Оставлено : 29 октября 2018 г. 12:42:15(UTC)
Denis1499

Статус: Участник

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

Автор: BaalPr Перейти к цитате
Добрый день
Действительно помогло.
В примерах samples-sources\CMS_samples\PKCS7EnvEphTransport.java есть метод wrap
там строки:

IvParameterSpec iv = new IvParameterSpec(syncro);
OID oid = CryptParamsSpec.OID_Crypt_VerbaO;

// Выработка ключа согласования.

Мы заменили этот параметр на OID oid = CryptParamsSpec.OID_Gost28147_89_Rosstandart_TC26_Z_ParamSet;

И все заработало.
Спасибо!


Спасибо за совет!
Решил попробовать еще раз.

Установка данного параметра помогла только для сертификата 2001 г., для 2012 так и не заработало.

Поменял

Цитата:

// Генерация эфемерной пары.
final String keyAlgName = recipientKey.getAlgorithm();
System.out.println(keyAlgName);

KeyPairGenerator kgp = KeyPairGenerator.getInstance(
JCP.GOST_EPH_DH_2012_256_NAME,
CryptoProvider.PROVIDER_NAME
);


тк вижу что keyAlgName == GOST3410_2012_256

Пока не заработало, буду смотреть и далее,
версия jcp 2.0.39893
Offline Евгений Афанасьев  
#54 Оставлено : 9 ноября 2018 г. 6:41:05(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Здравствуйте.
Согласно используемому примеру, попробуйте так (настройки из этого примера остаются практически прежними, некоторые методы изменились):
Код:

public class PKCS7EnvEphTransport {

    /**
     * Подписываемые/шифруемые данные.
     */
    private static final byte[] DATA = ...

    /**
     * Контейнер получателя.
     */
    private final static ISignatureContainer RECIPIENT = new EnvContainer2012_256(); // из samples

    /**
     * Извлечение параметров сертификата. Параметры шифрования
     * обычно null, поэтому будут получены параметры шифрования
     * по умолчанию.
     * У AlgIdSpec есть несколько конструкторов (с использованием
     * OID и др.).
     *
     * @param cert Сертификат.
     * @return параметры сертификата.
     * @throws Exception
     */
    private static AlgIdSpec getAlgIdSpec(X509Certificate cert)
        throws Exception {

        byte[] encoded = cert.getPublicKey().getEncoded();
        Asn1BerDecodeBuffer buf = new Asn1BerDecodeBuffer(encoded);
        SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo();

        try {
            keyInfo.decode(buf);
        } catch (Asn1Exception e) {
            IOException ex = new IOException("Not GOST DH public key");
            ex.initCause(e);
            throw ex;
        }

        buf.reset();
        return new AlgIdSpec(keyInfo.algorithm);

    }

    /**
     * Зашифрование сообщения (enveloped).
     *
     * @param recipientCert - сертификат получателя.
     * @param data - исходное сообщение (PKCS7).
     * @return зашифрованное сообщение (enveloped).
     * @throws Exception
    */
    public static byte[] EncryptPKCS7(X509Certificate recipientCert,
        byte[] data) throws Exception {

	final PublicKey recipientPublic = recipientCert.getPublicKey();

	// Генерирование симметричного ключа с параметрами
	// шифрования из контрольной панели.

	final KeyGenerator kg = KeyGenerator.getInstance(
            CMStools.SEC_KEY_ALG_NAME, CRYPT_PROVIDER_NAME);

        // Параметры шифрования симметричного ключа (по умолчанию)
        // и параметры шифрования данных (по умолчанию).

        final AlgIdSpec algIdSpec = getAlgIdSpec(recipientCert);

        final ParamsInterface recipientTransportParameters = algIdSpec.getCryptParams(); // из открытого ключа
	final ParamsInterface contentEncryptionParameters  = algIdSpec.getCryptParams(); // могут быть другие

        // Инициализация генератора.

        kg.init(contentEncryptionParameters);

        // Симметричный ключ.

	final SecretKey symmetricKey = kg.generateKey();
	    
	// Зашифрование текста на симметричном ключе.

	Cipher cipher = Cipher.getInstance(CIPHER_MODE, CRYPT_PROVIDER_NAME);
	cipher.init(Cipher.ENCRYPT_MODE, symmetricKey, (SecureRandom) null);

	final byte[] iv = cipher.getIV();
	final byte[] text = cipher.doFinal(data, 0, data.length);

	// Зашифрование симметричного ключа.

	final byte[] keyTransport = wrap(symmetricKey, recipientPublic,
            recipientTransportParameters);

	// Формирование CMS-сообщения.

	final ContentInfo all = new ContentInfo();
	all.contentType = new Asn1ObjectIdentifier(new OID(CMStools.STR_CMS_OID_ENVELOPED).value);

	final EnvelopedData cms = new EnvelopedData();

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

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

	final KeyTransRecipientInfo key_trans = new KeyTransRecipientInfo();
        key_trans.version = new CMSVersion(0);

	final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();

	final AlgorithmIdentifier id = (AlgorithmIdentifier) algIdSpec.getDecoded();
	id.encode(ebuf);

	Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(ebuf.getMsgCopy());
        key_trans.keyEncryptionAlgorithm = new KeyEncryptionAlgorithmIdentifier();
        key_trans.keyEncryptionAlgorithm.decode(dbuf);

	ebuf.reset();
	dbuf.reset();

        key_trans.rid = new RecipientIdentifier();
	final IssuerAndSerialNumber issuer = new IssuerAndSerialNumber();

	final X500Principal issuerName = recipientCert.getIssuerX500Principal();
	dbuf = new Asn1BerDecodeBuffer(issuerName.getEncoded());
	    
	issuer.issuer = new Name();
	final RDNSequence rnd = new RDNSequence();
	rnd.decode(dbuf);
	    
	issuer.issuer.set_rdnSequence(rnd);
	issuer.serialNumber = new CertificateSerialNumber(recipientCert.getSerialNumber());

        key_trans.rid.set_issuerAndSerialNumber(issuer);
	dbuf.reset();

        key_trans.encryptedKey = new EncryptedKey(keyTransport);
	ebuf.reset();
	    
	cms.recipientInfos.elements[0].set_ktri(key_trans);
	cms.encryptedContentInfo = new EncryptedContentInfo();

	final OID contentType = new OID(CMStools.STR_CMS_OID_DATA);
	cms.encryptedContentInfo.contentType = new ContentType(contentType.value);

	final Gost28147_89_Parameters parameters = new Gost28147_89_Parameters();
        parameters.iv = new Gost28147_89_IV(iv);

        parameters.encryptionParamSet = new Gost28147_89_ParamSet(contentEncryptionParameters.getOID().value); // параметры шифрования данных
	cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
	    _Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, parameters);

	cms.encryptedContentInfo.encryptedContent = new EncryptedContent(text);
	all.encode(ebuf);

	return ebuf.getMsgCopy();

    }
		
    /**
     * Расшифрование PKCS7 (Enveloped).
     *
     * @param recipientAlias - алиас получателя.
     * @param recipientPassword - пароль получателя.
     * @param enveloped - зашифрованное сообщение (Enveloped).
     * @param data - исходные данные (нужны при проверке detached CMS подписи).
     * @param detached - флаг detached подписи.
     * @return результат проверки.
     * @throws Exception
    */
    public static boolean DecryptPKCS7(String recipientAlias, char[]
        recipientPassword, byte[] enveloped, byte[] data, boolean
        detached) throws Exception {

	// Разбор CMS-сообщения.

	Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(enveloped);
	final ContentInfo all = new ContentInfo();

	all.decode(dbuf);
	dbuf.reset();
		
	final EnvelopedData cms = (EnvelopedData) all.content;
	KeyTransRecipientInfo key_trans;

        // Только key_trans.

	if (cms.recipientInfos.elements[0].getChoiceID() == RecipientInfo._KTRI) {
            key_trans = (KeyTransRecipientInfo) (cms.recipientInfos.elements[0].getElement());
	}
	else {
	    throw new Exception("Unknown recipient info");
	}

	final byte[] wrapKey = key_trans.encryptedKey.value;
	final Gost28147_89_Parameters params = (Gost28147_89_Parameters)
            cms.encryptedContentInfo.contentEncryptionAlgorithm.parameters;

	final byte[] iv = params.iv.value;
	final OID cipherOID = new OID(params.encryptionParamSet.value); // параметры шифрования данных
	final byte[] text = cms.encryptedContentInfo.encryptedContent.value;

	// Получатель - закрытый ключ.

        final JCPProtectionParameter protectionParameter =
            new JCPProtectionParameter(recipientPassword);

        final JCPPrivateKeyEntry recipientEntry = (JCPPrivateKeyEntry) keyStore
            .getEntry(recipientAlias, protectionParameter);

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

	final SecretKey symmetricKey = unwrap(wrapKey,
            recipientEntry.getPrivateKey());

	// Расшифрование текста на симметричном ключе.

	final GostCipherSpec spec = new GostCipherSpec(iv, cipherOID);
	Cipher cipher = Cipher.getInstance(CIPHER_MODE, CRYPT_PROVIDER_NAME);

	cipher.init(Cipher.DECRYPT_MODE, symmetricKey, spec, null);
	final byte[] result = cipher.doFinal(text, 0, text.length);

	Array.writeFile(TEST_DIR + "cms_cms.bin", result);
	// checkPKCS7(result, detached, data, TEST_DIR + "cms_cms_data.txt");

	return true;

    }

    /**
     * Зашифрование сессионного ключа.
     *
     * @param secretKey Сессионный ключ.
     * @param recipientKey Открытый ключ получателя.
     * @return транспортная структура GostR3410_KeyTransport.
     * @throws Exception
    */
    private static byte[] wrap(SecretKey secretKey, PublicKey
        recipientKey, ParamsInterface recipientTransportParameters)
        throws Exception {

        // Определение алгоритма эфемерного ключа.

        String keyAlgorithm = recipientKey.getAlgorithm();
        String ephKeyAlgorithm = JCP.GOST_EL_DH_EPH_NAME;

        if (keyAlgorithm.equalsIgnoreCase(JCP.GOST_EL_2012_256_NAME)) {
            ephKeyAlgorithm = JCP.GOST_EPH_DH_2012_256_NAME;
        } // if
        else if (keyAlgorithm.equalsIgnoreCase(JCP.GOST_EL_2012_512_NAME)) {
            ephKeyAlgorithm = JCP.GOST_EPH_DH_2012_512_NAME;
        } // else

	// Генерация эфемерной пары.

	KeyPairGenerator kgp = KeyPairGenerator.getInstance(
            ephKeyAlgorithm, CRYPT_PROVIDER_NAME);

	// Устанавливаем нужные параметры, как у
	// получателя.

        AlgorithmParameterSpec spec = new X509PublicKeySpec(recipientKey.getEncoded());
        kgp.initialize(spec);

	// Генерируем эфемерную пару. Ключи получат
	// параметры recipientKey, а у него параметры
	// - recipientTransportParameters.

	KeyPair ephPair = kgp.generateKeyPair();

	PrivateKey privateKey = ephPair.getPrivate();
	PublicKey publicKey = ephPair.getPublic();

	byte[] syncro = new byte[8];
	SecureRandom random = SecureRandom.getInstance(JCP.CP_RANDOM, PROVIDER_NAME);
	random.nextBytes(syncro);

	IvParameterSpec iv = new IvParameterSpec(syncro);

	// Выработка ключа согласования.

	KeyAgreement ka = KeyAgreement.getInstance(privateKey.getAlgorithm(), CRYPT_PROVIDER_NAME);
	ka.init(privateKey, iv);

	ka.doPhase(recipientKey, true);
	Key dh = ka.generateSecret(CIPHER); // dh получит параметры из privateKey, т.е. recipientTransportParameters

	// Зашифрование симметричного ключа на ключе согласования
	// отправителя. Передаются параметры шифрования ключа, если
        // отличаются от тех, что у dh.

	final Cipher cipher = Cipher.getInstance(CIPHER, CRYPT_PROVIDER_NAME);
	cipher.init(Cipher.WRAP_MODE, dh, recipientTransportParameters, (SecureRandom) null);

	final byte[] wrappedKey = cipher.wrap(secretKey);

	// Упаковка параметров и ключа.

	Gost28147_89_EncryptedKey encryptedKey = new Gost28147_89_EncryptedKey();
	Asn1BerDecodeBuffer decoder = new Asn1BerDecodeBuffer(wrappedKey);
	encryptedKey.decode(decoder);

	byte[] imita = encryptedKey.macKey.value;
	byte[] wrapperKeyBytes = encryptedKey.encryptedKey.value;

	// Кодирование открытого ключа в SubjectPublicKeyInfo.

	byte[] publicKeyBytes = publicKey.getEncoded();
	SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo();

	decoder = new Asn1BerDecodeBuffer(publicKeyBytes);
	publicKeyInfo.decode(decoder);

	// Кодирование GostR3410_KeyTransport.

	GostR3410_KeyTransport keyTransport = new GostR3410_KeyTransport();
	Asn1BerEncodeBuffer encoder = new Asn1BerEncodeBuffer();

	keyTransport.sessionEncryptedKey = new Gost28147_89_EncryptedKey(wrapperKeyBytes, imita);
	keyTransport.transportParameters = new GostR3410_TransportParameters(
	    new Gost28147_89_ParamSet(recipientTransportParameters.getOID().value), // параметры шифрования ключа
		publicKeyInfo,
		new Asn1OctetString(iv.getIV()));

	keyTransport.encode(encoder);
	return encoder.getMsgCopy();

    }

    /**
     * Зашифрование сессионного ключа.
     *
     * @param wrappedKey Зашифрованный сессионный ключ (транспортная
     * структура GostR3410_KeyTransport).
     * @param recipientKey Закрытый ключ получателя.
     * @return сессионный ключ.
     * @throws Exception
     */
    private static SecretKey unwrap(byte[] wrappedKey, Key
        recipientKey) throws Exception {

	// Декодирование GostR3410_KeyTransport.

	GostR3410_KeyTransport keyTransport = new GostR3410_KeyTransport();
	Asn1BerDecodeBuffer decoder = new Asn1BerDecodeBuffer(wrappedKey);
	keyTransport.decode(decoder);

	// EncryptedKey в правильном формате для шифратора.

	byte[] wrappedKeyBytes = keyTransport.sessionEncryptedKey.encryptedKey.value;
	byte[] imita = keyTransport.sessionEncryptedKey.macKey.value;

	Asn1BerEncodeBuffer encoder = new Asn1BerEncodeBuffer();
	Gost28147_89_EncryptedKey encryptedKey = new Gost28147_89_EncryptedKey(
	    new Gost28147_89_Key(wrappedKeyBytes), null, new Gost28147_89_MAC(imita));

	encryptedKey.encode(encoder);
	byte[] wrapped = encoder.getMsgCopy();

	// Декодирование открытого ключа.

	encoder.reset();
	keyTransport.transportParameters.ephemeralPublicKey.encode(encoder);

	byte[] encodedPublic = encoder.getMsgCopy();
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedPublic);

        KeyFactory kf = KeyFactory.getInstance(recipientKey.getAlgorithm(), PROVIDER_NAME);
	PublicKey publicKey = kf.generatePublic(keySpec);

	// Параметры шифрования.

	IvParameterSpec iv = new IvParameterSpec(keyTransport.transportParameters.ukm.value);
	OID transportParametersOid = new OID(keyTransport.transportParameters.encryptionParamSet.value); // параметры шифрования ключа

	CryptParamsSpec uz = CryptParamsSpec.getInstance(transportParametersOid);
	GostCipherSpec params = new GostCipherSpec(iv, uz);

	// Выработка ключа согласования.

	KeyAgreement ka = KeyAgreement.getInstance(recipientKey.getAlgorithm(), CRYPT_PROVIDER_NAME);
	ka.init(recipientKey, iv);

	ka.doPhase(publicKey, true);
	Key dh = ka.generateSecret(CIPHER); // dh получит параметры из recipientKey, т.е., по идее, transportParametersOid

	// Расшифрование сессионного ключа.

	Cipher cipher = Cipher.getInstance(CIPHER, CRYPT_PROVIDER_NAME);
	cipher.init(Cipher.UNWRAP_MODE, dh, params);

	return (SecretKey) cipher.unwrap(wrapped, null, Cipher.SECRET_KEY);

    }

...

    public static void main(String[] args) throws Exception {
        byte[] enveloped =  EncryptPKCS7(RECIPIENT.getAlias(), DATA);
        DecryptPKCS7(RECIPIENT.getAlias(), RECIPIENT.getPassword(), enveloped, null, false);
        // "C:\Program Files\Crypto Pro\CSP\csptest" -lowenc -decrypt -in "jcp_enveloped_cms.bin" -out "decrypted.txt" -my <installed_recipient_RECIPIENT>
    }



Вообще, часть wrap/unwrap можно заменить с помощью алгоритма Cipher - "GostTransport": он также генерирует эфемерный ключ, экспортирует/импортирует его и т.д.

Отредактировано пользователем 9 ноября 2018 г. 6:43:59(UTC)  | Причина: Не указана

Техническую поддержку оказываем тут
Наша база знаний
Offline Denis1499  
#55 Оставлено : 15 ноября 2018 г. 13:10:31(UTC)
Denis1499

Статус: Участник

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

Добрый день!

В конечном счете я понял, что наша проблема в создании файла подписи.

Помогло, что вывели oids алгоритмов, которые использовались в ключе:

Код:

System.out.println(((GostExchPrivateKey) senderPrivateKey).getSpec().getParams());


Потом подобрали параметры, для создания конверта.
Нам помогли следующие константы (CMStools, CMSSign взяты из примеров JCP):

Код:

CMSSign.createCMSEx(data, keys, certs, null, true, 
        		CMStools.DIGEST_OID_2012_256, CMStools.SIGN_OID_2012_256,
			JCP.GOST_DHEL_SIGN_NAME, JCP.PROVIDER_NAME);


вместо

Код:

CMSSign.createCMSEx(data, keys, certs, null, true, 
        		CMStools.DIGEST_OID, CMStools.SIGN_OID,
        		JCP.GOST_DHEL_SIGN_NAME, JCP.PROVIDER_NAME);


Возможно кому-то константы 512 требуется указать.

Всем спасибо за помощь, что не бросали нас, все работает. Тему можно закрывать.
Offline Евгений Афанасьев  
#56 Оставлено : 15 ноября 2018 г. 13:13:59(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Тогда, по идее, и JCP.GOST_DHEL_SIGN_NAME надо заменить на JCP.GOST_SIGN_2012_256_NAME.
Техническую поддержку оказываем тут
Наша база знаний
Offline Евгений Афанасьев  
#57 Оставлено : 15 ноября 2018 г. 16:24:31(UTC)
Евгений Афанасьев

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

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 2,360
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 12 раз
Поблагодарили: 322 раз в 319 постах
Хотя да, в новой версии алгоритм не важен.
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
3 Страницы<123
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.