您好我正在开发Android应用程序,其中我需要执行一些https Web服务,因此我的所有webservice URL和Web API KEY都在代码加上服务器的IP地址。当任何人对我的应用程序进行逆向工程时,那个人可以获得我的Web服务URL以及API KEY,然后可以使用rest client点击它。
如何确保任何攻击者都无法获得我在strings.xml
<string name="WEB_API_KEY">XXXXXXXXXXXXXXXXXXXXXXXXXXX</string>
提前致谢。
答案 0 :(得分:3)
我遇到了同样的问题。 首先要确保这是我创建的应用程序仅调用Web服务。即使他们通过崇敬工程获得关键。 其次,有效用户正在调用该应用程序。 以下检查在服务器中完成。
1)确认它真的由Google签名。
2)确认它真的适合你。
您需要使用Google开发者控制台https://console.developers.google.com/project?authuser=0
在Menu API&amp;下创建两个Client Ids(一个用于服务器,另一个用于android应用程序。) AUTH。
要为Android应用程序创建客户端ID,您可以使用keytool
keytool -exportcert -alias <your-key-name> -keystore <your-key-store-file> -v -list
我已按照here
中的步骤操作Serverside 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();
}
}
答案 1 :(得分:1)
最好的方法是 首次打开应用时从服务器接收网络API密钥。
在这种情况下,app将内存存储的密钥存储在apk中。
答案 2 :(得分:0)
您不能依赖代码中的硬编码来识别请求是来自您的应用还是来自流氓客户端。您必须做的是在接受任何请求之前使Web服务需要某种身份验证。一个示例是需要用户名/密码对,或者使Web服务基于其SSL证书接受/拒绝客户端。这样只有授权用户才能使用网络服务。
答案 3 :(得分:0)
将API_KEY存储在应用程序中并不是一个好主意,它可以很容易地进行逆向工程,尤其是在XML资源中。您必须将它放在服务器端,然后调用服务。
App --- Call ---&gt; [具有API_KEY的Service1.php] ---通话 - &gt;付款服务。
App&lt; --- Response --- [Service1.php]&lt; --- Response ---- Payment Service。
就像在支付服务和您的应用之间使用中间层。像这样,黑客无法抓住钥匙。
答案 4 :(得分:0)
仅使用硬编码凭据保护应用程序已经提到不安全了。
我建议你使用一些类似登录的结构。 你首先要求用户名/密码。
然后使用在运行时编译的签名构建upp API调用。通过这样做,您永远不需要通过开放的Web发送用户密码。
你可以通过这样的电话来实现这个目标:
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).
然后,您可以通过使用数据库中存储的密码重新编译签名服务器端来验证呼叫。 如果签名匹配,则呼叫应该是可信的。 你还应该设置一个时间限制并拒绝每个旧的呼叫。
注意:您可能需要调整并将其更改为使用您的语言的工作代码,但您明白了。