Unity 开发中验证Android 签名

在开发的过程中为了apk的安全,最好在apk运行的最开始进行签名的验证,防止被人反编译后重新打包运行,下面就在 C# 中展示如何在 unity 进行签名的认证:

using System;
using System.Text;
using UnityEngine;

public class CheckSignatureUtils
{
    // 请替换成自己游戏的签名
    public static string signatureNormal = "AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0"; 
    // 特殊渠道签名,他们一般会二次签名
    public static string signatureBili = "AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0";
    public static string signatureUc = "AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0:AA:C0";
  
    public static void CheckSignature(string channel)
    {
#if UNITY_ANDROID && !UNITY_EDITOR
        //5.X以上版本  com.unity3d.player.UnityPlayerActivity
        //5.X以下版本  com.unity3d.player.UnityPlayerNativeActivity
        var player = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        var activity = player.GetStatic<AndroidJavaObject>("currentActivity");
        var PackageManager = new AndroidJavaClass("android.content.pm.PackageManager");
        var packageName = activity.Call<string>("getPackageName");
        var GET_SIGNATURES = PackageManager.GetStatic<int>("GET_SIGNATURES");
        var packageManager = activity.Call<AndroidJavaObject>("getPackageManager");
        var packageInfo = packageManager.Call<AndroidJavaObject>("getPackageInfo", packageName, GET_SIGNATURES);
        var signatures = packageInfo.Get<AndroidJavaObject[]>("signatures");

        if (signatures != null && signatures.Length > 0)
        {
            byte[] bytes = signatures[0].Call<byte[]>("toByteArray");
            var md5String = GetMD5(bytes);
            md5String = md5String.ToUpper();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < md5String.Length; ++i)
            {
                if (i > 0 && i % 2 == 0)
                {
                    sb.Append(':');
                }
                sb.Append(md5String[i]);
            }
            string signatureStr = sb.ToString();
            CheckeSignatureStr(channel, signatureStr);
        }
#endif
    }

    private static string GetMD5(byte[] bytedata)
    {
        try
        {
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(bytedata);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            throw new Exception("GetMD5 fail,error:" + ex.Message);
        }
    }

    //在这里进行特殊渠道的特殊处理
    private static void CheckeSignatureStr(string channel , string signatureStr)
    {
        Debug.Log(" channel," + channel + ",signatureStr:" + signatureStr);
        if (signatureStr.Equals(signatureNormal ))
        {
            Debug.Log("签名验证正常");
        }
        else if (channel.Equals("bili") && signatureStr.Equals(signatureBili))
        {
            Debug.Log("B站签名验证正常");
        }
        else if (channel.Equals("uc") && signatureStr.Equals(signatureUc))
        {
            Debug.Log("UC签名验证正常");
        }
        else {
            Debug.Log("签名异常");
            Application.Quit();
        }
    }
}

接下来展示如何获取签名文件的MD5

2种方式:

  1. 如果只有apk包的话,用keytool 命令行获取。把apk包解压,进入 META-INF 目录下,拿到 .RSA结尾的文件,命令:
keytool -printcert -file "RSA 路径\xxx.RSA"
  1. 如果有签名,直接通过keystore 签名文件获取
keytool -list -v -keystore  "keystore  路径\xxx.keystore"

输入密码即可

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一、概述 这个玩意简单说起来很简单,详细描述起来很复杂,复杂在什么地方呢,首先有一块陌生的知识点,包括但不限于证书...
    Time_x阅读 2,424评论 1 1
  • 蓝师傅最近几个月非常忙,很久没更新文章了,惭愧惭愧,距离上一篇技术文章已经是半年前了~ 前几个月负责游戏SDK的开...
    蓝师傅_Android阅读 2,185评论 1 15
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,570评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,612评论 0 11
  • 可爱进取,孤独成精。努力飞翔,天堂翱翔。战争美好,孤独进取。胆大飞翔,成就辉煌。努力进取,遥望,和谐家园。可爱游走...
    赵原野阅读 2,774评论 1 1