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

Уведомление

Icon
Error

6 Страницы123>»
Опции
К последнему сообщению К первому непрочитанному
Offline Denis1499  
#1 Оставлено : 3 июля 2018 г. 13:59:39(UTC)
Denis1499

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

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

У нас есть приложение, написанное на оутсорсе. Которое шифрует отчеты и отправляет в НБКИ.
До 2018 готом шифровали предоставленным сертификатом от НБКИ, который был сделан
по ГОСТ 2001.

Нам предоставили новый сертификат для шифрования, который выпущен по ГОСТ 2012
и НБКИ теперь не может расшифровать наши отправляемые отчеты.

На руках есть исходный код шифрования файлов. Но непонятно что в нем необходимо исправить.

Использовали для подписи "1.2.643.2.2.19" (GOST_EL_KEY_OID), для генерации ключей "GOST3410DHELEPH",
сейчас пробовал "1.2.643.7.1.1.1.2" (GOST_PARAMS_SIG_2012_512_KEY_OID) и "GOST3410DHEPH_2012_512", а так же 256 битные алгоритмы.

И все равно шифруется неверно. Куда еще можно посмотреть?
Online Евгений Афанасьев  
#2 Оставлено : 3 июля 2018 г. 14:39:23(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Здравствуйте.
Вы можете сделать пример, воспроизводящий ошибку? Что используется для расшифрования на стороне НБКИ?

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

Offline Denis1499  
#3 Оставлено : 3 июля 2018 г. 15:21:28(UTC)
Denis1499

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

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

Добрый день,
я могу привести только код, как мы шифруем.

Имеет смысл?
Online Евгений Афанасьев  
#4 Оставлено : 3 июля 2018 г. 15:58:01(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Приведите, посмотрим. Если не сложно, создайте тестовый контейнер, зашифруйте в его адрес и приложите всё (пример, контейнер, сообщение), я попроверяю с помощью jcp и csp.
Offline Denis1499  
#5 Оставлено : 3 июля 2018 г. 16:32:22(UTC)
Denis1499

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

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

Шифруем мы следующим образом

Код:

public class EncryptService {

  public byte[] encrypt(X509Certificate recipientCert, Path fileToEncrypt) throws Exception {

    byte[] data = Files.readAllBytes(fileToEncrypt);
    final PublicKey recipientPublic = recipientCert.getPublicKey();

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

    final KeyGenerator kg = KeyGenerator.getInstance(CryptoUtil.GOST28147, CryptoProvider.PROVIDER_NAME);
    final ParamsInterface paramss = AlgIdSpec.getDefaultCryptParams();
    kg.init(paramss);
    final SecretKey simm = kg.generateKey();

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

    Cipher cipher = Cipher.getInstance(CryptoUtil.CIPHER_MODE, CryptoProvider.PROVIDER_NAME);
    cipher.init(Cipher.ENCRYPT_MODE, simm, (SecureRandom) null);

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

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

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

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

    final ContentInfo all = new ContentInfo();
    all.contentType = new Asn1ObjectIdentifier(new OID(CryptoUtil.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 keytrans = new KeyTransRecipientInfo();
    keytrans.version = new CMSVersion(0);

    final Asn1BerEncodeBuffer ebuf = new Asn1BerEncodeBuffer();
    
    final SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo();
    final Asn1BerDecodeBuffer dbuff = new Asn1BerDecodeBuffer(
    		recipientPublic.getEncoded());
    spki.decode(dbuff);
    dbuff.reset();

//    final AlgIdInterface algid = new AlgIdSpec(JCP.GOST_EL_KEY_OID);
    final AlgIdInterface algid = new AlgIdSpec(spki.algorithm);
    final AlgorithmIdentifier id = (AlgorithmIdentifier) algid.getDecoded();
    id.encode(ebuf);

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

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

    keytrans.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());

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

    keytrans.encryptedKey = new EncryptedKey(keyTransport);
    ebuf.reset();

    cms.recipientInfos.elements[0].set_ktri(keytrans);
    cms.encryptedContentInfo = new EncryptedContentInfo();

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

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

    params.encryptionParamSet = new Gost28147_89_ParamSet(paramss.getOID().value);
    cms.encryptedContentInfo.contentEncryptionAlgorithm = new ContentEncryptionAlgorithmIdentifier(
            _Gost28147_89_EncryptionSyntaxValues.id_Gost28147_89, params);

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

    return ebuf.getMsgCopy();
  }


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

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

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

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

    GostPublicKey repPublicKey = (GostPublicKey) recipientKey;
    ParamsInterface repPublicKeySpec = repPublicKey.getSpec().getParams();
    kgp.initialize(repPublicKeySpec);

    // Генерируем эфемерную пару.

    KeyPair ephPair = kgp.generateKeyPair();

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

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

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

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

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

    ka.doPhase(recipientKey, true);
    Key dh = ka.generateSecret(CryptoUtil.GOST28147);

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

    final Cipher cipher = Cipher.getInstance(CryptoUtil.GOST28147, CryptoProvider.PROVIDER_NAME);
    cipher.init(Cipher.WRAP_MODE, dh, (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(oid.value),
            publicKeyInfo,
            new Asn1OctetString(iv.getIV()));

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


Сигнатуру получаем следующим образом:

Код:

public class SignatureService {

    public byte[] signDetached(Path originalFilePath, PrivateKey privateKey, X509Certificate certificate) throws Exception {
        byte[] data = Files.readAllBytes(originalFilePath);
        Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_512_NAME);
        signature.initSign(privateKey);
        signature.update(data);
        return createCMSEx(data, signature.sign(), certificate, true);
    }

    public byte[] sign(Path originalFilePath, PrivateKey privateKey, X509Certificate certificate) throws Exception {
        byte[] data = Files.readAllBytes(originalFilePath);
        Signature signature = Signature.getInstance(JCP.GOST_SIGN_2012_512_NAME);
        signature.initSign(privateKey);
        signature.update(data);
        return createCMSEx(data, signature.sign(), certificate, false);
    }

    public byte[] readAndVerify(byte[] bytes, X509Certificate cert) {
        return propagateCatchableException(() -> {
            CMSSignedData data = new CMSSignedData(bytes);
            SignerInformation signer = data.getSignerInfos().getSigners().iterator().next();
            JcaSimpleSignerInfoVerifierBuilder builder = new JcaSimpleSignerInfoVerifierBuilder();
            SignerInformationVerifier verifier = builder.build(cert);
            if (!signer.verify(verifier)) {
                throw new Exception("Data is compromised, wrong signDetached");
            }
            return (byte[]) data.getSignedContent().getContent();
        });
    }

    public byte[] readNotVerify(byte[] bytes) {
        return propagateCatchableException(() -> {
            CMSSignedData data = new CMSSignedData(bytes);
            return (byte[]) data.getSignedContent().getContent();
        });
    }

    private byte[] createCMSEx(byte[] data, byte[] sign, Certificate cert, boolean detached) throws Exception {

        final ContentInfo all = new ContentInfo();
        all.contentType = new Asn1ObjectIdentifier(new OID(CryptoUtil.STR_CMS_OID_SIGNED).value);

        final SignedData cms = new SignedData();
        all.content = cms;
        cms.version = new CMSVersion(1);

        // digest
        cms.digestAlgorithms = new DigestAlgorithmIdentifiers(1);
        final DigestAlgorithmIdentifier a = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);

        a.parameters = new Asn1Null();
        cms.digestAlgorithms.elements[0] = a;

        if (detached) {
            cms.encapContentInfo = new EncapsulatedContentInfo(
                    new Asn1ObjectIdentifier(
                            new OID(CryptoUtil.STR_CMS_OID_DATA).value), null);
        } else {
            cms.encapContentInfo =
                    new EncapsulatedContentInfo(new Asn1ObjectIdentifier(
                            new OID(CryptoUtil.STR_CMS_OID_DATA).value),
                            new Asn1OctetString(data));
        }

        // certificate
        cms.certificates = new CertificateSet(1);
        final ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate certificate = new ru.CryptoPro.JCP.ASN.PKIX1Explicit88.Certificate();
        final Asn1BerDecodeBuffer decodeBuffer = new Asn1BerDecodeBuffer(cert.getEncoded());
        certificate.decode(decodeBuffer);

        cms.certificates.elements = new CertificateChoices[1];
        cms.certificates.elements[0] = new CertificateChoices();
        cms.certificates.elements[0].set_certificate(certificate);

        // signer info
        cms.signerInfos = new SignerInfos(1);
        cms.signerInfos.elements[0] = new SignerInfo();
        cms.signerInfos.elements[0].version = new CMSVersion(1);
        cms.signerInfos.elements[0].sid = new SignerIdentifier();

        final byte[] encodedName = ((X509Certificate) cert).getIssuerX500Principal().getEncoded();
        final Asn1BerDecodeBuffer nameBuf = new Asn1BerDecodeBuffer(encodedName);
        final Name name = new Name();
        name.decode(nameBuf);

        final CertificateSerialNumber num = new CertificateSerialNumber(((X509Certificate) cert).getSerialNumber());
        cms.signerInfos.elements[0].sid.set_issuerAndSerialNumber(new IssuerAndSerialNumber(name, num));
        cms.signerInfos.elements[0].digestAlgorithm = new DigestAlgorithmIdentifier(new OID(JCP.GOST_DIGEST_2012_512_OID).value);
        cms.signerInfos.elements[0].digestAlgorithm.parameters = new Asn1Null();
        cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(JCP.GOST_PARAMS_SIG_2012_512_KEY_OID).value);
        cms.signerInfos.elements[0].signatureAlgorithm.parameters = new Asn1Null();
        cms.signerInfos.elements[0].signature = new SignatureValue(sign);

        // encode
        final Asn1BerEncodeBuffer asnBuf = new Asn1BerEncodeBuffer();
        all.encode(asnBuf, true);
        return asnBuf.getMsgCopy();
    }
}


Это уже адаптированный код мною по ГОСТ 2012, 512 бит.

В атаче исходный файл (данные фейковые) и зашифрованный, что отправляю.

B701FF000000_20100901_164556.zip.enc (3kb) загружен 3 раз(а).

Сертификат НБКИ, наверное, я не имею права выкладывать.
Offline Denis1499  
#6 Оставлено : 3 июля 2018 г. 16:43:27(UTC)
Denis1499

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

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

А сам файл сообщения не прикладывается, zip возможно приложить к сообщению?
Online Евгений Афанасьев  
#7 Оставлено : 3 июля 2018 г. 17:27:33(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Архив можно прикрепить к сообщению (включить в него зашифр. сообщение, тестовый контейнер, в адрес которого шифровали).
Offline Denis1499  
#8 Оставлено : 3 июля 2018 г. 18:17:13(UTC)
Denis1499

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

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

А что такое тестовый контейнер?
Online Евгений Афанасьев  
#9 Оставлено : 4 июля 2018 г. 11:16:02(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Я имел в виду зашифровать в адрес тестового сертификата, вместо НБКИ, и передать в архиве контейнер, чтобы можно было проверить расшифрование.
Offline Denis1499  
#10 Оставлено : 4 июля 2018 г. 14:25:06(UTC)
Denis1499

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

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

Добрый день!

С получением тестового сертификата пока заминка.

А какой командой вы проверяете расшифрование, может я попробую?
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
6 Страницы123>»
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.