在Unity3d项目中获取APK包签名公钥的方法,核心思想就是通过JNI调用Android提供的方法。不过Unity3d提供了比JNI更上一层的类AndroidJavaObject以及继承它的AndroidJavaClass,帮助开发者省去很多工作。这两种类型的函数及内部原理可以看Unity3d官网,也可以反编译看里面的代码,直接说用法。

首先要获取到当前运行程序的Activity才好继续以后的操作。Unity3d在程序启动时记录下了这个值,可以通过UnityPlayer类的静态字段currentActivity来取得,UnityPlayer是由UnityPlayerActivity这个继承自Activity的类在onCreate时创建并传入当前Activity(详细流程可以通过jd-gui或反编译项目smali查看)。取到Activity以后就可以getPackageManager、getPackageInfo来获取到签名。得到的签名据说保存了公钥以及其他一些信息,这个没有具体深入了解,但是可以从签名获取到公钥是一定可以的,CertificateFactory的generateCertificate、getPublicKey方法取得最终值。下面是完整代码,注释对应java代码:

 private byte[] GetSignature()
{
//Player = new UnityPlayer();
AndroidJavaClass Player = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
//Activity = Player.currentActivity;
AndroidJavaObject Activity = Player.GetStatic<AndroidJavaObject>("currentActivity");
//PackageManager = Activity.getPackageManager();
AndroidJavaObject PackageManager = Activity.Call<AndroidJavaObject>("getPackageManager");
//GET_SIGNATURES = PackageManager.GET_SIGNATURES;
int GET_SIGNATURES = PackageManager.GetStatic<int>("GET_SIGNATURES");
//PackageInfo = PackageManager.getPackageInfo("com.ztx.uni", PackageManager.GET_SIGNATURES);
AndroidJavaObject PackageInfo = PackageManager.Call<AndroidJavaObject>("getPackageInfo", "com.ztx.uni", GET_SIGNATURES);
//Signatures = PackageInfo.signatures;
AndroidJavaObject[] Signatures = PackageInfo.Get<AndroidJavaObject[]>("signatures");
//return Signatures[0].toByteArray();
return (Signatures != null && Signatures.Length > 0) ? Signatures[0].Call<byte[]>("toByteArray") : null;
} private string GetPublicKey()
{
byte[] Signatures = GetSignature(); if (Signatures != null)
{
//CCertificateFactory = new CertificateFactory();
AndroidJavaClass CCertificateFactory = new AndroidJavaClass("java.security.cert.CertificateFactory");
//OCertFactory = CCertificateFactory.getInstance();
AndroidJavaObject OCertFactory = CCertificateFactory.CallStatic<AndroidJavaObject>("getInstance", "X.509");
//OByteArrayInputStream = new ByteArrayInputStream(Signatures);
AndroidJavaObject OByteArrayInputStream = new AndroidJavaObject("java.io.ByteArrayInputStream", Signatures);
//OX509Certificate = OCertFactory.generateCertificate(OByteArrayInputStream);
AndroidJavaObject OX509Certificate = OCertFactory.Call<AndroidJavaObject>("generateCertificate", OByteArrayInputStream);
//OPublicKey = OX509Certificate.getPublicKey();
AndroidJavaObject OPublicKey = OX509Certificate.Call<AndroidJavaObject>("getPublicKey"); string publickey = OPublicKey.Call<string>("toString");
AndroidJavaObject CString = new AndroidJavaObject("java/lang/String", publickey);
int start = CString.Call<int>("indexOf", "modulus");
int end = CString.Call<int>("indexOf", "public"); if (start >= 0 && end >= 0)
{
return CString.Call<string>("substring", start + 8, end - 1);
}
} return null;
} 在GetPublicKey()中取得的OPublicKey是如下的形式:
OpenSSLRSAPublicKey
{modulus=d6931904dec60b24b1edc762e0d9d8253e3ecd6ceb1de2ff068ca8e8bca8cd6bd3786ea70aa76ce
60ebb0f993559ffd93e77a943e7e83d4b64b8e4fea2d3e656f1e267a81bbfb230b578c20443be4c7218b846f
5211586f038a14e89c2be387f8ebecf8fcac3da1ee330c9ea93d0a7c3dc4af350220d50080732e0809717ee6
a053359e6a694ec2cb3f284a0a466c87a94d83b31093a67372e2f6412c06e6d42f15818dffe0381cc0cd444d
a6cddc3b82458194801b32564134fbfde98c9287748dbf5676a540d8154c8bbca07b9e247553311c46b9af76
fdeeccc8e69e7c8a2d08e782620943f99727d3c04fe72991d99df9bae38a0b2177fa31d5b6afee91f,publicExponent=3} 而我们要的只是其中的256位公钥,所以在函数后面取了modulus和publicExponent之间的值。至此全部工作结束,很简单吧,如果在ndk中做公钥提取也是这个道理,不过要写很多很多代码。 转载地址:http://m.blog.csdn.net/blog/s10141303/38260469

最新文章

  1. Ubuntu下的MySQL安装
  2. 随机生成数字(ashx文件,调用上篇所写发送邮件代码)
  3. MVC 创建线程内的db单例
  4. Bootstrap_导航
  5. phpPgAdmin安装与配置
  6. 特征工程 dataframe格式
  7. Build 2016概览
  8. jQuery属性,方法操作
  9. 顺序表及其多种实现方式 --- C/C++
  10. 【系统Configmachine.config与自己的应用程序的App.config/Web.Config配置节点重复】解决方法
  11. 【贪心】bzoj 3709:[PA2014]Bohater
  12. (一)问候Struts2
  13. Entity Framework CodeFirst------数据迁移(二)
  14. 8--UI 初步认识 简易计算器
  15. iOS查错机制
  16. maven lean install 的时候出错 Failed to clean project
  17. Java Script中常见操作
  18. 多输入select
  19. 优化CSS重排重绘与浏览器性能
  20. python 全栈开发,Day90(Vue组件,前端开发工具包)

热门文章

  1. Codeforces 722D. Generating Sets
  2. VS.Net 2015 Update3 学习(2) jquery-form, jquery-validation,jquery-validation-unobtrusive一起用
  3. 理解RESTful
  4. 上传文件fileupload
  5. pandas应用之分组因子暴露和分位数分析
  6. centos7
  7. Javascript优化后的加减乘除(解决js浮点数计算bug)
  8. OneProxy自动剔除延迟节点
  9. iBATIS代码生成分析
  10. 8bit YUV4:2:2格式对应的颜色