AES加密在Java端,解密在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字符串的编码。请确保您传递给PHP的数据与您在Java中从cipher.doFinal接收到的数据完全相同。

我希望我能帮到你。

这个链接http://www.androidsnippets.com/encrypt-decrypt-between-android-and-php有一个教程可以帮助你。

相关文章: