如何在超过 28 的 Xamarin android api 级别中获取包签名

问题描述

 private static string GetPackageSignature(Context context)
 {
        PackageManager packageManager = context.PackageManager;
        var signing = packageManager.GetPackageInfo(context.PackageName,PackageInfoFlags.Signatures).Signatures;

        return signing.First().tochaRSString();
 }

通常我通过上面的代码获得签名。 但这已被弃用 我试图找到替换代码并尝试了很多解决方案,但我找不到能够更改的代码

How to use PackageInfo.GET_SIGNING_CERTIFICATES in API 28?

我将上述解决方代码转换为 Xamarin 代码,但它不起作用

        List<string> signatureBase64 = new List<string>();
        if (Build.VERSION.SdkInt >= BuildVersionCodes.P)
        {
            
            PackageInfo packageInfo = context.PackageManager.GetPackageInfo(context.PackageName,PackageInfoFlags.SigningCertificates);
            Signature[] signatures = packageInfo.SigningInfo.GetApkContentsSigners();
            MessageDigest md = MessageDigest.GetInstance("SHA");
            foreach(Signature signature in signatures)
            {
                md.Update(signature.ToByteArray());
                signatureBase64.Add(new string(Encoding.Unicode.GetChars(Base64.Encode(md.Digest(),Base64Flags.Default))));
            
            }
        }
        return signatureBase64[0];

如果我有什么错误或者我不知道,你能告诉我吗

这是我的最终解决方

 private static string GetPackageSignature(Context context)
    {
        string packageSign = "-1";


        if (context != null)
        {

            PackageManager packageManager = context.PackageManager;
            PackageInfo packageInfo;

            string packageName = context.PackageName;

            Signature[] signatures = null;
            try
            {
                if (Build.VERSION.SdkInt > BuildVersionCodes.P)
                {

                    packageInfo = packageManager.GetPackageInfo(packageName,PackageInfoFlags.SigningCertificates);
                    SigningInfo signingInfo = packageInfo.SigningInfo;
                    signatures = signingInfo.GetApkContentsSigners();
                }
                else
                {
                    // APi Level28 Under
#pragma warning disable CS0618 // Type or member is obsolete
                    var signing = packageManager.GetPackageInfo(packageName,PackageInfoFlags.Signatures).Signatures;
#pragma warning restore CS0618 // Type or member is obsolete

                    return signing.First().tochaRSString();
                }
            }
            catch (java.lang.Exception e)
            {
                Log.Error("Don't Read Pkg Sign AppHashKeyHelper",e.ToString());

            }
            if (null != signatures && signatures.Length > 0)
            {
                Signature sign = signatures[0];
                packageSign = sign.tochaRSString();
            }
        }
        return packageSign;
    }

以上代码返回值为packagesign

解决方法

您可以检查以下代码

public static string GetPackageSign(Context context)
{
    string str = "-1";


    if (context != null)
    {
       
        PackageManager packageManager = context.PackageManager;
        PackageInfo packageInfo;

        string packageName = context.PackageName;
       
        Android.Content.PM.Signature[] signatures = null;
        try
        {
            if (Build.VERSION.SdkInt > BuildVersionCodes.P)
            {

                packageInfo = packageManager.GetPackageInfo(context.PackageName,PackageInfoFlags.SigningCertificates);
                SigningInfo signingInfo = packageInfo.SigningInfo;
                signatures = signingInfo.GetApkContentsSigners();
            }
            else
            {
                
            }
        }
        catch (Java.Lang.Exception e)
        {
           

        }
        if (null != signatures && signatures.Length > 0)
        {
            Android.Content.PM.Signature sign = signatures[0];
            str = EncryptionMD5(sign.ToByteArray()).ToUpper();
        }
    }

    return str;
}


private static string EncryptionMD5(byte[] byteStr)
{
    MessageDigest messageDigest;
    StringBuffer md5StrBuff = new StringBuffer();
    try
    {
        messageDigest = MessageDigest.GetInstance("MD5");
        messageDigest.Reset();
        messageDigest.Update(byteStr);
        byte[] byteArray = messageDigest.Digest();
        foreach (byte aByteArray in byteArray)
        {
            if (Integer.ToHexString(0xFF & aByteArray).Length == 1)
            {
                md5StrBuff.Append("0").Append(Integer.ToHexString(0xFF & aByteArray));
            }
            else
            {
                md5StrBuff.Append(Integer.ToHexString(0xFF & aByteArray));
            }
        }
    }
    catch (Java.Lang.Exception e)
    {
       
    }
    return md5StrBuff.ToString();
}
,

试试这个。

public static String getSHA1(Context context){
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(),PackageManager.GET_SIGNATURES);
            byte[] cert = info.signatures[0].toByteArray();
            MessageDigest md = MessageDigest.getInstance("SHA1");
            byte[] publicKey = md.digest(cert);
            StringBuffer hexString = new StringBuffer();
            for (int i = 0; i < publicKey.length; i++  ) {
                String appendString = Integer.toHexString(0xFF & publicKey[i])
                        .toUpperCase(Locale.US);
                if (appendString.length() == 1)
                    hexString.append("0");
                hexString.append(appendString);
                hexString.append(":");
            }
            String result = hexString.toString();
            return result.substring(0,result.length()-1);
        } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }