简体   繁体   中英

AES/CBC/PKCS5Padding encryption done both in android and java. Encrypted text does not match

I want to encrypt the password in android application.So i have chosen AES/CBC/PKCS5Padding encryption. Below is my code to do encryption in android. I also need same encryption in php. So i have the code for php also. But the encrypted data done in android is not matching that done with php Please help i'm new to encryption.

    public class AESCrypt {
    private final String characterEncoding = "UTF-8";
    private final String cipherTransformation = "AES/CBC/PKCS5Padding";
    private final String aesEncryptionAlgorithm = "AES";

    public  byte[] bytedecrypt(byte[] cipherText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        Cipher cipher = Cipher.getInstance(cipherTransformation);
        SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec);
        cipherText = cipher.doFinal(cipherText);
        return cipherText;
    }

    public byte[] byteencrypt(byte[] plainText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        Cipher cipher = Cipher.getInstance(cipherTransformation);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        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;
    }


    public String encrypt(String plainText) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{
        byte[] plainTextbytes = plainText.getBytes(characterEncoding);
        byte[] keyBytes = getKeyBytes("9vYJNrqiHifDWGw6X9UHU5h7kBtb8TNB");
        return Base64.encodeToString(byteencrypt(plainTextbytes,keyBytes, keyBytes), Base64.DEFAULT);
    }


    public String decrypt(String encryptedText) throws KeyException, GeneralSecurityException, GeneralSecurityException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException{
        byte[] cipheredBytes = Base64.decode(encryptedText, Base64.DEFAULT);
        byte[] keyBytes = getKeyBytes("9vYJNrqiHifDWGw6X9UHU5h7kBtb8TNB");
        return new String(bytedecrypt(cipheredBytes, keyBytes, keyBytes), characterEncoding);
    }

}

Below is the php code for same encryption

$data_to_encrypt = $out;
$key128 = "9vYJNrqiHifDWGw6X9UHU5h7kBtb8TNB";
$iv = "0000000000000000";

$cc = $data_to_encrypt;
$key = $key128;
$iv =  $iv;
$length = strlen($cc);

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128,'','cbc',$iv);

mcrypt_generic_init($cipher, $key, $iv);
$encrypted = base64_encode(mcrypt_generic($cipher,$cc));
mcrypt_generic_deinit($cipher);

mcrypt_generic_init($cipher, $key, $iv);
$decrypted = mdecrypt_generic($cipher,base64_decode($encrypted));
mcrypt_generic_deinit($cipher);

echo "encrypted: " . $encrypted;
echo "";
echo "length:".strlen($encrypted);
echo "<br />";
echo "decrypted: " . substr($decrypted, 0, $length);

Make sure you are using the same initialVector.

In PHP you are using $iv = "0000000000000000";

But in java instead of initalVector you are passing keyBytes as third parameter.

byteencrypt(plainTextbytes,keyBytes, keyBytes)

mcrypt uses zero padding while you're trying to decode information with PKCS5 on Android. Cipher does not support zero padding. As of PHP 7.1.0 mcrypt is deprecated in favor of OpenSSL.

Additionality, your AES key should not be hard-coded on your client as a hacker can access it easily. Use Android KeyStore .

Secondly, Initialization Vector ( IV ) must be random. After encryption append it at the front of the encrypted message and then retrieve it on the client. There's no need to encrypt it, after encryption it can be public.

Consider using GCM mode, as it supports authentication while CBC by default does not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM