Расшифруйте Rijndael 256 (из PhP) закодированный текст в Java с небольшим количеством информации - PullRequest
1 голос
/ 23 марта 2012

У меня есть некоторые данные от внешней стороны, которые зашифрованы в соответствии с ними в: 'Rijndeal 256 с закрытым ключом'

Наряду с этими записями есть сертификат открытого и закрытого ключа, который выглядит как сертификаты RSA.

Из того, что я узнал до сих пор, кажется, что наиболее распространенный способ использования шифрования с сертификатами - генерировать «секретный ключ» или какой-то другой вектор инициализации и использовать его для шифрования текста.Поэтому я думаю, что это, вероятно, то, что они сделали (данные были зашифрованы приложением PHP)

Я пытаюсь расшифровать этот текст с помощью javax.crypto.Cipher, но я думаю, что, вероятно, мне нужно больше информациина конкретном шифровании, но я действительно не знаю, какую информацию запрашивать, и думаю, что, вероятно, будут работать «опции по умолчанию».(Связь с поставщиком - трудная и медленная).

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

  InputStreamReader ir = new InputStreamReader(the_inputstream_for_the_private_key_record);
   Security.addProvider(new BouncyCastleProvider());
   pemr = new PEMReader(ir);
   Object o = pemr.readObject();
   keyPair kp = (KeyPair) o;
   return kp.getPrivate();

Это работает, когда я получаю экземплярОбъект PrivateKey без ошибок выглядит так:

RSA Private CRT Key
            modulus: c98faa50ba69<trimmed>
    public exponent: 10001
   private exponent: bb889fbe5cb2a6763f...<trimmed>
             primeP: eb73e85dc636f5751b...<trimmed>
             primeQ: db269bd603a2b81fc9...<trimmed>
     primeExponentP: 85b9f111c190595cc8...<trimmed>
     primeExponentQ: a66d59a75bb77530de...<trimmed>
     crtCoefficient: 79415b078c4c229746...<trimmed>

Для каждой записи у меня также есть запись, подобная следующей:

{
"decryptedLength":128389,
"symKeyLength":32,
"symKey":"SImE8VnSZaAu1Ve...<trimmed (this is always 685 chars long) >...ayaJcnpSeOqAGM7q="
}

По сути, это то, где я немного застрял.Я предполагаю, что это значение 'symkey' зашифровывается с помощью RSA, который, в свою очередь, при расшифровке дает секретный ключ для части AES, но если я попытаюсь:

Cipher rsaCipher = Cipher.getInstance("RSA");
rsaCipher.init(Cipher.DECRYPT_MODE, key);
byte[] b = rsaCipher.doFinal('symkey'.getbytes());

, то получится "javax.cryptoIllegalBlockSizeException: данные не должны быть длиннее 512 байт ", что кажется логичным, поскольку эта строка имеет длину 685 символов

Я, вероятно, здесь упускаю что-то очень очевидное ... Любые предложения приветствуются.

Ответы [ 3 ]

2 голосов
/ 24 марта 2012

Просто догадываюсь, но я думаю, что значение

"symKey":"SImE8VnSZaAu1Ve...<trimmed (this is always 685 chars long) >...ayaJcnpSeOqAGM7q="

является закодированным в base64 выводом от шифрования RSA с использованием 4096-битного открытого ключа.Вам нужно сначала base64 декодировать значение в массив byte [], затем расшифровать его с помощью закрытого ключа, результатом которого будет 256-битный ключ.Обратите внимание, что «Rijndael 256» является неоднозначным, поскольку Rijndael поддерживает как 256-битный размер блока, так и 256-битный размер ключа.

1 голос
/ 26 марта 2012

с ответом Грегса я наконец-то получил это на работу. (добавление ответа на случай, если кому-то еще нужно расшифровать аналогичные php-файлы).

Первая часть состояла в том, чтобы расшифровать de симметричный ключ ("symkey") из строки метаданных Это было так, как Грег отмечает в кодированном Base64 ключе RSA, который был декодирован так:

Cipher rsaCipher = Cipher.getInstance("RSA");
rsaCipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedRijndaelKey = Base64.decodeBase64(base64EncodedSymetricKey); //from the metaData
byte[] rijndaelKeyBytes = rsaCipher.doFinal(encryptedRijndaelKey);

Этот ключ Rijndael затем использовался для дешифрования фактически зашифрованных данных, например:

RijndaelEngine rijndaelEngine = new RijndaelEngine(256); // *1 *2
KeyParameter keyParam = new KeyParameter(rijndaelKeyBytes)
rijndaelEngine.init(false, keyParam);  //false == decrypt
PaddedBufferedBlockCipher bbc = new PaddedBufferedBlockCipher(rijndaelEngine, new ZeroBytePadding()); // *3 

byte[] decryptedBytes = new byte[decryptedLenght]; //from the storageOptions string
int processed = bbc.processBytes(inputBytes, 0, inputBytes.length, decryptedBytes, 0);
bbc.doFinal(decryptedBytes, processed);

* 1, поскольку Sun JCA поддерживает только общий AES с размером ключа 128 бит, мне пришлось использовать другого поставщика (BouncyCastle). * 2 очевидно размер блока был также 256 бит (след и ошибка) * 3, по-видимому, не использовалось заполнение, поэтому ZeroPadding для заполнения (снова trail & error).

0 голосов
/ 24 марта 2012

Значение symKey имеет кодировку Base64 и должно быть декодировано, прежде чем вы сможете выполнить расшифровку секретного ключа на нем. Также симметричное шифрование звучит как AES-256. (AES основан на шифре Рейндаля).

...