使用LVL和AESObfuscator可以解决可怕的SecretKeyFactory性能问题吗?

nbl*_*ike 9 performance android android-lvl

我想在Android Marketplace中使用新的许可(LVL),但是我遇到了AESObfuscator的性能问题.具体来说,构造函数需要几秒钟才能在设备上运行(仿真器上的纯粹痛苦).由于此代码需要运行以检查缓存的许可证响应,因此在启动时检查许可证会严重阻碍.

运行LVL示例应用程序,这是我对AESObfuscator构造函数的野蛮风格分析:

public AESObfuscator(byte[] salt, String applicationId, String deviceId) {
        Log.w("AESObfuscator", "constructor starting");
        try {
            Log.w("AESObfuscator", "1");
            SecretKeyFactory factory = SecretKeyFactory.getInstance(KEYGEN_ALGORITHM);
            Log.w("AESObfuscator", "2");
            KeySpec keySpec =
                new PBEKeySpec((applicationId + deviceId).toCharArray(), salt, 1024, 256);
            Log.w("AESObfuscator", "3");
            SecretKey tmp = factory.generateSecret(keySpec);
            Log.w("AESObfuscator", "4");
            SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
            Log.w("AESObfuscator", "5");
            mEncryptor = Cipher.getInstance(CIPHER_ALGORITHM);
            Log.w("AESObfuscator", "6");
            mEncryptor.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(IV));
            Log.w("AESObfuscator", "7");
            mDecryptor = Cipher.getInstance(CIPHER_ALGORITHM);
            Log.w("AESObfuscator", "8");
            mDecryptor.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(IV));
        } catch (GeneralSecurityException e) {
            // This can't happen on a compatible Android device.
            throw new RuntimeException("Invalid environment", e);
        }
        Log.w("AESObfuscator", "constructor done");
    }
Run Code Online (Sandbox Code Playgroud)

Nexus One的输出:

09-28 09:29:02.799: INFO/System.out(12377): debugger has settled (1396)
09-28 09:29:02.988: WARN/AESObfuscator(12377): constructor starting
09-28 09:29:02.988: WARN/AESObfuscator(12377): 1
09-28 09:29:02.999: WARN/AESObfuscator(12377): 2
09-28 09:29:02.999: WARN/AESObfuscator(12377): 3
09-28 09:29:09.369: WARN/AESObfuscator(12377): 4
09-28 09:29:09.369: WARN/AESObfuscator(12377): 5
09-28 09:29:10.389: WARN/AESObfuscator(12377): 6
09-28 09:29:10.398: WARN/AESObfuscator(12377): 7
09-28 09:29:10.398: WARN/AESObfuscator(12377): 8
09-28 09:29:10.409: WARN/AESObfuscator(12377): constructor done
09-28 09:29:10.409: WARN/ActivityManager(83): Launch timeout has expired, giving up wake lock!
09-28 09:29:10.458: INFO/LicenseChecker(12377): Binding to licensing service.
Run Code Online (Sandbox Code Playgroud)

颠簸7秒(模拟器中大约20秒,呃).我可以在AsyncTask上关闭它,但它在那里做得不多,因为在我验证许可证之前,应用程序无法真正运行.我得到的只是一个漂亮的,漂亮的7秒进度条,而用户等待我查看许可证.

有任何想法吗?使用比AES更简单的东西来滚动我自己的混淆器以缓存我自己的许可证响应?

nbl*_*ike 6

经过广泛的搜索和修改,我最好的解决方法似乎是自己创建AES密钥,而不是在PBEKeySpec中使用PKCS#5代码.我有点惊讶其他人没有发布这个问题.

解决方法是将一堆标识数据(设备ID,IMEI,包名等)组合成一个字符串.然后,我取该字符串的SHA-1哈希值,得到20字节的24字节AES密钥.不可否认,没有像PKCS#5那样多的熵,并且知道密钥的4个字节.但是,真的,谁将要进行加密攻击?虽然我还试图强化它,但它仍然很有声音并且LVL中有更弱的攻击点.

由于即使创建AES密码似乎也是一个昂贵的(模拟器上2秒)操作,我也推迟创建加密器和解密器成员,直到调用混淆和反混淆需要它们为止.当应用程序使用缓存许可证响应时,它不需要加密器; 这样可以减少最常见的启动模式.

我的新构造函数如下.如果有人想要整个源文件,请给我留言.

   /**
    * @param initialNoise device/app identifier. Use as many sources as possible to
    *    create this unique identifier.
    */
   public PixieObfuscator(String initialNoise) {
        try {
            // Hash up the initial noise into something smaller:
            MessageDigest md = MessageDigest.getInstance(HASH_ALGORITHM);
            md.update(initialNoise.getBytes());
            byte[] hash = md.digest();

            // Allocate a buffer for our actual AES key:
            byte[] aesKEY = new byte[AES_KEY_LENGTH];   

            // Fill it with our lucky byte to take up whatever slack is not filled by hash:
            Arrays.fill(aesKEY, LUCKY_BYTE);

            // Copy in as much of the hash as we got (should be twenty bytes, take as much as we can):
            for (int i = 0; i < hash.length && i < aesKEY.length; i++)
                aesKEY[i] = hash[i];

            // Now make the damn AES key object:
              secret = new SecretKeySpec(aesKEY, "AES");
        }
        catch (GeneralSecurityException ex) {
            throw new RuntimeException("Exception in PixieObfuscator constructor, invalid environment");
        }
   }
Run Code Online (Sandbox Code Playgroud)