首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用PackageInfo.signatures指纹串模拟SHA1

用PackageInfo.signatures指纹串模拟SHA1
EN

Stack Overflow用户
提问于 2018-11-27 14:23:33
回答 2查看 645关注 0票数 2

通过比较PackageInfo的包名和签名,我在android应用程序中实现了不兼容应用程序的验证。我通过以下方式获得有关已安装软件包的信息:

val packages = context.ctx.packageManager.getInstalledPackages(PackageManager.GET_META_DATA or PackageManager.GET_SIGNATURES)

之后,只需比较包名和签名的字符串。我通过以下函数将PackageInfo.signatures转换为十六进制:

代码语言:javascript
复制
fun bytesToHex(bytes: ByteArray): String {
        val hexArray = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F')
        val hexChars = CharArray(bytes.size * 2)
        var v: Int
        for (j in bytes.indices) {
            v = bytes[j].toInt() and 0xFF
            hexChars[j * 2] = hexArray[v.ushr(4)]
            hexChars[j * 2 + 1] = hexArray[v and 0x0F]
        }
        return String(hexChars)
}

而且效果很好。

现在,我想为这个功能实现几个单元测试,并且遇到了困难:如何模拟PackageInfo.signatures?如何将SHA1指纹字符串转换为android.content.pm.Signature?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-27 17:51:11

我不建议模拟框架类,因为这将是脆弱的。相反,只需创建自己的接口来提供签名,并在依赖于框架的实际应用程序中使用一个实现。例如:

代码语言:javascript
复制
interface SignatureProvider {
    val signatures: List<String>
}

class AndroidSignatureProvider(private val packageManager: PackageManager): SignatureProvider {
    private val flags = PackageManager.GET_META_DATA or PackageManager.GET_SIGNATURES

    override val signatures: List<String>
        get() = packageManager.getInstalledPackages(flags)
           .flatMap { it.packageInfo.signatures.toList() }
           .map { it.toCharsString() }
}

然后,在您的测试中,您只需模拟一个SignatureProvider,返回要对其进行测试的不同签名字符串:

代码语言:javascript
复制
private lateinit var signatureProvider: SignatureProvider

@Before fun setup() {
    signatureProvider = mock(SignatureProvider::class.java)
    doReturn(listOf("sigA", "sigB")).`when`(signatureProvider)`.signatures
}
票数 1
EN

Stack Overflow用户

发布于 2019-06-26 09:13:33

我相信你可以通过这样做来实现这一点:

代码语言:javascript
复制
testPackage() {
   final ShadowPackageManager packageManager = shadowOf(RuntimeEnvironment.application.getPackageManager());
   packageManager.installPackage(getPackageInfo(com.yourapp));
   final PackageInfo packageInfo = packageManager.getInternalMutablePackageInfo(com.yourapp);
   packageInfo.signatures = new Signature[1];
   packageInfo.signatures[0] = new Signature("your_signature");
}

private static PackageInfo getPackageInfo(String packageName) {
    final PackageInfoBuilder builder = PackageInfoBuilder.newBuilder();
    builder.setPackageName(packageName);
    return builder.build();
}

预期的格式是由Signature#toChars()生成的。

现在,我同意@kcoppock,因为使用签名和它们不同的表示方式操作很麻烦,而且容易出错。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53501818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档