如何验证发送 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。
我正在制作一个服务器 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。