在开发的过程中为了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种方式:
- 如果只有apk包的话,用keytool 命令行获取。把apk包解压,进入 META-INF 目录下,拿到 .RSA结尾的文件,命令:
keytool -printcert -file "RSA 路径\xxx.RSA"
- 如果有签名,直接通过keystore 签名文件获取
keytool -list -v -keystore "keystore 路径\xxx.keystore"
输入密码即可
网友评论