【问题标题】:AES CBC 128 bit encryption using Java and PHP使用 Java 和 PHP 的 AES CBC 128 位加密
【发布时间】:2017-03-27 07:53:48
【问题描述】:

我最近在 Java 中使用了 AES CBC 128 算法来加密数据。现在我需要在 PHP 中重建该算法,但我不知道如何,因为互联网上的 PHP 算法返回不同的结果。也许你可以帮助我。

这是要加密的 Java 代码:

private SecretKeySpec secretKey;
private IvParameterSpec ivSpec;

public void setKey(String myKey) {
    MessageDigest sha = null;
    try {
        byte[] key = myKey.getBytes("UTF-8");
        sha = MessageDigest.getInstance("SHA-1");
        key = sha.digest(key);
        key = Arrays.copyOf(key, 16);
        secretKey = new SecretKeySpec(key, "AES");

        byte[] iv = new String("1010101010101010").getBytes("UTF-8");
        ivSpec = new IvParameterSpec(iv);

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}

public String encrypt(String strToEncrypt) {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
        return Base64.encode(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public String decrypt(String strToDecrypt) {
    try {
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
        return new String(cipher.doFinal(Base64.decode(strToDecrypt)));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public static void main(String[] args) {

    AESText aes = new AESText();
    final String secretKey = "com.secure.test.projectjasdS/FjkGkGhkGjhG786Vjfg=tjGFGH";
    aes.setKey(secretKey);

    String originalString = "test set se ts et set s et se";
    String encryptedString = aes.encrypt(originalString);
    String decryptedString = aes.decrypt(encryptedString);

    System.out.println("origin: " + originalString);
    System.out.println("encrypted: " + encryptedString);
    System.out.println("decrypted: " + decryptedString);
}

这是我的 php 代码:

    protected $key;
    protected $method = 'AES-128-CBC';
    protected $iv = '1010101010101010';
    protected $option = OPENSSL_CIPHER_AES_128_CBC;

    function __construct($key)
    {
        $this->key = $key;
    }

    public function encrypt($data) {
        if (is_null($data)) {
            return "Error " . INVALID_PARAMS_ENCRYPTIONS . ": Data is null ";
        }
        $enc = openssl_encrypt($data, $this->method, $this->key, $this->option, $this->iv);
        return base64_encode($enc);
    }

    public function decrypt($data) {
        if (is_null($data)) {
            return "Error " . INVALID_PARAMS_ENCRYPTIONS . ": Data is null ";
        }
        $data = base64_decode($data);
        $dec = openssl_decrypt($data, $this->method, $this->key, $this->option, $this->iv);
        return $dec;
    }

当我从java加密中加密数据时,这个结果在Php解密时无法解密。

你们能帮我建立一个 PHP 脚本,用 java 加密返回相同的结果吗?

【问题讨论】:

    标签: java php cryptography aes php-openssl


    【解决方案1】:

    乍一看,我在这里看到三个问题:

    首先:你没有使用相同的模式:在java中你有AES/ECB/PKCS5Padding,而你的php使用AES-128-CBC

    第二:您可能没有在 Java 和 PHP 代码中使用相同的 IV(IV 与 ECB 无关,但是一旦您将 Java 切换到 CBC,您将需要它):

    您的 php 中有 $iv = '1010101010101010'(然后传递给 openssl),但在您的 java 中没有类似的东西。

    至少,您的 Java 部分可能也需要类似的东西:

    cipher.init(Cipher.DECRYPT_MODE/ENCRYPT_MODE, secretKey, new IvParameterSpec(iv))
    

    iv 是一个包含您的 IV 字节的 byte[]

    第三:一旦上述问题得到解决,填充可能是下一个破坏性的事情:您的 java 密码规范提到了PKCS5Padding。你需要确保你的两个对手都使用相同的。

    编辑:第四:还有一个问题是您派生要使用的密钥位的方式。在 java 中,您获取 sha1-hash 的前 16 个字节,而在 php 中,您只需将 $key 传递给 openssl。 openssl 可能会以不同的方式获取加密密钥。


    在使用分组密码构建与密码学相关的工具时,重温 Wikipedia 上的 Block cipher mode of operationPadding 之类的经典作品总是很不错的,以了解幕后发生的事情。

    【讨论】:

    • 谢谢@Shastick。我是加密初学者。我已经编辑了我的 java 代码。当我在 java 中使用PKCS5Padding 时,它可以工作,但是当我使用NoPadding 时出现错误javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes。但是,当我添加IV 并将ECB 更改为CBCPKCS5Padding 时,java 和php 之间的加密不匹配。你能帮我编辑我的代码吗?
    • 好吧,当输入长度不是 16 的倍数时,填充是用来填充整体的,正如在例外中提到的那样 :) 你可能需要多玩一点并查找一些教程来做对了。
    猜你喜欢
    • 2019-08-17
    • 2020-04-15
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多