Android内容提供商保护级别和不同的键 [英] Android content provider protection level & different keys

查看:80
本文介绍了Android内容提供商保护级别和不同的键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个适用于Pro(付费)和的应用程序;免费(添加受支持)版本.两种版本都使用相同的密钥库签名,但是每个版本都有自己的密钥别名.

I have an app available in Pro (paid) & Free (add supported) versions. Both versions are signed with the same key store, but each one with its own key alias.

知道,我想开发一个与两个版本都兼容的插件,并通过内容提供商提供数据.数据是敏感的,因此我需要只能从我的应用程序(Pro& Free版本)访问内容提供程序.

Know, I'd like to develop a plugin compatible with both versions, offering data through a content provider. The data is sensitive, so I need my content provider to be accessible only from my app (both Pro & Free versions).

使用android:protectionLevel ="signature"的权限不起作用,因为Free&专业版没有相同的签名:/.我想我应该用相同的密钥对两个版本进行签名,但是我认为Play商店中的每个应用都需要使用自己的密钥进行签名.

Using a permission with the android:protectionLevel="signature" is not working, because the Free & Pro versions do not have the same signature :/ . I guess I should have signed my two versions with the same key, but I thought each app on the Play Store needed to be signed with its own key.

那么,有人知道解决方案吗?有没有办法轻轻地要求Google更改我正在使用的密钥(我可以证明自己的身份,因为我没有松开密钥),还是卡住了??

So, does someone knows a solution ? Is there a way to gently ask Google to change the keys I'm using (I can prove my identity, as I did not loose my keys), or am I stuck??

我可以选择取消发布Pro版本(因为我目前下载量很少),并使用与免费版本相同的证书重新上载它.如果这样做,我是否需要更改其包装?

EDIT : I could choose to un-publish the Pro version (as I have very few downloads at the moment) and re-upload it with the same certificate than the one used for the free version. If I do so, will I need to change its package?

预先感谢

推荐答案

signature级别的权限很好,但又不太灵活:必须使用相同的签名密钥对应用程序进行签名.在许多情况下,我们将要检查其他应用程序是否已由预期的密钥签名,但是该密钥不是 our 密钥.在您的情况下,您有两个键.在其他情况下,可能正在检查某个合作伙伴应用的签名-—例如,确认要发送给用户的PayPal应用确实是PayPal应用,而不是替换了PayPal应用的恶意软件.

signature-level permissions are great, but fairly inflexible: the apps have to be signed by the same signing key. There are many cases in which we will want to check to see if another app is signed by the expected key, but that key is not our key. In your case, you have two keys. In other cases, one might be checking the signature of some partner app — confirming, for example, that the PayPal app you are about to send the user to is really the PayPal app and not malware that has replaced the PayPal app.

要验证另一个应用程序的签名,可以使用PackageManager.例如,这是我的SignatureUtils"rel =" nofollow noreferrer>我的CWAC-安全库:

To validate the signature of another app, you can use PackageManager. For example, here is the now-current edition of my SignatureUtils class from my CWAC-Security library:

/***
  Copyright (c) 2014 CommonsWare, LLC

  Licensed under the Apache License, Version 2.0 (the "License"); you may
  not use this file except in compliance with the License. You may obtain
  a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

package com.commonsware.cwac.security;

import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SignatureUtils {
  public static String getOwnSignatureHash(Context ctxt)
                                                        throws NameNotFoundException,
                                                        NoSuchAlgorithmException {
    return(getSignatureHash(ctxt, ctxt.getPackageName()));
  }

  public static String getSignatureHash(Context ctxt, String packageName)
                                                                         throws NameNotFoundException,
                                                                         NoSuchAlgorithmException {
    MessageDigest md=MessageDigest.getInstance("SHA-256");
    Signature sig=
        ctxt.getPackageManager()
            .getPackageInfo(packageName, PackageManager.GET_SIGNATURES).signatures[0];

    return(toHexStringWithColons(md.digest(sig.toByteArray())));
  }

  // based on https://stackoverflow.com/a/2197650/115145

  public static String toHexStringWithColons(byte[] bytes) {
    char[] hexArray=
        { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
            'C', 'D', 'E', 'F' };
    char[] hexChars=new char[(bytes.length * 3) - 1];
    int v;

    for (int j=0; j < bytes.length; j++) {
      v=bytes[j] & 0xFF;
      hexChars[j * 3]=hexArray[v / 16];
      hexChars[j * 3 + 1]=hexArray[v % 16];

      if (j < bytes.length - 1) {
        hexChars[j * 3 + 2]=':';
      }
    }

    return new String(hexChars);
  }
}

在给定包的应用程序ID的情况下,我使用PackageManager来获取给定包的Signature.尽管名称,Signature实际上是用于对应用程序进行签名的密钥对的公钥. getSignatureHash()的输出是用冒号分隔的一组十六进制字符对,表示公钥的SHA256哈希...与使用Java 7+ keytool 命令所获得的值相同

I use PackageManager to get the Signature for the given package, given its application ID. Despite the name, Signature is really the public key of the keypair used to sign the app. The output of getSignatureHash() is a colon-delimited set of hex character pairs, representing the SHA256 hash of the public key... the same value you get from using the Java 7+ keytool command.

在您的情况下,您试图动态确定传入的操作是否来自所需的应用程序,以及该所需的应用程序是否正确(例如,与重新打包的恶意软件相比).在您的情况下,Binder.getCallingUid()将为您提供触发IPC的应用程序的Linux UID,该IPC触发了您的代码. PackageManager可以危险,威尔·罗宾逊!危险!" .

In your case, you are trying to determine, on the fly, whether an incoming operation is from the desired app, and if that desired app is the right one (versus repackaged malware, for example). In your case, Binder.getCallingUid() will give you the Linux UID of the app that triggered the IPC that triggered your code. PackageManager can give you the application ID of the app for that UID (ignoring android:sharedUserId scenarios). You would then see if that application ID is the expected value, and if it is, check to see if the hashed signing key is the expected value. If either test fails, in the words of an arm-flailing robot, "Danger, Will Robinson! Danger!".

一个重要的警告是,一些开发人员将通过重新签名这些应用程序的渠道来发布应用程序.这里最值得注意的是Android专用的Amazon AppStore,Amazon故意将您的应用程序包装在自己的准DRM中,并使用由他们代表您生成的密钥对该应用程序进行签名.这与您在其他地方必须使用的密钥不同,因此可能需要比较多个有效的签名哈希.

One significant caveat is that some developers will publish apps through channels where those apps get re-signed. Most notable here is the Amazon AppStore for Android, where Amazon intentionally wraps your app in their own quasi-DRM and signs that app using a key that they generate on your behalf. That's not the same key that you would necessarily be using elsewhere, so there may be multiple valid signature hashes that you would need to compare.

这篇关于Android内容提供商保护级别和不同的键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆