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

前端之家收集整理的这篇文章主要介绍了将PHP Rijndael算法重写为Java(Android)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要在 JavaPHP中编码一个字符串,其结果必须相同.

给出以下条件:

>算法:RIJNDAEL-128
>键:5P443m2Q1R9A7f5r3e1z08642
>模式:ECB
>初始化向量:N / A(因为我们使用的是ECB,所以忽略了IV)

要编码的字符串:201412181656005P443m2Q1R9A7f5r3e1z08642

PHP

<?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,base64_decode($input),$this->iv));
            }
        }

        $raw_text = '201412181656005P443m2Q1R9A7f5r3e1z08642';
        $secretKey = '5P443m2Q1R9A7f5r3e1z08642';

        $cipher = new Cipher($secretKey);
        $encrypted = $cipher->encryptR($raw_text);     
?>

输出:MbDHhIanWgySlMTOX ItgVKudVLXbtj7ig2GMQacVM9JhyAPvVQxLJnHpEj / vhqW

JAVA

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,keyBytes,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,characterEncoding);
    }

}

输出:wd0FHYpLbgdpHhcsql7VVCiKWJWN5hvP0W9F4sgKWAWeDcSjvfKWTM5LHBCZJSRw

更新:

我将填充从NoPadding更改为PKCS5Padding

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

Info on Mcrypt

额外洞察力:

阅读此document关于填充(无填充).一定是和这个问题有关.

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

您的Java版本的getKeyBytes()方法仅返回提供的密钥的前16个字节,因此仅使用它加密.

尝试将PHP版本中的密钥截断为5P443m2Q1R9A7f5r,您将得到相同的结果.除了可能不同的末端部分.那时,问题就是填充.您可以在明文上应用pkcs5_pad PHP函数,使其与您的Java版本匹配.

所有这一切,如果这只是为了学习目的,那没关系.否则,对于实际使用,重要的是你do not use ECB cipher mode.

猜你在找的PHP相关文章