У меня есть алгоритм DES использовать Java, теперь мне нужно конвертировать эту программу Java для PHP, я не знаю Java cipher.init
третьи параметры метода SecureRandom
Итак, я использую свою программу php Des для шифрования строки, но я получил другой результат с Java Des.
Вот мой Java DES:
public static String encode(String srcStr) {
if (srcStr == null)
return null;
String dst = null;
byte[] result = encrypt2(srcStr.getBytes(), "h43au76U");
if (result == null)
return null;
System.out.println(result);
dst = byte2HexStr(result, result.length);
return dst;
}
private static final char[] mChars = "0123456789ABCDEF".toCharArray();public static String byte2HexStr(byte[] b, int iLen) {
if (b == null)
return null;
StringBuilder sb = new StringBuilder();
for (int n = 0; n < iLen; n++) {
sb.append(mChars[(b[n] & 0xff) >> 4]);
sb.append(mChars[b[n] & 0xf]);
}
return sb.toString().trim().toUpperCase(Locale.US);
}private static byte[] encrypt2(byte[] datasource, String password) {
byte[] is;
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
javax.crypto.SecretKey securekey
= keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(1, securekey, random);
is = cipher.doFinal(datasource);
} catch (Throwable e) {
e.printStackTrace();
return null;
}
return is;
}
И это мой php des:
function encrypt($input,$key,$iv=0){
$size = mcrypt_get_block_size(MCRYPT_DES,MCRYPT_MODE_CBC); //3DES加密将MCRYPT_DES改为MCRYPT_3DES
$input =pkcs5_pad($input, $size); //如果采用PaddingPKCS7,请更换成PaddingPKCS7方法。
$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
@mcrypt_generic_init($td, $key,$iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
// return $data;
return strtoupper(bin2hex($data));
}
Я получил другой результат, почему? И я не знаю, является ли SecureRandom iv
?
Всегда используйте полностью определенную строку шифра. Cipher.getInstance("DES");
может привести к различным шифрам в зависимости от поставщика безопасности по умолчанию. Это, скорее всего, приводит к "DES/ECB/PKCS5Padding"
, но это не должно быть. Если это изменится, вы потеряете совместимость между различными JVM.
Что вам нужно сделать в PHP для достижения совместимости с Java, это использовать режим ECB вместо режима CBC и применять заполнение PKCS # 5 (аналогично заполнению PKCS # 7). Этот ответ показывает реализацию этого заполнения. Вы просто должны использовать правильный размер блока, который равен 8 для DES.
Никогда не используйте Режим ЕЦБ. Это детерминированный и, следовательно, не семантически безопасный. Вы должны по крайней мере использовать случайный режим, как CBC или же CTR. Лучше аутентифицировать ваши шифротексты так, чтобы атаки набивка оракула не возможно. Это можно сделать с помощью аутентифицированных режимов, таких как GCM или EAX, или с шифровать-то-MAC схема.
IV должен быть непредсказуемым (читай: случайно). Не используйте статический IV, потому что это делает шифр детерминированным и, следовательно, не является семантически безопасным. Злоумышленник, наблюдающий шифротексты, может определить, когда тот же префикс сообщения был отправлен ранее. IV не секрет, поэтому вы можете отправить его вместе с зашифрованным текстом. Обычно он просто добавляется к зашифрованному тексту и отсекается перед расшифровкой.
Других решений пока нет …