2016-05-10 132 views
-1

我必須從Java桌面應用程序和Android應用程序連接到Web服務。我需要發送與RIJNDAEL加密的登錄信息,但我遇到問題。Java加密和PHP解密(RIJNDAEL)

代碼Java中:

public static String getEncryptedLogin(String loginID, String encryptionKey) { 
    byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 
    SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "RIJNDAEL"); 

    AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes); 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); 
    byte[] result = cipher.doFinal(loginID.getBytes("UTF-8")); 
    return Base64.getEncoder().encodeToString(result); 
} 

而且這樣調用。

String dataToSend = "login="+Testencrypted.getEncryptedLogin(LOGIN,WS_ENCKEY)+"&language=en"; 

上WS_ENCKEY是一個字符串與密鑰(32chars)加密。

當我執行Java代碼中,我得到一個異常錯誤「非法密鑰大小」,所以在別人看完後張貼在這個網站上,RIJNDAEL算法需要128位的密鑰,所以我改變我的方式調用加密方法

String dataToSend = "login="+Testencrypted.getEncryptedLogin(LOGIN,WS_ENCKEY.substring(0,16))+"&language=en"; 

在服務器端我有這樣的PHP代碼解密:

<?php 
class Encrypter { 
    public static function encrypt($text,$key) { 
     $textenc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $text, MCRYPT_MODE_ECB); 
     return base64_encode($textenc); 
    } 
    public static function decrypt($text,$key) { 
     return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($text), MCRYPT_MODE_ECB)); 
    } 
} 

在服務器我收到正確的數據,但是當我嘗試解密登錄,輸出是不一樣的。

我不能更改服務器端的代碼,你能幫我嗎?

+0

PHP mcrypt不支持PKCS5填充。最好不要使用mcrypt,它是放棄使用,多年未更新並且不支持標準PKCS#7(néePKCS#5)填充,只有非標準的null填充甚至不能用於二進制數據。請考慮使用[defuse](https://github.com/defuse/php-encryption),它正在維護並且是正確的。 – zaph

回答

0

PHP mcrypt不支持PKCS5填充,只有null填充。您將不得不在Java中選擇填充,並且將加密後的輸入數據填充爲塊大小的倍數,並在Java中解密時刪除空值。

PHP mcrypt服務器代碼使用的ECB模式是不安全的,爲了兼容Java還需要指定ECB模式,而不是CBC模式。 ECB模式不使用IV。