Шифрование строки в Java и дешифрование в C ++ - PullRequest
1 голос
/ 16 декабря 2010

Мне нужно зашифровать строку в Java и расшифровать ее в C ++.Я видел, что в C ++ есть библиотека Crypto ++, а в Java есть JCE, Jasypt, BouncyCastle и т. Д., Но я все больше и больше путаюсь ...

Я ищу что-то простое.Высокий уровень безопасности не требуется для этого варианта использования.Важно, чтобы алгоритм шифрования на одной стороне был аналогичен алгоритму на другой, конфигурируя их самым простым способом.


РЕДАКТИРОВАТЬ (улучшенное объяснение):

Я хотел бы сделать это:

  • in Java : взять строку ввода , шифровать с строковым паролем (и не с такими вещами, как байтовые массивы или векторы инициализации), получая зашифрованную строку

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

Для части Java, которую я знаюэтот код Jasypt:

StandardPBEStringEncryptor hexEncryptor = new StandardPBEStringEncryptor() ;
hexEncryptor.setStringOutputType("hexadecimal");
hexEncryptor.setPassword(ENCRYPTION_PASSWORD);
String encryptedString = hexEncryptor.encrypt(inputString);

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

Ответы [ 6 ]

3 голосов
/ 25 декабря 2010

Вы можете сделать это, это не тонна работы.Вам просто нужны строительные блоки из крипто-библиотек.

  1. Используйте PBKDF1 или PBKDF2 для получения ключей.Оба алгоритма имеют много реализаций как на C ++, так и на Java.Вы вводите пароль, вы получаете симметричный ключ шифрования.

  2. Вы говорите: «высокий уровень безопасности не важен», что, я думаю, не имеет большого смысла (вы тожеиметь безопасность или нет), но позвольте мне зафиксировать это и принять это как означающее, что вы будете рады использовать потоковый шифр, такой как RC4, вместо AES с его IV и режимами блочного шифра и т. д., которые могут бытьболь, с которой приходится иметь дело в различных реализациях.

  3. Так что используйте RC4 или ARC4.Опять же, много реализаций на Java и C ++.Вы передаете ему свой ключ и строку байтов, и выходит строка байтов: открытый текст или зашифрованный текст, основанный на операции.RC4 не имеет хорошей репутации, но по сей день это шифр по умолчанию в IE и IIS для TLS.Вы будете в порядке с RC4.(Я не являюсь поклонником IE и IIS по большому количеству причин, но RC4 в моем списке нет.)

  4. Для хорошей меры вы можете добавить префикс вашего открытого текста до того, какшифрование с заголовком.Вы можете указать длину открытого текста в заголовке и SHA1 / 256/512 (на ваш выбор) хеш открытого текста.Опять же, много хороших реализаций для этих хэш-алгоритмов в C ++ и Java.Затем вы шифруете заголовок и текст.Таким образом, будет очень легко определить, прошла ли расшифровка хорошо;просто проверьте поля длины и хеша.

Пока вы используете одни и те же хорошо зарекомендовавшие себя алгоритмы как в C ++, так и в Java, и у вас есть четко определенный формат обмена (см. 4выше) вы можете быстро и безопасно решить эту проблему.

РЕДАКТИРОВАТЬ:

Обратите внимание, что существуют предостережения, которые применяются к потоковым шифрам.Цитируя Шнайера:

Одно из самых важных правил потоковых шифров - никогда не использовать один и тот же поток ключей для шифрования двух разных документов.Если кто-то это сделает, вы можете нарушить шифрование, XOR объединяя два потока зашифрованного текста вместе.Поток ключей выпадает, и в итоге вы получаете XOR с открытым текстом с открытым текстом - и вы можете легко восстановить два открытых текста, используя частотный анализ букв и другие базовые методы.

Это крипто-ошибка любителя.Простой способ предотвратить эту атаку - использовать уникальный вектор инициализации (IV) в дополнение к ключу при каждом шифровании документа.

2 голосов
/ 21 декабря 2010

Если безопасность не важна, просто сделайте XOR на одном конце, скажем, с 70, затем снова XOR на другом.Это займет около 10 минут для любого взломщика, чтобы выяснить вручную.Или бабушка, которая хорошо разбирается в криптоцитатах в газете.

Если вы действительно хотите безопасный, легкий и медленный, не имеет значения (обработка <1x в секунду в среднем или 10x / sec, если у вас естьмашина для себя), сделайте это: </p>

  1. реализовать шифрование / дешифрование с помощью общей библиотеки Java
  2. чтобы C ++ сделал process.start длярасшифровщик Java

Передача чего-то уникального, скажем, идентификатора процесса программы C #, в качестве параметра для программы Java, вы можете поделиться файлом, содержащим этот идентификатор.Или, если вы можете заставить программу Java работать как консольную программу, пусть она читает / записывает консоль, а C # использует Process.StandardInput / StandardOutput.Или ... и т. Д. И т. Д.

Гадкий хак, да.Если вы хотите работать быстро и выполнять больше работы в течение дня, выясните, будут ли ваши клиенты или пользователи заботиться о вас.

1 голос
/ 30 июля 2015

Я много исследовал это в интернете, и никакого решения не было найдено.Поэтому я решил сделать это сам.

Я создал класс для этого!Приведенный ниже код объясняет сам по себе.Хорошо выглядишь!

            #pragma once
            #include <string>
            #include "../../Include/Cryptopp562/aes.h"
            using namespace CryptoPP;

            //.h

                class CryptoUtil 
                {
                public:
                    CryptoUtil(std::wstring mac);

                    byte m_key[CryptoPP::AES::DEFAULT_KEYLENGTH];
                    byte m_iv[CryptoPP::AES::DEFAULT_KEYLENGTH];
                    char m_macInChar[12];

                    // decripty string encrypted in AES/CBC/PKCS5Padding mode
                    std::wstring DecryptStr(std::wstring str);
                };


            //.cpp
            #include "stdafx.h"
            #include "CryptoUtil.h"
            #include <atlstr.h>
            #include "../../Include/Cryptopp562/cryptlib.h"
            #include "../../Include/Cryptopp562/filters.h"
            #include "../../Include/Cryptopp562/modes.h"
            #include "../../Include/Cryptopp562/modes.h"
            #include "../../Include/Cryptopp562/aes.h"
            #include "../../Include/Cryptopp562/filters.h"
            #include "../../Include/Cryptopp562/aes.h"
            #include "../../Include/Cryptopp562/base64.h"
            #include "../../Include/Cryptopp562/md5.h"


            using namespace CryptoPP;




            CryptoUtil::CryptoUtil(std::wstring mac)
            {
                CryptoPP::MD5 md5;

                byte ivString [] = { "blablabla!@#$&&&&&&&" };

                md5.CalculateDigest(m_iv, (byte*) ivString, 20);

                char macInChar[12 + 1];

                size_t charsConverted = 0;

                wcstombs_s(&charsConverted, macInChar, mac.c_str(), mac.length());

                md5.CalculateDigest(m_key, (byte*) macInChar, 12);
            }

            std::wstring CryptoUtil::DecryptStr(std::wstring str)
            {
                std::string encoded, decoded, recovered;

                //change wchar to char
                size_t outputSize = str.length() + 1;

                char* pBuffer = new char[outputSize];

                size_t charsConverted = 0;

                wcstombs_s(&charsConverted, pBuffer, outputSize, str.c_str(), str.length());

                std::string plain(pBuffer);

                delete [] pBuffer;

                char * pFormattedStr = new char[outputSize];
                int sizeOf = sizeof(pFormattedStr);

                sprintf_s(pFormattedStr, outputSize, "%16s", plain.c_str());

                encoded = pFormattedStr;

                delete [] pFormattedStr;

                try
                {

                    StringSource ss(encoded, true,
                        new CryptoPP::Base64URLDecoder(
                        new StringSink(decoded)
                        ) // Base64URLDecoder
                        ); // StringSource


                    CBC_Mode< AES >::Decryption dec;
                    dec.SetKeyWithIV(m_key, sizeof(m_key), m_iv);

                    // The StreamTransformationFilter removes
                    //  padding as required.
                    //StringSource s(cipher, true,
                    StringSource s(decoded, true,
                        new StreamTransformationFilter(dec,
                        new StringSink(recovered)
                        ) // StreamTransformationFilter
                        ); // StringSource


                    CStringW strTemp = CA2W((char*) recovered.c_str(), CP_UTF8);

                    strTemp.Trim();

                    std::wstring strRecovered(strTemp);

                    return strRecovered;

                }
                catch (const CryptoPP::Exception& e)
                {
                    throw e;
                }

            }
0 голосов
/ 20 ноября 2013

Просто проанализируйте шифры, используемые в C ++ и Java.В Java по умолчанию используется ECB.Это может быть проблемой.

0 голосов
/ 26 декабря 2010

RSA-шифрование - это шифрование с открытым ключом, которое довольно легко внедрить и использовать.

Ранее было сообщение о потоке стека о шифровании RSA в C ++: Библиотека шифрования RSA для C ++ .

Быстрый поиск Google для Java RSA предоставит вам достаточно библиотек для шифрования / дешифрования для ваших целей.

0 голосов
/ 16 декабря 2010

Прежде всего: AES - это блочный шифр, т. Е. Он шифрует или дешифрует блоки с фиксированным числом байтов - обычно 16. Так что вам нужно что-то вроде AES / CBC или AES / CTS.

  • Для C ++ я не знаю ничего, кроме Crypro ++.
  • Для Java с JCE

Пример:

import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.Key;
import java.text.NumberFormat;
public static void runEncTest( byte[] encryptionKey, byte[] ivBytes, byte[] input )
{
  try
  {
    Key key = new SecretKeySpec( encryptionKey, "AES" );

    Cipher cipher = Cipher.getInstance( "AES/CTS/NoPadding" );
    cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));

    byte[] cipherText = new byte[cipher.getOutputSize(input.length)];
    int ctLength = cipher.update(input, 0, input.length, cipherText, 0);
    ctLength += cipher.doFinal(cipherText, ctLength);

    printByteArray( "PLAIN:", input );
    printByteArray( "CRYPT:", cipherText );      
  }
  catch( java.lang.Exception e )
  {
    System.out.println("Got an Exception: " + e.getMessage());
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...