2015-07-03 4 views
1

У меня есть этот унаследованный код в PHP, что я хочу, чтобы воспроизвести в Java:Java/PHP шифрования CAST-256

function enCrypt($data = null) { 
    $key = 'thisismysupersecretkeyglhf1'; 

    $encoded=mcrypt_encrypt(MCRYPT_CAST_256, 
    $key, 
    $data, 
    MCRYPT_MODE_ECB 
    ); 

    $encoded = base64_encode($encoded); 

    return $encoded; 
} 

function deCrypt($data = null) { 
    $key = 'thisismysupersecretkeyglhf1'; 

    $decrypted= mcrypt_decrypt(
    MCRYPT_CAST_256, 
    $key, 
    base64_decode($data), 
    MCRYPT_MODE_ECB 
    ); 

    return $decrypted; 
} 

Я использую Надувной замок CAST-6 Двигатель следующим образом:

public static final String KEY = "thisismysupersecretkeyglhf1"; 


public static String encrypt(String toDecrypt) throws NoSuchPaddingException, 
     NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, 
     InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException, UnsupportedEncodingException { 

    Cipher cipher = Cipher.getInstance("CAST6/ECB/NoPadding"); 

    SecretKeySpec key=new SecretKeySpec(KEY.getBytes(),"CAST6"); 

    cipher.init(Cipher.ENCRYPT_MODE, key); 

    String decoded=org.apache.commons.codec.binary.Base64.encodeBase64String(cipher.doFinal(toDecrypt.getBytes())); 

    return decoded; 
} 

public static String decrypt(String toDecrypt) throws NoSuchPaddingException, 
     NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, 
     InvalidKeyException, BadPaddingException, IllegalBlockSizeException, DecoderException, UnsupportedEncodingException { 

    Cipher cipher = Cipher.getInstance("CAST6/ECB/NoPadding"); 

    SecretKeySpec key=new SecretKeySpec(KEY.getBytes(),"CAST6"); 

    cipher.init(Cipher.DECRYPT_MODE, key); 

    byte[] decoded=org.apache.commons.codec.binary.Base64.decodeBase64(toDecrypt); 

    return new String(cipher.doFinal(decoded)); 
} 

Однако я не могу производить одни и те же зашифрованные результаты или расшифровывать что-либо зашифрованное на PHP с помощью JAVA.

Что мне не хватает?

Является ли это проблемой для заполнения? Читая через mcrypt документацию, они, похоже, делают много дополнений к ключам и данным. Мой ключ (устаревший ключ) результаты 27chars длинного, которые я считаю, должны быть дополнен до 32 байт по Mcrypt, так как mcrypt_get_key_size (MCRYPT_CAST_256, MCRYPT_MODE_ECB) в 32

Для получения дополнительной информации струны Я пытаюсь зашифровать это " 1111111111111111" . Я не знаю, будет ли это дополняться PHP, но я бы подумал, что это не так, потому что mcrypt_get_block_size (MCRYPT_CAST_256, MCRYPT_MODE_ECB) возвращает 16, что точно соответствует длине Im.

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

Любая помощь в реализации этих функций в Java будет с благодарностью оценена.

PD. Я знаю, что этот алгоритм не самый лучший, а не использование IV, а также использование ECB как-то тревожно, но это только для интеграции устаревших кодов.

+0

У меня была такая же проблема с PHP <=> Delphi и AES-256. Это также была проблема с заполнением, поэтому мы использовали обработку префикса на обоих концах Webservice, чтобы получить тот же самый. Люди, которые более квалифицированы в симметричной криптографии, смогут вам помочь. Удачи ! –

+0

Не могли бы вы опубликовать PHP-шифрованный текст (в шестнадцатеричных)? –

ответ

1

Итак, я, наконец, понял это.

Очевидно, что реализация PHP алгоритма Cast6, по-видимому, не является стандартной.

Сначала у меня был нервный срыв, поскольку он не смог воспроизвести то же значение, что и в алгоритме test vectors. Так что пришло время посмотреть на источник PHP.

Я загрузил PhpCrypt Library от Ryan Gilfether, который производит тот же результат, что и mcrypt lib php. И началась отладка.

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

Итак, как только проблема была обнаружена, было просто, чтобы воссоздать процесс со стороны Java, я создал новый Bouncy Castle Engine, расширяющий CAST5Engine, и заменил метод setKey и encryptBlock. Вы можете посмотреть this gist, чтобы узнать, как это работает.

Ключ обратныйByteArrayByBlock, который вызывается несколько раз. Точно так же, как это делает PHP.

В Gist вы также можете узнать, как использовать класс в файле PHPCast256Crypter.java, если вы не слишком хорошо знакомы с тем, как работает Bouncy Castle (функции шифрования/дешифрования предполагают, что ваши ключи закодированы в шестнадцатеричном формате).

Удачи!

+0

Вы только что спасли мой день! Большое спасибо за это –