阅读 77

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"

输入密码即可

作者:flu鲁少

原文链接:https://www.jianshu.com/p/7cba88548108

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐