简体   繁体   English

使用Base64编码的AES-128加密在带有较长字符串的Java和PHP中的作用不同

[英]AES-128 Encryption with Base64 Encoding doesn't act the same in Java and PHP with longer strings

I have been trying to get Encryption/Decryption to work the same in Java (Android) and PHP and produce the same results for client/server communications. 我一直在尝试使加密/解密在Java(Android)和PHP中工作相同,并为客户端/服务器通信产生相同的结果。

I'm using the code below for encryption, but I don't know what's wrong with it. 我正在使用下面的代码进行加密,但是我不知道这是怎么回事。 Running both with the same key and small strings produce the same encrypted value, with longer strings however, I get two different results. 使用相同的密钥和较小的字符串运行会产生相同的加密值,但是使用较长的字符串,则会得到两个不同的结果。 PHP: PHP:

$str = 'test1234test1234';

$key = 'TESTKEYTESTKEY12';

$block = mcrypt_get_block_size('des', 'ecb');

$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
echo base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB));

and in Java ( on Android ): 并在Java中(在Android上):

public static String encryptTest() {
  String cleartext = "test1234test1234";
  String key = "TESTKEYTESTKEY12";
    byte[] raw = key.getBytes();
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    try {
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted;
        encrypted = cipher.doFinal(cleartext.getBytes());
    return new String(Base64.encode(encrypted,Base64.DEFAULT));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

Running this with String test1234 gives: 8i4KEe82TQl0Zdlc14fwAg== in both implementations. 在两个实现中,使用String test1234运行test1234得到: 8i4KEe82TQl0Zdlc14fwAg== With string test1234test1234 however I get 4s5a0edsvwWt/3/enRe0wgJQD/0zL45NRb/r3p6L/Is= with PHP, and 4s5a0edsvwWt/3/enRe0wgA0jk78zwWJr1xsosZbYUA= with Java. 使用字符串test1234test1234但是使用PHP获得4s5a0edsvwWt/3/enRe0wgJQD/0zL45NRb/r3p6L/Is= ,使用Java获得4s5a0edsvwWt/3/enRe0wgA0jk78zwWJr1xsosZbYUA= I'm not sure what's wrong and I'm not knowledgeable enough about Cryptography. 我不确定哪里出了问题,而且我对密码学的知识还不够。

The main problem of your Java code is that you don't specify the cipher mode and the used padding algorithm. Java代码的主要问题是您未指定密码模式和使用的填充算法。 Therefore which cipher mode and padding algorithm is used depends on the used crypto provider and in this specific detail Android works different to J2SE. 因此,使用哪种加密方式和填充算法取决于所使用的加密提供程序,并且在此特定细节中,Android的工作方式不同于J2SE。

If I execute your Java code on J2SE I get the same result as you got with PHP. 如果我在J2SE上执行Java代码,则得到的结果与PHP相同。 This does not change if I change the code to use Cipher.getInstance("AES/ECB/PKCS5Padding"); 如果我更改代码以使用Cipher.getInstance("AES/ECB/PKCS5Padding");这不会改变Cipher.getInstance("AES/ECB/PKCS5Padding"); .

As only the last block of your cipher text changes I assume that Android uses a different padding algorithm by default. 由于只有密文的最后一块更改,因此我假设Android默认情况下使用其他填充算法。

The fact you have different results for short versus long strings suggest you are using different padding on each implementation. 您对长字符串和短字符串有不同的结果,这表明您在每个实现上使用不同的填充

Make sure you use the same type of padding on both your java and your php implementations. 确保在Java和php实现上使用相同类型的填充。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM