簡體   English   中英

Java方面的AES加密-PHP方面的解密並選擇單個密鑰

[英]AES encryption on Java side - decryption on PHP side and selecting a single key

我正在使用AES,我想確定一個可以在Java端使用的密鑰來加密字符串,我在PHP端對相同的密鑰進行硬編碼,並且如果該字符串與我經過身份驗證的字符串匹配,則可以解密該字符串。

以下是我的Java代碼:

public class AESencrp {

     private static final String ALGO = "AES";
    private static final byte[] keyValue = 
        new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };

public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }
    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(keyValue, ALGO);
        return key;
}

}

這是我在PHP中使用的功能:

function fnDecrypt()
{
 // echo $_POST['key'];
 $sValue = $_POST['key']; 
 $sSecretKey = "TheBestSecretKey";
    return rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_256, 
            $sSecretKey, 
            base64_decode($sValue), 
            MCRYPT_MODE_CBC,
            mcrypt_create_iv(
                mcrypt_get_iv_size(
                    MCRYPT_RIJNDAEL_256,
                    MCRYPT_MODE_CBC
                ), 
                MCRYPT_RAND
            )
        ), "\0"
    );
}

但是看來,我總是在php端獲得不同的解密文本,我覺得問題出在密鑰上,而當我進行硬編碼時,這種行為不應該發生,有什么提示嗎?

您似乎在做錯幾件事,我將按順序進行檢查:

在Java中創建Cipher實例時,請始終指定"Algorithm/Mode/Padding" 否則,您永遠不會知道將使用哪種模式和填充,如果要在不同的平台和編程語言之間傳遞加密的數據,這將尤其成問題,因為它們可能具有不同的默認值。 (例如,Java的默認填充為PKCS1Padding ,其中PHP的mcrypt_decrypt()需要ZeroBytePadding
因此,使用以下命令初始化ALGO

/* ZeroBytePadding should better not be used in practice */
private static final String ALGO = "AES/CBC/ZeroBytePadding";

正如Roland Jansen所述,Java AES是128位版本。 因此,在PHP中使用:

MCRYPT_RIJNDAEL_128

第三,必須始終為每種加密指定不同的隨機IV (一定不能保密)。 然后,您必須使用相同的IV進行解密。 因此,您還必須在Java中生成一個IV ,然后將其傳遞給PHP並用於在那里進行解密。

byte[] iv = new byte[16]; // must be 16 bytes for AES-128
new SecureRandom().nextBytes(iv); // generate random bytes
IvParameterSpec ivSpec = new IvParameterSpec(iv);

/* create instance of Cipher and keys */

cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

到目前為止,您還可以在PHP中生成一個隨機IV ,這顯然不會導致所需的純文本。 在php中執行以下操作以進行解密:

 $key = "{insert Java encryption key here}";
 $iv; = "{insert Java encryption IV here}";

 mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $ciphertext, MCRYPT_MODE_CBC, $iv);

如果在完成這些修復后仍無法正常工作,則問題可能出在密文或密鑰/ IV字符串的編碼上。 嘗試確保將與從Java中cipher.doFinal接收到的數據完全相同的數據傳遞給PHP。

希望能為您服務。

此鏈接http://www.androidsnippets.com/encrypt-decrypt-between-android-and-php提供了可幫助您的教程。 如果要更改SecretKey。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM