现在注册的账号特别多,但是为了安全起见又不能把每个账号的密码都设置的一样,不然泄露了一个,其他账号也会沦陷。所以,出现了很多帮助我们记录账号和密码的软件,而且通常需要一个主秘钥来加密解密这些账号和密码。这一次逆向经历是源于我把主秘钥忘记了,希望逆向找到主密钥存储位置。
该APK非常小,不超过3m;使用的工具还是JEB225。
首先找到应用入口。
因为APP进入主页面后,会要求先输入主密钥,所以这里一定会有关于主密钥的处理逻辑。找到相应editText传入的字符串,跟踪。
发现它对主密钥做了如下处理:
public static String Decryption(String arg3, String arg4) {
return new String(d.b(d.getMD5(arg3).substring(0, 16).getBytes(), Base64.decode(arg4, 2)));
}
public static String getMD5(String arg2) {
String v0_2;
try {
byte[] v0_1 = arg2.getBytes();
MessageDigest v1 = MessageDigest.getInstance("MD5");
v1.update(v0_1);
v0_2 = new String(d.a(v1.digest()));
}
catch(Exception v0) {
v0.printStackTrace();
v0_2 = null;
}
return v0_2;
}
private static void a(StringBuffer arg3, byte arg4) {
arg3.append("0123456789abcdef".charAt(arg4 >> 4 & 15)).append("0123456789abcdef".charAt(arg4 & 15));
}
private static byte[] AESdecryption(byte[] arg3, byte[] arg4) {
SecretKeySpec v0 = new SecretKeySpec(arg3, "AES");
Cipher v1 = Cipher.getInstance("AES/ECB/PKCS5Padding");
v1.init(2, ((Key)v0));
return v1.doFinal(arg4);
}
可以看出它将主密钥先进行了MD5计算,截取了前16个字符,再转化为字节。而arg4通过cross-Reference发现是被加密的账号和密码,这里先用Base64反编码回来,再转成字节。然后将转化后的主密钥作为密钥,arg4作为解密数据,进行AES解密。
也就是说,当用户输入一个主密钥后,它直接用于去解密以前加密的数据,完全没有与任何数据匹配。这时我又新建了一个主密钥,然后记录了一个账号和密码,发现它果然没有记录任何关于主密钥的信息,还是按照上面的流程 MD5(mainKey),subString(0, 16).getBytes() 作为密钥, Base64.encode(accountInfo)作为加密数据,进行了AES加密计算,最后进记录加密后的信息。
所以总的来说,该密码管理APP不会记录你的主密钥。它以主密钥为密钥对你记录的数据进行AES加密,这些加密的数据还可以备份,以后必须提供相同的主密钥才能解密,所以我找不到主密钥了...