安全的 REST 服务只能由特定的 android 应用程序使用

Posted

技术标签:

【中文标题】安全的 REST 服务只能由特定的 android 应用程序使用【英文标题】:Secure REST service to consume only by specific android app 【发布时间】:2015-06-01 23:42:20 【问题描述】:

我的服务器公开了许多 REST 服务,我希望保护 Web 服务,使其只能由我拥有的 android 应用程序使用。

基本上客户端(安卓应用)和服务器都是我开发的;我只需要向我的 android 应用程序公开 REST 服务。

我想到了多种保护 REST 服务的方法,例如

使用基于用户名/密码的身份验证 JWT 令牌 基于签名的验证 等

在所有情况下,android 应用程序都应将密码存储在应用程序中;在这种情况下,黑客可以轻松反编译应用程序并获取密码。

如何保护我的 REST 只能由 android 应用程序访问?

编辑: 客户端应用不需要用户进行任何身份验证

【问题讨论】:

【参考方案1】:

您可以将 SSL 与 客户端 身份验证一起使用。服务器必须知道应用程序的公钥,而应用程序必须知道服务器的公钥。应用的私钥使用keystore存储在应用本身,这是一种防止反编译的安全方法,看看https://developer.android.com/training/articles/keystore.html

替代方案:

获取应用的哈希

public void traceKeyHash(Activity activity)
    try 
        PackageInfo info = activity.getPackageManager().getPackageInfo("your.package.here", PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) 
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            Log.i(getClass().getName(), "Share - KeyHash: " + Base64.encodeToString(md.digest(), Base64.DEFAULT));
        
    
    catch (Exception e) 
        e.printStackTrace();
    

现在您必须将哈希发送到您的服务器,但是...为了避免嗅探请求,您必须加密您的哈希。使用存储在密钥库中的私钥加密您的哈希,并使用服务器端的公钥解密消息,检查哈希是否与您注册的匹配。

【讨论】:

【参考方案2】:
    让用户登录以发出令牌。保存令牌颁发者的应用 ID。 当使用令牌访问 Web 服务时,服务器可以验证该令牌确实是通过 appId y 发送给用户 x。

【讨论】:

【参考方案3】:

你不能。身份验证是通过在客户端和服务器之间共享一些秘密来完成的。如果你把这个秘密放在你的应用程序中,它将被反编译和窃取(如果有人足够关心的话)。如果您将该秘密(如密码)提供给某人,您可以验证该人的身份,但该人可以将其输入假应用程序。当您处理不受您控制的未知硬件时,无法确保它是您的应用程序而不是其他人的应用程序 - 您只能确保用户已获得授权。

【讨论】:

【参考方案4】:

我建议您永远不要在客户端存储密码。使用授权密钥。用户在第一次身份验证时输入登录名和密码一次,然后服务器检查凭据并发出身份验证令牌。结果客户端必须只存储令牌。

【讨论】:

以上是关于安全的 REST 服务只能由特定的 android 应用程序使用的主要内容,如果未能解决你的问题,请参考以下文章

REST Web 服务身份验证令牌实现

xmpp 的简单 REST HTTP 代理

对REST的理解

为 iOS/Android 应用程序保护基于 REST 的服务的选项

TCP 服务和 REST API

REST 和服务到服务身份验证