2016-05-12 43 views
1

我需要在JAVA應用程序和PHP網站之間交換加密數據。 這就是會被用來對數據進行加密的代碼:JAVA和PHP AES加密之間的區別

private static SecretKeySpec createKeyFromString(String plainKey) { 

    MessageDigest sha = null; 
    byte[] key; 
    SecretKeySpec secretKey = null; 

    try { 

     key = plainKey.getBytes("UTF-8"); 
     sha = MessageDigest.getInstance("SHA-1"); 
     key = sha.digest(key); 
     key = Arrays.copyOf(key, 16); 

     secretKey = new SecretKeySpec(key, "AES"); 

    } catch(NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch(UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 

    return secretKey; 

} 

private static String AESCrypt(String password, SecretKeySpec secretKey) { 
    try { 

     Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); 
     cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
     return Base64.getEncoder().encodeToString(cipher.doFinal(password.getBytes("UTF-8"))); 

    } catch (Exception e) { 
     System.out.println(e.toString()); 
    } 
    return null; 
} 


public static void main(String[] args) { 

    System.out.println(Pay.AESCrypt("password", Pay.createKeyFromString("key"))); 

} 

這個程序的輸出是:

aRtcSG0H5u9v7xVYClnYIw== 

我嘗試使用下面的代碼複製在PHP這種行爲:

function createKeyFromString($key) { 
    return substr(hash('sha1', $key), 0, 16); 
} 

echo openssl_encrypt("password", "AES-128-ECB", createKeyFromString("key")); 

但我發現了這樣的輸出:

pE3cPGDFjM9vwWZ3EO8xDg== 

我有點失落,爲什麼我得到一個不同的加密字符串。我試圖使用這個函數填充數據在PHP中進行加密:

function pkcs5_pad($text) { 
    $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB); 
    $pad = $size - (strlen($text) % $size); 
    return $text . str_repeat(chr($pad), $pad); 
} 

echo openssl_encrypt(pkcs5_pad("password"), "AES-128-ECB", createKeyFromString("key")); 

但它仍然不起作用。

+1

檢查您是否從SHA1獲取了相同的密鑰。特別是'hash('sha1',$ key)'返回十六進制字符,除非你給第三個參數傳遞'true'。 (另外,我真的希望你不會在最終產品中使用ECB模式。) –

+0

謝謝,就是這樣,我在生成哈希時需要第三個參數。關於ECB,使用ECB的JAVA應用程序,我不得不與我交換數據,所以我別無選擇。 –

+0

如果您有機會改進它,只需切換到libsodium。 :) –

回答

0

我錯過了PHP的哈希函數中的第三個參數來獲取原始輸出而不是HEX版本。