2016-06-14 2 views
3

Я знаю, что есть довольно много обсуждают вокруг StackOverflow о шифровании PHP Java AES CBC, но ни один из них не решить мою проблемуИспользование PHP, чтобы получить такое же шифрование AES-128-CBC, как Java делает

здесь ява функция:

public static String encrypt(String input, String key){ 
    byte[] crypted = null; 

    SecretKeySpec skey = new SecretKeySpec(getHash("MD5", key), "AES"); 
    IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }); 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, skey, iv); 
    crypted = cipher.doFinal(input.getBytes()); 
    return new String(Base64.encodeBase64(crypted)); 
} 

private static byte[] getHash(String algorithm, String text) { 
    try { 
     byte[] bytes = text.getBytes("UTF-8"); 
     final MessageDigest digest = MessageDigest.getInstance(algorithm); 
     digest.update(bytes); 
     return digest.digest(); 
    } catch (final Exception ex) { 
     throw new RuntimeException(ex.getMessage()); 
    } 
} 

Вот что я сделал в PHP

public static function encrypt($input, $key) { 

    $key = hash('md5', $key, true); 
    $iv = '0000000000000000'; 
    return openssl_encrypt($input, 'aes-128-cbc', $key, 0, $iv); 
} 

Давайте посмотреть результат

key:"790757e76c8942f995675b247aa57c2a" 
input:"1234" 

result in java:UfczMtIAm8ewSuIGRdPTDQ== 
result in PHP:wd/OTHoIXwgHGDHcj8OTgg==  

В PHP, я также использовать другой метод, например, mcrypt_encrypt, mcrypt_generic с pkcs5 прокладкой (см код удара), все они могли бы получить такое же шифрование, как openssl_encrypt сделал, но все же не такой же, как Java результат функции

public static function encrypt($input, $key) { 

    $key = hash('md5', $key, true); 


    $iv = '0000000000000000'; 

    $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
    $input = Security::pkcs5_pad($input, $size); 


    $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $input, MCRYPT_MODE_CBC, $iv); 

    // output wd/OTHoIXwgHGDHcj8OTgg== 
    echo base64_encode($encrypted); 

    $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); 

    mcrypt_generic_init($td, $key, $iv); 
    $data = mcrypt_generic($td, $input); 
    mcrypt_generic_deinit($td); 
    mcrypt_module_close($td); 
    $data = base64_encode($data); 

    // output wd/OTHoIXwgHGDHcj8OTgg== 
    echo $data; 
} 

private static function pkcs5_pad ($text, $blocksize) { 
    $pad = $blocksize - (strlen($text) % $blocksize); 
    return $text . str_repeat(chr($pad), $pad); 
} 

Еще одна странной вещью, которую я уведомление, если я изменю шифр метода от CBC к ЕЦБ, как Java и PHP шифрование будет то же самое, но, к сожалению для доступа к 3-й партии API, я должен использовать CBC

+0

Как вы гарантировать, что они имеют такую ​​же отступы? – Rahul

+0

@Rahul Я использую PKCS # 5 –

ответ

2

наконец, выяснить это

$iv = '0000000000000000'; 

должен заменить его

$iv = str_repeat(chr(0), 16); 

скопировать его где-то еще и подумал '0000000000000000' равно IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }), и это было совершенно неправильно ..