我正在使用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字符串的编码。请确保您传递给PHP的数据与您在Java中从cipher.doFinal
接收到的数据完全相同。
我希望我能帮到你。
这个链接http://www.androidsnippets.com/encrypt-decrypt-between-android-and-php有一个教程可以帮助你。