Android 如何高效地调用AES/ECB 64k次?

Android 如何高效地调用AES/ECB 64k次?,android,performance,encryption,cryptography,aes,Android,Performance,Encryption,Cryptography,Aes,我正在为MEGA(这个奇怪的人的云站点)开发一个图书馆。如果我没有弄错,他们通过以下方式从用户密码中派生AES主密钥: 使用UTF-8密码编码作为起始序列 通过追加0展开s,使其长度为16的倍数 将128位主密钥pkey设置为修复初始向量 在64k轮中的每一轮中: 对于s AES/ECB的每个128位块s[i],使用s[i]作为密钥加密k 总而言之,对于一个28个字符的密码,我必须给AES打128k的电话。我的实现结果相当缓慢。比如:“见鬼,那太长了。” DDMS向我显示GC正在运行。如

我正在为MEGA(这个奇怪的人的云站点)开发一个图书馆。如果我没有弄错,他们通过以下方式从用户密码中派生AES主密钥:

  • 使用UTF-8密码编码作为起始序列
  • 通过追加0展开s,使其长度为16的倍数
  • 将128位主密钥pkey设置为修复初始向量
  • 在64k轮中的每一轮中:
    • 对于s AES/ECB的每个128位块s[i],使用s[i]作为密钥加密k
总而言之,对于一个28个字符的密码,我必须给AES打128k的电话。我的实现结果相当缓慢。比如:“见鬼,那太长了。”

DDMS向我显示GC正在运行。如何让AES实现在内部完成所有这些任务,或者至少更有效地完成这些任务?每次调用都会创建一个新的字节数组,然后将其丢弃。有什么办法可以做到这一点吗

public static byte[] calculatePasswordKey(String password) {
    Log.v(TAG, ">calculatePasswordKey");

    byte[] pw = password.getBytes();
    byte[] pkey = {(byte)0x93, (byte)0xC4, 0x67, (byte)0xE3, 0x7D, (byte)0xB0, (byte)0xC7, (byte)0xA4, (byte)0xD1, (byte)0xBE, 0x3F, (byte)0x81, 0x01, 0x52, (byte)0xCB, 0x56};

    //expand by appending 0s
    Log.v(TAG, Arrays.toString(pw));
    if ((pw.length & 0xf0) != 0) {
        int l = (pw.length & 0xf0) + 0x10;
        byte[] paddedpw = new byte[l];
        System.arraycopy(pw, 0, paddedpw, 0, pw.length);
        pw = paddedpw;
        Log.v(TAG, Arrays.toString(pw));
    }

    try {
        //create ciphers only once
        Cipher[] ciphers = new Cipher[pw.length / 16];
        Log.v(TAG, "Creating " + ciphers.length + " AES ciphers");
        for (int cIndex = 0; cIndex < ciphers.length; cIndex++) {
            ciphers[cIndex] = getAesEcbCipher();
            ciphers[cIndex].init(Cipher.ENCRYPT_MODE, new SecretKeySpec(pw, cIndex * 16, 16, "AES"));
        }

        Log.v(TAG, "Beginning 65536 rounds of AES encryption");
        for (int round = 0; round < 65536; round--) {
            for (Cipher c: ciphers) {
                pkey = c.update(pkey);
                if (pkey.length != 16) {
                    throw new Error("update does not work, revert to doFinal()");
                }
            }
        }
        return pkey;
    } catch (Exception e) {
        Log.e(TAG, "Cannot calculate password key: " + e.getMessage());
        e.printStackTrace();
    }
    return null;
}
公共静态字节[]calculatePasswordKey(字符串密码){
Log.v(标记“>calculatePasswordKey”);
字节[]pw=密码。getBytes();
字节[]pkey={(字节)0x93,(字节)0xC4,0x67,(字节)0xE3,0x7D,(字节)0xB0,(字节)0xC7,(字节)0xA4,(字节)0xD1,(字节)0xBE,0x3F,(字节)0x81,0x01,0x52,(字节)0xCB,0x56};
//通过追加0展开
Log.v(TAG,array.toString(pw));
如果((pw.length&0xf0)!=0){
intl=(pw.length&0xf0)+0x10;
字节[]paddedpw=新字节[l];
系统阵列拷贝(pw,0,paddedpw,0,pw.length);
pw=填充pw;
Log.v(TAG,array.toString(pw));
}
试一试{
//只创建一次密码
密码[]密码=新密码[pw.length/16];
Log.v(标记“创建”+密码.length+“AES密码”);
for(int-cIndex=0;cIndex
非常感谢,
沃尔克

出于存档目的,我写下我的评论作为回答,因为其中一些评论可能对将来的人有用


问题是第二个for循环中的
计数--
。它应该是一个
count++
。实际上,代码正在执行2^31轮,即2147483648轮,而不是所需的65536轮。

Uhm。我想知道“PKDBF-2”是否有意义^^一点建议:至少暂时不要使用MEGA。目前,它使用的加密机制在任何程度上都不安全。我希望如此。不幸的是,看起来他们必须创建自己的密钥派生,而不是使用已建立的东西。在我看来,这和PKDBF完全不同。@Eric thx。虽然我真的不喜欢Kim,但多年来我一直渴望基于客户端的加密云。在我看来,所有问题都源于MEGA使用从服务器加载的javascript。使用强加密库的Android应用程序应该可以解决这些问题,至少如果您从未使用javascript站点(包括注册)。您确定
for(int round=0;round<65536;round--)中的
轮--