如何验证发送 POST 请求的应用程序的身份

How to verify the identity of the app sending an POST request

我正在制作一个服务器 API,它将 return 我的应用程序的一些机密密钥。

然后应用程序将使用这些键来执行特定的操作。我会通过 SSL 发送密钥,这样任何中间人攻击都无法读取它们。

首先,我将首先是包名,然后我还想验证一些东西,以确保我的应用程序没有被反编译和重新编译,并且包不是假的。

基本上我想避免这些问题:

1) 有人没有创建假包名然后发送请求 2)有人没有重新编译我的应用程序然后发送请求 3) 有人如果没有通过 MIM

跟踪服务器的响应

到目前为止,我认为最好的方法是使用 HASH 密钥,然后在我的服务器中比较它,看看 POST 密钥是否与我服务器中存储的相同。

但我一直无法找到附加到应用程序签名密钥的密钥,任何拥有我应用程序 APK 的人都无法访问该密钥。

任何帮助将不胜感激。

如果您使用 android 的 NDK 库中提供的 C++ 代码在您的应用程序中创建密钥,则可以添加额外的保护层。在通过您的 SSL 服务器的 post 请求发送之前,您的密钥上有一个惊人的 tutorial for that. Basically, this protects your app from de-compiling tools which commonly de-compiles java files. Also, I recommend adding 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, also on Wikipedia,关于如何应对跨站请求伪造,有很多建议。其中包括:

Synchronizer token pattern
Cookie-to-header token

仅举几例。

这里还有一层额外的安全措施来识别 authenticity of the app request