Jump to content
evgenyshevnin

Расшифрование данных. ГОСТ 28147-89.

Recommended Posts

Добрый день!

Пытаюсь расшифровать файл, который был зашифрован с помощью Vipnet CryptoFile по алгоритму "ГОСТ 28147-89", и имеющий контейнер закрытого ключа с алгоритмом "ГОСТ Р 34.10-2001 DH". Интересно что делаю не так? Может необходимо вызывать другие алгоритмы расшифрования или с другими параметрами?

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

"java.security.InvalidKeyException: Unsupported key!ru.infotecs.crypto.gost3410.GostR341001PrivateKey
    at ru.infotecs.crypto.gost28147.h.engineGetKeySize(Unknown Source)
    at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1052)
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1023)
    at javax.crypto.Cipher.init(Cipher.java:1345)
    at javax.crypto.Cipher.init(Cipher.java:1282)
    at ru.it.npf.vipnet.utils.CipherUtil.decryptWithGOST28147_89_CFB(CipherUtil.java:117)
    at com.it.crypto.Test2.main(Test2.java:34)"

 

Метод которым извлекаю закрытый ключ:

public static GostR341001PrivateKey getSecretKeyFromKeyStore34(String folder, String keyAlias, String password) {
        KeyStore keyStore = KeyStoreUtil.getKeyStore();
        KeyStoreUtil.loadKeyStore(keyStore, folder);
        
        Key key;
        try {
            key = keyStore.getKey(keyAlias, password.toCharArray());
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        
        return (GostR341001PrivateKey)key;
        
    }

Метод

которым делаю расшифровку:

public static byte[] decryptWithGOST28147_89_CFB(
            Gost28147ParamSet inputParamSet, Key inputSecretKey,
            byte[] inputIV, byte[] inputData) throws Exception {
        // подготовка ключа расшифрования
        Key secretKey = inputSecretKey;

        // получение шифра ГОСТ 28147-89, работающего в режиме CFB без
        // дополнения
        Cipher cipherDriver = Cipher.getInstance("GOST28147-89/CFB/NoPadding", // строка
                                                                                // трансформации
                                                                                // шифра
                "ViPNet" // название провайдера
        );

        // подготовка параметров расшифрования
        // подготовка набора параметров работы алгоритма ГОСТ 28147-89
        Gost28147ParamSet paramSet = inputParamSet;
        // подготовка вектора инициализации (8 байт)
        byte[] iv = inputIV;
        // создание параметров расшифрования
        AlgorithmParameterSpec params = new Gost28147CipherParameterSpec(
                paramSet, iv);

        // инициализация шифра в режиме расшифрования данных
        cipherDriver.init(Cipher.DECRYPT_MODE, secretKey, params);

        // расшифрование данных
        byte[] nextEncodedChunk = inputData;
        byte[] nextPlainChunk = cipherDriver.update(nextEncodedChunk);

        // завершение операции расшифрования
        byte[] lastPlainChunk = cipherDriver.doFinal();

        byte[] outputData = new byte[nextPlainChunk.length
                + lastPlainChunk.length];
        System.arraycopy(nextPlainChunk, 0, outputData, 0,
                nextPlainChunk.length);
        System.arraycopy(lastPlainChunk, 0, outputData, nextPlainChunk.length,
                lastPlainChunk.length);
        return outputData;
    }

Вызов метода для расшифровки

byte[] decryptFile = CipherUtil.decryptWithGOST28147_89_CFB(Gost28147ParamSet.CryptoPro_A, secretKey,
                    inputIV, fileData);

 

Share this post


Link to post
Share on other sites

Евгений, добрый день.

Ошибка:

"java.security.InvalidKeyException: Unsupported key!ru.infotecs.crypto.gost3410.GostR341001PrivateKey

возникает из-за того, что в методе

public static byte[] decryptWithGOST28147_89_CFB(
            Gost28147ParamSet inputParamSet, Key inputSecretKey,
            byte[] inputIV, byte[] inputData)

параметр "Key inputSecretKey" у вас оказался закрытым асимметричным ключом, т. е. объектом типа GostR341001PrivateKey, в то время как JCrypto SDK ожидает объект типа "Gost28147SecretKey". 
Алгоритм ГОСТ 28147-89 работает только с симметричными ключами длиной 256 бит. Закрытые ключи можно использовать только для создания электронной подписи, генерации парного открытого ключа и выработки симметричных ключей по алгоритму Диффи-Хеллмана.


Что нужно сделать, чтобы расшифровать файл, созданный в ViPNet CryptoFile?
1) ViPNet CryptoFile создает зашифрованные сообщения в формате PKCS#7. Чтобы расшифровать такой файл, вам понадобятся 2 модуля из состава JCrypto SDK:
- jcrypto-jca-2.6.0-R******.jar
- jcrypto-pkcs-2.6.0-R******.jar
Убедитесь, что ваш проект использует эти модули.
2) Метод "getSecretKeyFromKeyStore34" вашей программы оставляем - закрытый ключ вам действительно понадобится. Для корректности метод лучше назвать "getPrivateKeyFromKeyStore34".

3) Кроме метода "getPrivateKeyFromKeyStore34" вам также понадобится метод, возвращающий сертификат:

public static X509Certificate getCertificateFromKeyStore34(String folder, String keyAlias, String password) throws Exception {
    KeyStore keyStore = KeyStoreUtil.getKeyStore();
    KeyStoreUtil.loadKeyStore(keyStore, folder);
    return keyStore.getCertificate(keyAlias);
}

4) Метод "decryptWithGOST28147_89_CFB" нужно полностью переписать. Найдите в комплекте JCrypto SDK документ "ViPNet JCrypto SDK. Руководство программиста". В руководстве есть небольшой раздел "Расшифрование CMS-сообщений". В этом разделе есть пример кода, который расшифровывает сообщение в формате PKCS#7.
Обратите внимание, что в методе CMSEnvelopedDataStream.init(privateKey, certificate) вам необходимо передать не только закрытый ключ, но и сертификат, который у вас хранится в хранилище (смотрите код метода getCertificateFromKeyStore34).

Share this post


Link to post
Share on other sites

спасибо большое за объяснение, но при попытке инициализировать объект CMSEnvelopedDataInputStream выходит ошибка.

Как инициализирую:

 

           InputStream inputStream = new FileInputStream(new File(FILE_ENC));
            CMSEnvelopedDataInputStream encryptedStream = new CMSEnvelopedDataInputStream(inputStream);

Текст ошибки:

Exception in thread "main" java.lang.NoSuchMethodError: ru.infotecs.cms.input.CMSEnvelopedDataInputStream.<init>(Ljava/io/InputStream;)V
    at com.it.crypto.Test2.decrypte(Test2.java:60)
    at com.it.crypto.Test2.main(Test2.java:45)

полный код метода расшифровки:

private static void decrypte(X509Certificate certificat, PrivateKey privateKey) throws Exception {
        // регистрируем провайдер
        Security.addProvider(new ViPNetProvider());
        try (InputStream inputStream = new FileInputStream(new File(FILE_ENC));
                CMSEnvelopedDataInputStream encryptedStream = new CMSEnvelopedDataInputStream(inputStream);
                OutputStream outputStream = new FileOutputStream(new File(FILE_ENC.replace(".enc", "")));) {

            // инициализируем закрытый ключ
            encryptedStream.init(privateKey, certificat);
            // считываем расшифрованное сообщение
            byte[] buffer = new byte[1024];
            int len;
            while ((len = encryptedStream.read(buffer)) >= 0) {
                outputStream.write(buffer, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception(e);
        }
    }

 

Share this post


Link to post
Share on other sites

Приветствую!

Вышел новый релиз ViPNet CryptoFile.

Скоро появится на нашем сайте.

Предлагаю дождаться его, попробовать Вам обновиться и воспроизвести ситуацию. Возможно, всё заработает.

 

Share this post


Link to post
Share on other sites
5 часов назад, Petrenko Sergey сказал:

Приветствую!

Вышел новый релиз ViPNet CryptoFile.

Скоро появится на нашем сайте.

Предлагаю дождаться его, попробовать Вам обновиться и воспроизвести ситуацию. Возможно, всё заработает.

 

Добрый день! 

Вы наверное имели в виду про новую версию ViPNet Java Crypto SDK?

Share this post


Link to post
Share on other sites
В 27.02.2017в13:50, evgenyshevnin сказал:

Вопрос ещё актуален, есть какие-нибудь предположения что делаю не так?

Евгений, попробовал у себя похожий код расшифрования - все работает. Ошибка:

Exception in thread "main" java.lang.NoSuchMethodError: ru.infotecs.cms.input.CMSEnvelopedDataInputStream.<init>(Ljava/io/InputStream;)V
    at com.it.crypto.Test2.decrypte(Test2.java:60)
    at com.it.crypto.Test2.main(Test2.java:45)

возможно, связана с тем, что у вас модуль "jcrypto-pkcs7-2.6.1-R******.jar" используется при компиляции, но не во время выполнения программы. Нужно проверить, что модуль "jcrypto-pkcs7-2.6.1-R******.jar" попадает в CLASSPATH во время запуска вашего теста.

Хотелось также уточнить, в какой IDE вы запускаете прогрмму и какую версию JCrypto SDK вы используете?
 

 

Share this post


Link to post
Share on other sites

Такая же проблема - использую android studio, compile project(':jcrypto-pkcs7-android-2.6.1-R363770')
Unable to find class:ru.infotecs.cms.output.CMSEnvelopedDataOutputStream

 

моя тема 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.