AES 使用来自 JavaScript 代码的 android 加密

AES encrypt with android from JavaScript code

我必须在 Android 中模拟和 JavaScript 代码来执行 AES 加密和解密,但我的 Android 代码不能像 JavaScrip 代码一样工作。

我必须按照 JavaScript 中的代码执行相同的操作:

<html>
<head>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/pad-zeropadding-min.js"></script>    
<!-- jquery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<div id="0"></div>
<div id="1"></div>
<div id="2"></div>
<div id="3"></div>
<div id="4"></div>
<script>
var key = CryptoJS.enc.Utf8.parse('a5240ba5b7cbde89e8075db30138ce64');
var iv  = CryptoJS.enc.Utf8.parse('1ec9b4a4767e582b8a1e3dcad1782f80');
var message = "message";
$('#0').text("Message: "+message);
var encrypted = CryptoJS.AES.encrypt(message, key, { iv: iv, padding: CryptoJS.pad.ZeroPadding, mode: CryptoJS.mode.CBC});
$('#1').text("Encrypted BASE64: "+encrypted);
$('#2').text("Encrypted HEX: "+encrypted.ciphertext);

var decrypted = CryptoJS.AES.decrypt(encrypted,key, { iv: iv, padding: CryptoJS.pad.ZeroPadding, mode: CryptoJS.mode.CBC});
$('#3').text("Decrypted HEX: "+decrypted);
$('#4').text("Decrypted TEXT: "+decrypted.toString(CryptoJS.enc.Utf8));
</script>
</body>
</html>

我必须使用 bouncycastle lib 来完成它,因为如您所见,IV 的长度为 32 字节,我这样做了,但我的代码 return 与此 JavaScript 代码不同。有人知道我在 android 代码中做错了什么吗?

这是 android 代码:

private static final String ZERO_PADDING_KEY = "a5240ba5b7cbde89e8075db30138ce64";
private static final String IV = "1ec9b4a4767e582b8a1e3dcad1782f80";
public String encryptURL(String url) {
    try {
        Hex hex = new Hex();

        byte[] key = ZERO_PADDING_KEY.getBytes("UTF-8");
        byte[] iv = IV.getBytes("UTF-8");

        PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
        c.init(true, new ParametersWithIV(new KeyParameter(key), iv));

        byte[] res = cipherData(c, url.getBytes("UTF-8"));
        String resul = bytesToHex(res);

        return resul;
    } catch (Exception e) {
        Log.e("ENCRYPT ERROR", e.getMessage());
        e.printStackTrace();
    }
    return "";
}

public String decryptUrl(String encrypted) {
    try {
        Hex hex = new Hex();
        byte[] key = ZERO_PADDING_KEY.getBytes("UTF-8");
        byte[] iv = IV.getBytes("UTF-8");


        PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
        c.init(false, new ParametersWithIV(new KeyParameter(key), iv));

        byte[] decryptedText = cipherData(c, (byte[]) hex.decode(encrypted));
        String decrypted = new String(decryptedText, "UTF-8");
        Log.d("DECRYPTED", decrypted);

        return decrypted;
    } catch (Exception e) {
        try {
            throw new CryptoException("Unable to decrypt", e);
        } catch (CryptoException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
    return "";
}

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws Exception {

    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] result = new byte[actualLength];
    System.arraycopy(outBuf, 0, result, 0, result.length);
    return result;
}

public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    for (int j = 0; j < bytes.length; j++) {
        int v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}

您的 Android 代码中有 new RijndaelEngine(256)。它是块大小为 256 的 Rijndael。CryptoJS 仅支持 AES,即块大小为 128 的 Rijndael。

由于 CryptoJS 仅支持块大小为 128 的 AES,因此 IV 大小也必须为 128。您应该将 IV 解析为 Hex。 CryptoJS 似乎并不介意传递更大的 IV。在 CryptoJS 中:

var iv = CryptoJS.enc.Hex.parse('1ec9b4a4767e582b8a1e3dcad1782f80');

并且在 Android 中,您可以使用代码中已有的十六进制 class。

如果你不想更改 JavaScript 代码,你可以只使用 Android 中 IV 的前 128 位(我怀疑这是 CryptoJS 所做的,但不能'验证一下):

byte[] iv = Arrays.copyOf(IV.getBytes("UTF-8"), 16);