有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

php中java加密方法的转换

下面是用java编写的加密方法,我正试图用php进行转换

public static String encryptWithAesCtrNoPadding(final String key, final String value)
throws IOException {
    try {
        byte[] encKey = Arrays.copyOf(key.getBytes("UTF-8"), 16);
        SecretKeySpec secretKey = new SecretKeySpec(encKey, "AES");
        Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(new byte[16]));
        return Hex.encodeHexString(cipher.doFinal(value.getBytes("UTF-8")));
    } catch (Exception ex) {
        throw new IOException(ex.getMessage());
    }
}

我尝试了几种在线解释的方法,但两个函数的加密值不匹配

下面是到目前为止我得到的最接近的解决方案,但没有得到所需的输出

<?php

function do_encryption(String $key, String $value)
{

    $iv = "0000000000000000"; //base64_encode(openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-128-cbc')));

    $encodedEncryptedData = bin2hex(openssl_encrypt($value, "AES-128-CTR", $key, OPENSSL_RAW_DATA, substr(($iv) , 0, 16)));
}

do_encryption("secret", "1234567890");

?>

非常感谢您为解决此问题提供的任何帮助。谢谢


共 (1) 个答案

  1. # 1 楼答案

    Java的AES CTR实现和PHP OpenSSL的AES CTR实现在使用相同数据(加密密钥、初始化向量和明文)馈送时提供相同的密文

    在下面,您会发现两个程序都使用了不安全的固定IV(出于演示目的)-永远不要在实际程序中使用固定IV

    Java端的结果是:

    ciphertext (hex): 8cddfd68b61265f7d9bb36a058e9405ad15c7797a322ef8c4e4788b5c31508aec8917f7c17234e757d7e38
    

    PHP端的结果也是一样的:

    ciphertext (hex): 8cddfd68b61265f7d9bb36a058e9405ad15c7797a322ef8c4e4788b5c31508aec8917f7c17234e757d7e38
    

    安全警告:以下代码使用静态IV和静态(硬编码)钥匙,仅用于教育目的:

    爪哇:

    import org.apache.commons.codec.binary.Hex;
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.IOException;
    import java.util.Arrays;
    
    public class Main {
        public static void main(String[] args) throws IOException {
    
            String encryptionKey = "1234567890123456";
            String plaintext = "The quick brown fox jumps over the lazy dog";
            String ciphertext = encryptWithAesCtrNoPadding(encryptionKey, plaintext);
            System.out.println("ciphertext (hex): " + ciphertext);
            // result: 8cddfd68b61265f7d9bb36a058e9405ad15c7797a322ef8c4e4788b5c31508aec8917f7c17234e757d7e38
        }
    
        public static String encryptWithAesCtrNoPadding(final String key, final String value)
                throws IOException {
            try {
                byte[] encKey = Arrays.copyOf(key.getBytes("UTF-8"), 16);
                SecretKeySpec secretKey = new SecretKeySpec(encKey, "AES");
                Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
                // ### security warning: never use a STATIC IV ###
                cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(new byte[16]));
                return Hex.encodeHexString(cipher.doFinal(value.getBytes("UTF-8")));
            } catch (Exception ex) {
                throw new IOException(ex.getMessage());
            }
        }
    }
    

    PHP:

    <?php
    function do_encryption(String $key, String $value)
    {
        // ### security warning: never use a STATIC IV ###
        $fixedIv =  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
        //$iv = "0000000000000000"; //base64_encode(openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-128-cbc')));
        $encodedEncryptedData = bin2hex(openssl_encrypt($value, "AES-128-CTR", $key, OPENSSL_RAW_DATA, substr(($fixedIv) , 0, 16)));
        return $encodedEncryptedData;
    }
    $encryptionKey = "1234567890123456";
    $plaintext = "The quick brown fox jumps over the lazy dog";
    $ciphertext = do_encryption($encryptionKey, $plaintext);
    echo 'ciphertext (hex): ' . $ciphertext;
    // result 8cddfd68b61265f7d9bb36a058e9405ad15c7797a322ef8c4e4788b5c31508aec8917f7c17234e757d7e38
    // java   8cddfd68b61265f7d9bb36a058e9405ad15c7797a322ef8c4e4788b5c31508aec8917f7c17234e757d7e38
    ?>