5

您好,我正在开发 android 应用程序,在该应用程序中我需要执行一些 https Web 服务,因此我所有的 Web 服务 URL 和 Web API KEY 都在代码和服务器的 IP 地址中。当任何人对我的应用程序进行逆向工程时,那个人可以获取我的 Web 服务 URL 以及 API KEY,然后可以使用 rest 客户端简单地点击它。

如何确保任何攻击者都无法获得我在strings.xml

<string name="WEB_API_KEY">XXXXXXXXXXXXXXXXXXXXXXXXXXX</string>

提前致谢。

4

5 回答 5

3

我遇到了同样的问题。首先确保这是我创建的应用程序仅调用 Web 服务。即使他们通过崇敬工程获得了钥匙。其次,有效用户正在调用应用程序。以下检查在服务器中完成。

1)验证它确实由谷歌签名。

2)验证它是否真的适合你。

您需要使用 Google 开发者控制台https://console.developers.google.com/project?authuser=0 在 Menu API & auth 下创建两个客户端 ID(一个用于服务器,另一个用于 android 应用程序。)。要为 android 应用程序创建客户端 ID,您可以使用 keytool keytool -exportcert -alias <your-key-name> -keystore <your-key-store-file> -v -list

我已按照此处的步骤进行操作

服务器端 php 示例如下

function checkSession($token){
$result = Array();
if(isset($_SERVER['HTTPS']))
{
    if ($_SERVER["HTTPS"] == "on") 
    {
        $secure_connection = true;
    }
}
if($secure_connection){
try {
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$ticket = $client->verifyIdToken($token);
$validtocken = false;
  if($ticket){
   $token_data = $ticket->getAttributes();
   if($token_data ["payload"]["aud"]==CLIENT_ID &&
      $token_data ["payload"]["azp"]==ANDROID_ID){
       $validtocken = true;
       $result["Email"]=$token_data ["payload"]["email"];
      }
   else  
   { 
    log_message(serialize($token_data)); 
   }
  }
  } catch (Exception $e) {
  $result["Details"]=$e->getMessage();
  }
}
于 2014-12-15T05:36:45.867 回答
1

最好的方法是 在第一次打开应用程序时从服务器接收 web api 密钥

在这种情况下,应用程序将密钥存储在内部存储中,而不是在 apk 中。

于 2014-12-17T05:52:57.947 回答
0

您不能依赖代码中硬编码的内容来识别请求是来自您的应用程序还是来自恶意客户端。您必须做的是让 web 服务在接受任何请求之前需要某种身份验证。一个例子是需要用户名/密码对,或者让 web 服务根据他们的 SSL 证书接受/拒绝客户端。这样,只有授权用户才能使用 Web 服务。

于 2014-10-19T19:43:58.833 回答
0

将 API_KEY 存储在应用程序中并不是一个好主意,它很容易被逆向工程,尤其是在 XML 资源中时。您必须将其放在服务器端,然后调用服务。

App --- Call ---> [Service1.php which has API_KEY ] --- Call --> Payment Service。

App <--- 响应 --- [Service1.php] <--- 响应 ---- 支付服务。

这就像在支付服务和您的应用程序之间有中间件层。像这样,黑客无法拿到钥匙。

于 2014-12-14T12:17:52.543 回答
0

如前所述,仅使用硬编码凭据保护应用程序是不安全的。

我应该建议你使用一些类似登录的结构。您首先要求输入用户名/密码的地方。

然后,您使用在运行时编译的签名构建 API 调用。通过这样做,您永远不需要通过开放的网络发送用户密码。

您可以通过这样的调用来实现这一点:

APIkey = "a specicic APIkey"; //To identify the specifik app "not secret"
Username = "usersname"; //To identify witch user trying to make the call
Request = "you needed request data"; //Your actual requst parameters.
Timestamp = "Current_timestamp";  //Current timestamp user to get unique signatures for every call
Signature = sha256_hash(APIkey + Username + Request + Timestamp + Password); //Signature using the users password(Secret).

然后,您可以通过使用数据库中存储的密码重新编译签名服务器端来验证调用。如果签名匹配,则呼叫应该是真实的。您还应该设置时间限制并拒绝每个旧电话。

注意:您可能需要对其进行调整并将其更改为您的语言的工作代码,但您明白了。

于 2014-12-20T15:46:58.067 回答