#java #php #encryption #cryptography #aes
#java #php #шифрование #криптография #aes
Вопрос:
Я искал способ зашифровать строку в Java и расшифровать ее в PHP. Я нашел это в ответе где-то на Stackoverflow и изменил его, чтобы сделать прямо противоположное. Это мой код для шифрования на Java:
public static String encrypt(String data, String initialVectorString, String secretKey) {
String encryptedData = null;
try {
SecretKeySpec skeySpec = new SecretKeySpec(md5(secretKey).substring(0, 16).getBytes(), "AES");
IvParameterSpec initialVector = new IvParameterSpec(initialVectorString.getBytes());
Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initialVector);
byte[] encrypted = cipher.doFinal(data.getBytes());
byte[] base64encrypted = (new org.apache.commons.codec.binary.Base64()).encode(encrypted);
encryptedData = new String(base64encrypted, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return encryptedData;
}
и это мой код для расшифровки на PHP:
function decrypt($message, $initialVector, $secretKey) {
return (
mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
substr(md5($secretKey), 0, 16),
base64_decode($message),
MCRYPT_MODE_CFB,
$initialVector
)
);
}
Секретный ключ и начальный вектор меняются каждый раз.
Код работает в течение 90% времени, но иногда он только частично расшифровывает строку, а остальные символы нечитаемы, например: Microsoft Windows [Version 10.0.1��×
что должно сказать Microsoft Windows [Version 10.0.14393]
. Я допустил какие-либо ошибки, изменяя код?
РЕДАКТИРОВАТЬ: возможно, мне потребуется добавить, что дешифрование в Java с использованием кода из приведенной выше ссылки ДЕЙСТВИТЕЛЬНО работает.
EDIT2: Найден ответ, это была глупая ошибка, PHP получил в зашифрованной строке base64 как пробел. Спасибо за всю вашу помощь, я все равно буду использовать ее.
Комментарии:
1. Происходит ли сбой в 10% случаев в одной и той же строке, т.Е. Передача «Hello world» 10 раз корректно работает только 9 раз из 10? Или вы имеете в виду, что передача 10 разных строк приводит к тому, что одна из них нарушается? Я не уверен, что это ваша проблема, но следует отметить одну вещь: у вас должно быть правильное количество байтов в строке base64. Если у вас нет нужного количества, декодирование может дать вам разные результаты. При необходимости попробуйте добавить отступы в конец строки base64.
2. Этот код действительно небезопасен. Хотя ваш «ключ» содержит 16 символов, но поскольку эти символы являются шестнадцатеричными, каждый из них содержит только 4 бита (вместо 8 бит, если вы на самом деле использовали необработанный двоичный вывод). Итак, ваш ключ имеет только 64 бита, что в настоящее время является принудительным.
3. Лучше не использовать mcrypt, он заброшен, годами не обновлялся. mcrypt имеет много выдающихся ошибок , относящихся к 2003 году. Вместо этого рассмотрите возможность использования defuse или RNCryptor , они предоставляют комплексное решение, поддерживаются и являются правильными.
4. Вероятно, модифицируется строка base 64, поскольку она не была правильно закодирована в URL. Сравните зашифрованный текст и IV перед их декодированием. Обратите внимание, что
initialVectorString.getBytes()
это также может привести к сбоям, хотя это не приведет к этой конкретной проблеме.5. Если вы можете использовать все, что вам нравится, тогда вам следует рассмотреть возможность использования RNCryptor . Это действительно безопасно и предоставляет реализации для разных языков, так что вам не нужно думать о специфике криптографических примитивов.