Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将PHP Rijndael算法重写为Java(Android)_Java_Php_Android_Aes_Rijndael - Fatal编程技术网

将PHP Rijndael算法重写为Java(Android)

将PHP Rijndael算法重写为Java(Android),java,php,android,aes,rijndael,Java,Php,Android,Aes,Rijndael,我需要用Java和php编码一个字符串,结果必须相同 给出了以下条件: 算法:RIJNDAEL-128 钥匙:5P443M2Q1R9A7F5R3ME1Z08642 模式:欧洲央行 初始化向量:不适用(因为我们使用ECB,IV被忽略) 要编码的字符串:201412181656005P443m2Q1R9A7f5r3e1z08642 PHP 输出:WD0FHYPLBGDPHchSQL7VVCIKWJWN5HVP0W9F4SGKWAWEDCSJVFKWTM5LHBCZJSRW 更新: 我将填充从NoPa

我需要用Java和php编码一个字符串,结果必须相同

给出了以下条件:

  • 算法:RIJNDAEL-128
  • 钥匙:5P443M2Q1R9A7F5R3ME1Z08642
  • 模式:欧洲央行
  • 初始化向量:不适用(因为我们使用ECB,IV被忽略)
  • 要编码的字符串:201412181656005P443m2Q1R9A7f5r3e1z08642

    PHP 输出:WD0FHYPLBGDPHchSQL7VVCIKWJWN5HVP0W9F4SGKWAWEDCSJVFKWTM5LHBCZJSRW 更新: 我将填充从
    NoPadding
    更改为
    PKCS5Padding

    这是正确的吗?我不确定,因为如果你看PHP代码。没有指定任何填充(我自己基于语法的假设)

    其他见解:
    阅读有关填充(无填充)的内容。一定与问题有关。

    看起来您的PHP版本使用AES-128,根据定义,AES-128使用128位(16字节)密钥。但是,看起来您传入了一个25字节的键(
    5P443m2Q1R9A7f5r3e1z08642
    ),我不确定发生这种情况时PHP会做什么

    Java版本的getKeyBytes()方法只返回所提供密钥的前16个字节,因此它只使用该字节进行加密

    尝试将PHP版本中的键截断为
    5P443m2Q1R9A7f5r
    ,您将得到相同的结果。除了可能不同的端部。在这一点上,问题将是填充。您可以在明文上应用
    pkcs5\u pad
    PHP函数,使其与Java版本匹配


    所有这些都说明,如果这只是为了学习,那也没关系。否则,为了实际使用,您必须修改。

    我更改了
    byte[]keyBytes=new byte[16]
    to
    byte[]keyBytes=新字节[32]
    getKeyBytes
    方法中,它工作得很好。

    当我尝试运行您的代码时,出现以下异常:
    javax.crypto.IllegalBlockSizeException:com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1016)上的输入长度不是16字节的倍数
    AES/Rijndael平台之间的兼容性确实很难。注意块大小,您需要对其进行填充,并确保填充到最接近的整除值16。请注意,当AES iv大小为16字节时,您正在创建一个32字节的iv。最好不要使用mcrypt,它是弃用软件,多年来未更新,并且不支持标准PKCS#7(née PKCS#5)填充,只有非标准的空填充,甚至不能用于二进制数据。mcrypt在2003年就有很多杰出的作品。。取而代之的是考虑使用,它是维护和正确的。
     <?php
            class Cipher
            {
                private $securekey, $iv;
    
                function __construct($textkey)
                {
                    $this->securekey = $textkey;
                    $this->iv = mcrypt_create_iv(32);
                }
    
                function encryptR($input)
                {
                    $enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->securekey, $input, MCRYPT_MODE_ECB, $this->iv);
                    return base64_encode($enc);
                }
    
                function decryptR($input)
                {
                    return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->securekey, base64_decode($input), MCRYPT_MODE_ECB, $this->iv));
                }
            }
    
            $raw_text = '201412181656005P443m2Q1R9A7f5r3e1z08642';
            $secretKey = '5P443m2Q1R9A7f5r3e1z08642';
    
            $cipher = new Cipher($secretKey);
            $encrypted = $cipher->encryptR($raw_text);     
    ?>
    
    encrypted = encrypt("201412181656005P443m2Q1R9A7f5r3e1z08642","5P443m2Q1R9A7f5r3e1z08642");
    
    public class Crypt {
    
        private final String characterEncoding = "UTF-8";
        private final String cipherTransformation = "AES/ECB/PKCS5Padding";
        private final String aesEncryptionAlgorithm = "AES";
    
        public  byte[] decrypt(byte[] cipherText, byte[] key) throws Exception
        {
            Cipher cipher = Cipher.getInstance(cipherTransformation);
            SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy);
            cipherText = cipher.doFinal(cipherText);
            return cipherText;
        }
    
        public byte[] encrypt(byte[] plainText, byte[] key) throws Exception
        {
            Cipher cipher = Cipher.getInstance(cipherTransformation);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            plainText = cipher.doFinal(plainText);
            return plainText;
        }
    
        private byte[] getKeyBytes(String key) throws UnsupportedEncodingException{
            byte[] keyBytes= new byte[16];
            byte[] parameterKeyBytes= key.getBytes(characterEncoding);
            System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
            return keyBytes;
        }
    
        @SuppressLint("NewApi")
        public String encrypt(String plainText, String key) throws Exception {
            byte[] plainTextbytes = plainText.getBytes(characterEncoding);
            byte[] keyBytes = getKeyBytes(key);
            // Log.i("iv", ""+keyBytesIV);
            return Base64.encodeToString(encrypt(plainTextbytes,keyBytes), Base64.DEFAULT);
        }
    
        @SuppressLint("NewApi")
        public String decrypt(String encryptedText, String key) throws Exception {
            byte[] cipheredBytes = Base64.decode(encryptedText, Base64.DEFAULT);
            byte[] keyBytes = getKeyBytes(key);
    
            return new String(decrypt(cipheredBytes, keyBytes), characterEncoding);
        }
    
    }