Как соответствовать шифрованию ColdFusion Java 1.4.2?

*** сладкий - благодаря Edward Smith для CF Technote, который указал, ключ от ColdFusion был закодированным Base64. См. generateKey () для 'фиксации'

Моя задача состоит в том, чтобы использовать Java 1.4.2 для соответствия результатам данный пример кода ColdFusion для шифрования.

Знать/давать значения:

  • 24-байтовый ключ
  • 16-байтовая соль (IVorSalt)
  • Кодирование является Шестнадцатеричным числом
  • Алгоритм шифрования является AES/CBC/PKCS5Padding
  • Демонстрационное значение открытого текста
  • Зашифрованное значение демонстрационного открытого текста после прохождения через кода ColdFusion

Предположения:

  • Количество повторений, не указанных в ColdFusion, кодирует, таким образом, я принимаю только одно повторение
  • 24-байтовый ключ, таким образом, я принимаю 192-разрядное шифрование

Давать/работать образец кода шифрования ColdFusion:

<cfset ThisSalt = "16byte-salt-here">
<cfset ThisAlgorithm = "AES/CBC/PKCS5Padding">
<cfset ThisKey = "a-24byte-key-string-here">
<cfset thisAdjustedNow = now()>
<cfset ThisDateTimeVar = DateFormat( thisAdjustedNow , "yyyymmdd" )>
<cfset ThisDateTimeVar = ThisDateTimeVar & TimeFormat( thisAdjustedNow , "HHmmss" )>
<cfset ThisTAID = ThisDateTimeVar & "|" & someOtherData>
<cfset ThisTAIDEnc = Encrypt( ThisTAID , ThisKey , ThisAlgorithm , "Hex" , ThisSalt)>

Мой Java 1.4.2 добычи кода шифрования/дешифрования:

package so.example;

import java.security.*;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.*;

public class SO_AES192 {

private static final String _AES = "AES";
private static final String _AES_CBC_PKCS5Padding = "AES/CBC/PKCS5Padding";
private static final String KEY_VALUE = "a-24byte-key-string-here";
private static final String SALT_VALUE = "16byte-salt-here";
private static final int ITERATIONS = 1;

private static IvParameterSpec ivParameterSpec;

public static String encryptHex(String value) throws Exception {
    Key key = generateKey();

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding);
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes());
    c.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);

    String valueToEncrypt = null;
    String eValue = value;
    for (int i = 0; i < ITERATIONS; i++) {
//            valueToEncrypt = SALT_VALUE + eValue; // pre-pend salt - Length > sample length
        valueToEncrypt =  eValue;     // don't pre-pend salt  Length = sample length
        byte[] encValue = c.doFinal(valueToEncrypt.getBytes());
        eValue =  Hex.encodeHexString(encValue);
    }
    return eValue;
}

public static String decryptHex(String value) throws Exception {
    Key key = generateKey();

    Cipher c = Cipher.getInstance(_AES_CBC_PKCS5Padding);
    ivParameterSpec = new IvParameterSpec(SALT_VALUE.getBytes());
    c.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);

    String dValue = null;
    char[] valueToDecrypt = value.toCharArray();
    for (int i = 0; i < ITERATIONS; i++) {
        byte[] decordedValue = Hex.decodeHex(valueToDecrypt);
        byte[] decValue = c.doFinal(decordedValue);
//            dValue = new String(decValue).substring(SALT_VALUE.length()); // when salt is pre-pended
        dValue = new String(decValue);   // when salt is not pre-pended
        valueToDecrypt = dValue.toCharArray();
    }
    return dValue;
}

private static Key generateKey() throws Exception {
    // Key key = new SecretKeySpec(KEY_VALUE.getBytes(), _AES); // this was wrong
    Key key = new SecretKeySpec(new BASE64Decoder().decodeBuffer(keyValueString), _AES); // had to un-Base64 the 'known' 24-byte key.
    return key;
}

}

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

Я не очень crypto-опытен, но я думаю, что должен смочь взять демонстрационный открытый текст и произвести то же зашифрованное значение в Java как произведенный ColdFusion. Я могу шифровать/дешифровать свои собственные данные с моим кодом Java (таким образом, я последователен), но я не могу соответствовать, ни дешифровать зашифрованное значение образца ColdFusion.

У меня есть доступ к локальному веб-сервису, который может протестировать зашифрованный вывод. Данный выходной образец ColdFusion передает/дешифрует прекрасный (конечно). Если я пытаюсь дешифровать тот же образец со своим кодом Java (использующий фактический ключ и соль), я получаю "Данный заключительный блок не правильно дополненная" ошибка. Я получаю тот же конечный результат, когда я передаю свою попытку шифрования (использующий фактический ключ и соль) к тестовому веб-сервису.

Какие-либо идеи?

7
задан JohnTheBarber 14 April 2010 в 18:26
поделиться

1 ответ

Является ли значение в Coldfusion ThisKey:

<cfset ThisKey = "a-24byte-key-string-here">

той же самой строкой, которая возвращается функцией java generateKey ()? Я считаю, что они должны быть одной и той же строкой, чтобы сгенерированный зашифрованный текст был таким же.

Чтобы использовать фиксированный ключ, подобный тому, что используется в CF, вам может потребоваться следовать этому из CF technote по надежному шифрованию:

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

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

Например, чтобы создать 32-байтовый ключ для использования с алгоритмом AES с шестнадцатеричным значением :

8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c

, вы должны использовать {1} функции ColdFusion }} BinaryDecode и ToBase64 для создания ключа:

<cfset myKey =
ToBase64(BinaryDecode("8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c","Hex")>
<cfset encrypted =Encrypt(myString, myKey, "AES")>

РЕДАКТИРОВАТЬ: Только что понял, что ключ (как вы упомянули в своем комментарии) - это base64, поэтому, если метод "generateKey" в Java выглядит так:

private static Key generateKey() throws Exception {
final byte[] decodedKey = new BASE64Decoder().decodeBuffer(KEY_VALUE);
final Key key = new SecretKeySpec(decodedKey, _AES);
return key;
}

Вы должны быть золотыми.

4
ответ дан 7 December 2019 в 14:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: