1

我正在构建一个与在线 Web 服务通信的 Android 应用程序。我计划在 GitHub 上发布应用程序的源代码。对于我的生产版本,它将使用我的个人网络服务,我只想允许我的数字签名 apk 连接。

是否可以请求 APK 的密钥库并从该密钥库确认用户名/密码?

如果这是不可能的,我还能如何产生这个功能?

编辑:

我已经阅读了证书课程看起来我可以使用公钥/私钥来确认身份。但我仍然不确定实施

4

2 回答 2

1

我用这个——

    static public String getPackageFingerPrint( Context ctx ) {
        PackageManager pm = ctx.getPackageManager();
        String packageName = ctx.getPackageName();
        int flags = PackageManager.GET_SIGNATURES;

        PackageInfo packageInfo = null;

        try {
                packageInfo = pm.getPackageInfo(packageName, flags);
        } catch (NameNotFoundException e) {
                return "";
        }
        Signature[] signatures = packageInfo.signatures;

        byte[] cert = signatures[0].toByteArray();

        InputStream input = new ByteArrayInputStream(cert);

        CertificateFactory cf = null;
        try {
                cf = CertificateFactory.getInstance("X509");


        } catch (CertificateException e) {
                return "";
        }
        X509Certificate c = null;
        try {
                c = (X509Certificate) cf.generateCertificate(input);
        } catch (CertificateException e) {
                return "";
        }


        try {
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] publicKey = md.digest(c.getPublicKey().getEncoded());


            StringBuffer hexString = new StringBuffer();
            for (int i=0;i<publicKey.length;i++) {
                String appendString = Integer.toHexString(0xFF & publicKey[i]);
                if(appendString.length()==1)hexString.append("0");
                hexString.append(appendString);
                }


            return hexString.toString();

        } catch (NoSuchAlgorithmException e1) {
            return "";
        } 
    }

我在您的方法中看到的问题是任何人都可以确定包裹指纹或您的包裹并将其发送到您的网络服务。更好的可能性是使用质询-响应机制:您的 Web 服务向您发送一个唯一的会话令牌,您的应用程序使用共享算法对其进行加密或摘要,然后将此加密令牌发送回您的服务进行验证。当然,您不会想将该算法发布到 github。

于 2013-08-24T04:16:20.913 回答
0

您不能将 Web 服务限制为由特定密钥签名的 apk。

您的 apk 签名由 Android 操作系统验证,并且不会直接与设备连接的网络服务共享。即使您从密钥库中读取您的签名并将其与请求一起发送,攻击者也可以发送相同的签名(例如相同的字节流)而无需访问您的私钥。他只需要获取您签名的 apk,从密钥库中读取字节(或侦听合法请求)并破坏数据。

您需要签署单独的请求以获得一定程度的安全性。但是,如果您在发布版本中保留私钥(该密钥未在 gitHub 上分发),并使用该密钥签署请求,则您不安全,因为私钥作为您的 apk 的一部分分发,因此可以轻松提取。

无论如何,您的 API 都可能被其他 apk 访问。

但是,可能还有另一种方法来限制您的 API,例如使用许可证令牌等。在这种情况下,您可能不会关心用户是否自己构建 apk,只要他有有效的许可证令牌。如果许可证令牌被利用和分发,您可以对该许可证令牌上的大量流量做出反应,例如阻止其进一步请求。由于我不使用 Google Play,我不确定它们可以从您的服务器获得多远的验证,但也许应用程序许可门户是搜索合适令牌的良好起点。

于 2013-08-24T04:19:38.900 回答