[英]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.