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

Posted

技术标签:

【中文标题】如何验证发送 POST 请求的应用的身份【英文标题】:How to verify the identity of the app sending an POST request 【发布时间】:2019-07-04 20:42:10 【问题描述】:

我正在制作一个服务器 API,它将向我的应用返回一些机密密钥。

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

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

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

1) 有人没有创建一个虚假的包名然后发送请求 2)有人没有重新编译我的应用程序然后发送请求 3) 如果有人没有通过 MIM 跟踪服务器的响应

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

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

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

如果您使用 androidNDK 库中提供的 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。

【讨论】:

感谢您的回答。不知道为什么有人对答案投了反对票。但实际上我还需要验证发送 POST 的应用程序的身份,以验证它只是我发送请求的原始应用程序。是否有任何密钥,可能是我的证书密钥,只能由我的应用程序在运行时检索并附加到 POST 请求,然后我的服务器验证密钥。但是密钥不应该被任何人访问,例如 root 用户或拥有我的 apk 的用户。请帮忙。 这部分实现起来有点棘手。如果您的应用中有用户,最好实现access_tokens 以确保应用用户只能访问您的应用。然后将该访问令牌也包含在您的发布请求中 谢谢,但我不能将访问令牌分配给我的用户,因为他们是使用该应用程序的普通用户。我的 API 将用于检测欺诈用户,然后根据返回的密钥类型。还有什么办法吗?可能正在使用签名证书? 谢谢。我已接受您的回答,因为我认为这是最好的解决方案。 感谢您的链接。看起来很有用。您能否将该链接添加到答案中,其他人也可能会从中受益。

以上是关于如何验证发送 POST 请求的应用的身份的主要内容,如果未能解决你的问题,请参考以下文章

POST 请求的身份验证错误:“未提供身份验证凭据”使用 Axios,但使用 POSTMAN 工作

Spring Security 通过 post 对用户进行身份验证

如何管理从本地移动应用程序调用 Play2!-Scala REST 服务发送的用户请求的身份验证/授权

Invoke-RestMethod:发送到标头时找不到请求的身份验证数据

如何在 ASP.Net 中为一组 Web 请求发送身份验证标头

如何使用python请求将经过身份验证的POST请求编码到API?