的Andr​​oid / Java的AES 256 CBC与PHP PKCS5Padding解密 [英] Android/Java AES 256 CBC with PKCS5Padding decryption in PHP

查看:211
本文介绍了的Andr​​oid / Java的AES 256 CBC与PHP PKCS5Padding解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的Andr​​oid应用程序,然后将它发送到PHP页面进行解密和加密处理一些数据。

I am encrypting some data in my Android application, which is then sent to a PHP page for decryption and treatment.

正在使用的密码是AES / CBC / PKCS5Padding

现在一切工作正常(后四处寻找信息的很多)。
然而,所得到的解密数据具有添加到其不从应用程序发送的原始数据存在结束了一些新的线路。

Everything works fine now (after alot of digging around for info). However, the resulting decrypted data has a number of new lines added to the end which do not exist in the original data sent from the application.

我presuming这是的PHP不支持PKCS5Padding的副作用。
我不舒服的假设最终总会有附加到字符串换行或空格。

I am presuming that this is a side effect of PHP not supporting PKCS5Padding. I am uncomfortable assuming that the end will always have newlines or spaces appended to the string.

如果我尝试使用的mcrypt提出的code文档,加密缓冲区被清空。

If I try to use the code proposed in the mcrypt docs, the encrypted buffer is emptied.

有没有更好的解决方法去填充?

Is there a better workaround for unpadding ?

修改:code添加为每个请求

Edit : code added as per request

PHP

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, "", MCRYPT_MODE_CBC, "");
if($cipher === false)
{
    trigger_error("AES compatible cipher missing", E_USER_WARNING);
    exit;
}
$InitResult = mcrypt_generic_init($cipher, $AesPassword, $AesIv);
if($InitResult !== 0)
{
    trigger_error("AES cipher init failed", E_USER_WARNING);
    exit;
}
// now do the decryption
$DataBlock = mdecrypt_generic($cipher, $EncryptedBlock);
// close down mcrypt
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

的Andr​​oid / Java的:

Android/Java :

String strEncrypted = null;
Cipher cipher = null;
IvParameterSpec ivSpec = null;
byte[] btEncrypted = null;

try
{
    cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    ivSpec = new IvParameterSpec(m_btIV);

    cipher.init(Cipher.ENCRYPT_MODE, m_KeySpec, ivSpec);
    btEncrypted = cipher.doFinal(strData.getBytes(m_strCharSet));
    strEncrypted = Base64.encodeToString(btEncrypted, Base64.NO_PADDING | Base64.NO_WRAP);
}
catch(Exception e)
{
    e.printStackTrace();
}

return strEncrypted;

请注意,关键以及iv Android中被计算,并在POST数据发送到服务器

Note that the key and iv are calculated in Android and transmitted in the POST data to the server.

这是否帮助?

推荐答案

不幸的是,Java SE的供应商不支持PHP填充。充气城堡不支持这种填充无论是作为充气城堡总是至少有1个字节垫,即使是零填充。

Unfortunately the Java SE providers do not support PHP padding. Bouncy Castle does not support this kind of padding either as Bouncy Castle always pads with at least 1 byte, even for zero padding.

所以经过大量的调整,这是最好的,我可以想出:

So after a lot of tweaking, this is the best I can come up with:

/**
 * Pads data with zero valued bytes until the next block boundary is met.
 * Does not pad if the number of blocks is already on a boundary. This
 * method is not safe for binary data that may end with zero valued bytes as
 * they may be removed by the unpadding method.
 * If available, try and use PKCS#7 compatible padding instead.
 * 
 * @param data
 *            the binary data to pad, never null
 * @param blocksize
 *            the block size in bytes of the block cipher
 * @return the padded binary data as a copy
 * @throws NullPointerException
 *             if data is null
 */
public static byte[] phpPad(final byte[] data, final int blocksize) {
    if (data.length == 0) {
        return data;
    }

    final int blocks = (data.length - 1) / blocksize + 1;
    return Arrays.copyOf(data, blocks * blocksize);
}

/**
 * Unpads data removing zero valued bytes, removing up to blocksize - 1
 * bytes of padding. The input of the unpad method should consist of n times
 * the blocksize.
 * 
 * @param data
 *            the binary data to unpad, never null
 * @param blocksize
 *            the block size in bytes of the block cipher
 * @return the unpadded binary data as a copy
 * @throws NullPointerException
 *             if data is null
 * @throws IllegalArgumentException
 *             if the data is not n times the blocksize
 */
public static byte[] phpUnpad(final byte[] data, final int blocksize) {
    if (data.length % blocksize != 0) {
        throw new IllegalArgumentException(
                "Padded data should dividable by the block size");
    }

    if (data.length == 0) {
        return data.clone();
    }

    int padBytes = 0;
    for (; padBytes < blocksize; padBytes++) {
        if (data[data.length - padBytes - 1] != 0x00) {
            break;
        }
    }

    return Arrays.copyOf(data, data.length - padBytes);
}

这篇关于的Andr​​oid / Java的AES 256 CBC与PHP PKCS5Padding解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆