Tim*_*tin 4 android key signature android-contentprovider
我有一个应用程序提供专业版(付费)和免费版(添加支持)。两个版本都使用相同的密钥存储进行签名,但每个版本都有自己的密钥别名。
现在,我想开发一个与两个版本兼容的插件,通过内容提供商提供数据。数据很敏感,因此我需要只能从我的应用程序(专业版和免费版)访问我的内容提供程序。
使用 android:protectionLevel="signature" 的权限不起作用,因为免费版和专业版没有相同的签名 :/ 。我想我应该使用相同的密钥对我的两个版本进行签名,但我认为 Play 商店中的每个应用程序都需要使用自己的密钥进行签名。
那么,有人知道解决方案吗?有没有办法温和地要求谷歌更改我正在使用的密钥(我可以证明我的身份,因为我没有丢失我的密钥),或者我被卡住了?
编辑:我可以选择取消发布专业版(因为我目前的下载量很少)并使用与免费版本相同的证书重新上传它。如果这样做,我需要更改其包吗?
提前致谢
signature-level 权限很棒,但相当不灵活:应用程序必须使用相同的签名密钥进行签名。在很多情况下,我们想要检查另一个应用程序是否由预期的密钥签名,但该密钥不是我们的密钥。就您而言,您有两把钥匙。在其他情况下,人们可能会检查某些合作伙伴应用程序的签名 - 例如,确认您要向用户发送的 PayPal 应用程序确实是 PayPal 应用程序,而不是取代 PayPal 应用程序的恶意软件。
要验证另一个应用程序的签名,您可以使用PackageManager. 例如,这是我的 CWAC-Security 库中我的SignatureUtils课程的当前版本:
/***
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 /sf/answers/153835531/
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);
}
}
Run Code Online (Sandbox Code Playgroud)
我用来PackageManager获取Signature给定包的应用程序 ID。尽管有这个名字,Signature它实际上是用于签署应用程序的密钥对的公钥。的输出getSignatureHash()是一组以冒号分隔的十六进制字符对,表示公钥的 SHA256 哈希值...与使用 Java 7+ 命令获得的值相同keytool。
在您的情况下,您试图即时确定传入操作是否来自所需的应用程序,以及所需的应用程序是否正确(例如,与重新打包的恶意软件相比)。在您的情况下,Binder.getCallingUid()将为您提供触发 IPC(触发您的代码)的应用程序的 Linux UID。PackageManager可以为您提供该 UID 的应用程序的应用程序 ID(忽略android:sharedUserId场景)。然后,您将查看该应用程序 ID 是否是预期值,如果是,请检查哈希签名密钥是否是预期值。如果任一测试失败,用挥舞手臂的机器人的话来说,“危险,威尔·罗宾逊!危险!” 。
一个重要的警告是,一些开发人员将通过这些应用程序重新签名的渠道发布应用程序。这里最值得注意的是适用于 Android 的 Amazon AppStore,亚马逊有意将您的应用程序包装在他们自己的准 DRM 中,并使用他们代表您生成的密钥对该应用程序进行签名。这与您在其他地方必然使用的密钥不同,因此您可能需要比较多个有效的签名哈希值。
| 归档时间: |
|
| 查看次数: |
2340 次 |
| 最近记录: |