我正在制作一个服务器API,它会将一些机密密钥返回给我的应用程序。
然后,应用程序将使用这些键执行特定操作。我将通过SSL发送密钥,以便任何中间人攻击都无法读取它们。
首先,我将首先看到包名称的所有内容,然后我还要验证确保我的应用程序未经过反编译和重新编译并且包不是假的。
基本上我想避免这些问题:
1)有人没有创建假包名然后发送请求2)有人没有重新编译我的应用程序然后发送请求3)如果没有通过MIM跟踪服务器的响应,有人
到目前为止,我认为最好的方法是使用HASH密钥然后在我的服务器中进行比较,看看POST密钥是否与存储在我的服务器中的密钥相同。
但我无法找到附加到应用程序签名密钥的密钥,而且任何拥有我的应用程序APK的人都无法访问该密钥。
任何帮助将不胜感激。
如果使用android的NDK
库中提供的C ++代码在应用程序中创建密钥,则可以添加额外的保护层。这是一个惊人的tutorial。基本上,这可以保护您的应用程序免受反编译工具的影响,这些工具通常会反编译java文件。另外,我建议在通过SSL服务器的post请求发送之前在密钥上添加AES encryption。
在你的onCreate()
方法中,从本机C ++实现中获取密钥:
String nativeKey = invokeNativeFunction()
然后加密它:
byte[] keyStart = nativeKey.getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
// encrypt
byte[] encryptedData = encrypt(key,b);
加密方法:
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
编辑CSRF
:
这里有一个有趣的答案:Authenticity_token in Rails + Android,也在Wikipedia,有很多关于如何反击跨站请求伪造的建议。包括:
Synchronizer token pattern
Cookie-to-header token
仅举几例。
这里有一层额外的安全性来识别authenticity of the app request。