Java openssl_encrypt AES encrypt with out vector

Java openssl_encrypt AES encrypt with out vector,java,php,aes,Java,Php,Aes,我需要一个令牌来访问某个源。源提供程序给了我一个java示例,演示了如何创建它。下面是它如何加密文本: private static final String ALGO = "AES"; public static String encrypt(byte[] keyValue, String token_text) throws Exception { Key key = new SecretKeySpec(keyV

我需要一个令牌来访问某个源。源提供程序给了我一个java示例,演示了如何创建它。下面是它如何加密文本:

private static final String ALGO = "AES";                   
public static String encrypt(byte[] keyValue, String token_text) throws Exception {                 
    Key key = new SecretKeySpec(keyValue, ALGO);
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.ENCRYPT_MODE, key);

    byte[] bytes = c.doFinal(token_text.getBytes());
    byte[] buf = Base64.encodeBase64(bytes);

    return new String(buf); 
}
我想把这段java程序翻译成php。下面是我的代码:

public static function generate_token($token_text, $key) {
        $iv = self::hex_to_str("00000000000000000000000000000000");
        $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);
        return $token;
    }

    private static function hex_to_str($hex)
    {
            $string='';
            for ($i=0; $i < strlen($hex)-1; $i+=2)
            {
                $string .= chr(hexdec($hex[$i].$hex[$i+1]));
            }
            return $string;
    }
表示密码的默认向量为0。我试过了,仍然不能得到同样的结果,但非常接近:

java:v8GhW0lu8DzNyqsfQTg4g7H6pwXCAAgy9vqFdz5OmXY=

php:v8GhW0lu8DzNyqsfQTg4g6If77f+8YVCQ8VCQGNE68=

我被困在这里一整天了。如果有人能帮忙,我将不胜感激

# java -version
openjdk version "1.8.0_101"
OpenJDK Runtime Environment (build 1.8.0_101-b13)
OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)

# php -v
PHP 5.6.24 (cli) (built: Jul 21 2016 07:42:08) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

假设Java端使用SunJCE提供程序,默认模式为ECB模式,默认填充为PKCS5Padding,即
Cipher.getInstance(“AES”)
Cipher.getInstance(“AES/ECB/PKCS5Padding”)
相同,请参见示例

ECB模式不使用IV。因此,您必须在PHP generate_token-method中替换

$iv = self::hex_to_str("00000000000000000000000000000000");
$token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);

例如:

encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");
提供

fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==
这与PHP代码的结果相同(对于相同的键和纯文本)

通常,如果您有多个块,ECB模式是不安全的(从您的示例中,我推断您的令牌至少由两个块组成)。然后,更好的选择是CBC或GCM模式,参见和。但由于Java加密方法似乎是您的参考,因此可能无法更改它

编辑:


Java cipher类使用keysize自动确定是否必须使用AES-128、AES-192或AES-256。因此,您还必须知道Java代码上下文中键的大小。如果密钥大小为16字节,则选择AES-128-ECB是正确的,否则您必须相应地调整PHP代码(例如,AES-192-ECB或AES-256-ECB分别为24字节或32字节的密钥大小)

假设Java端使用SunJCE提供程序,默认模式为ECB模式,默认填充为PKCS5Padding,即
Cipher.getInstance(“AES”)
Cipher.getInstance(“AES/ECB/PKCS5Padding”)
相同,请参见示例

ECB模式不使用IV。因此,您必须在PHP generate_token-method中替换

$iv = self::hex_to_str("00000000000000000000000000000000");
$token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);

例如:

encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");
提供

fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==
这与PHP代码的结果相同(对于相同的键和纯文本)

通常,如果您有多个块,ECB模式是不安全的(从您的示例中,我推断您的令牌至少由两个块组成)。然后,更好的选择是CBC或GCM模式,参见和。但由于Java加密方法似乎是您的参考,因此可能无法更改它

编辑:


Java cipher类使用keysize自动确定是否必须使用AES-128、AES-192或AES-256。因此,您还必须知道Java代码上下文中键的大小。如果密钥大小为16字节,则选择AES-128-ECB是正确的,否则您必须相应地调整PHP代码(例如,AES-192-ECB或AES-256-ECB分别为24字节或32字节的密钥大小)

对!!AES-128-ECB!非常感谢。你刚刚救了我的命。我尝试了列表中的每个方法。但是我没有注意到还有更多的方法,也没有自己调用openssl\u get\u cipher\u方法。多大的错误啊。再次感谢你,是的!AES-128-ECB!非常感谢。你刚刚救了我的命。我尝试了列表中的每个方法。但是我没有注意到还有更多的方法,也没有自己调用openssl\u get\u cipher\u方法。多大的错误啊。再次谢谢你。