android应用标签未完善,Ionic Android进行签名校验验证-应用签名未校验风险的讲解...
Ionic签名校验验证
1. 为什么要进行签名校验
2. 查看安卓证书信息
3. 编写检验文件
3.1 编写校验文件`SignCheck.java`
3.2 修改MainActivity.java
3.3 其他方案
4. 打包
4.1 移除android平台
4.2 增加android平台版本
4.3 覆盖`MainActivity.java`
4.4 使用证书进行打包
5. 打包完成安装apk
6. 加固原理
1. 为什么要进行签名校验
有些应用会使用工具对应用进行扫描进行判断所存在的风险,特别一些国企,金融,安全类等应用,其中扫描有一项是应用签名未校验风险。
危害的风险描述: 签名证书是对App开发者身份的唯一标识,开发者可利用签名证书有效降低App的盗版率,。未进行签名证书的App,可能被反编译后进行二次打包。重新打包签名的应用,可能导致App被仿冒盗版,影响其合法收入,甚至可能被添钓鱼代码、病毒代码、恶意代码,导致用户敏感信息泄露或者恶意攻击。
因此针对这个需求需要对应用进行处理,可以检测App程序启动时是否校验签名证书。增加签名证书的校验代码,降低App被二次打包的几率。
通常会对应用进行几步操作: 1.增加签名校验。 2.对App进行加固。3.对加固的App进行二次签名。
2. 查看安卓证书信息
Ionic移动开发完成后,需要进行打包操作,此时需要使用证书进行打包。
证书可以自己进行生成。那如何查看证书生成后的信息呢?
# 在证书的文件根目录运行 keytool -list -v -keystore mykeystorefile(证书名称) # 输入密钥库口令,这时请输入证书生成时所用到的密码 钥库类型: JKS 密钥库提供方: SUN 您的密钥库包含 1 个条目 别名: com.zhangguoye.app 创建日期: 2018-1-26 条目类型: PrivateKeyEntry 证书链长度: 1 证书[1]: 所有者: CN=com.zhangguoye.app, OU=com.zhangguoye.app, O=com.zhangguoye.app 发布者: CN=com.zhangguoye.app, OU=com.zhangguoye.app, O=com.zhangguoye.app 序列号: 1230f945 有效期开始日期: Tue Feb 26 15:04:52 CST 2018, 截止日期: Sat Feb 20 15:04:52 CST 2020 证书指纹: MD5: 12:34:56:68:6A:78:22:90:12:FE:12:95:12F:6E:29:12 SHA1: 12:23:45:E1:D1:01:A2:12:37:B2:E3:B1:79:21:16:FD:0B:8D:3E:EB SHA256: 12:10:37:15:73:D1:11:F1:32:23:33:63:12:9A:12:12:ED:12:12:12:12:2D:02:12:22:4A:52:62:92:51:22:01 签名算法名称: S********* 版本: 3 扩展: ..... ******************************************* *******************************************
3. 编写检验文件
3.1 编写校验文件SignCheck.java
package com.zhangguoye.app; // 你的包名 import android.app.AlertDialog; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.content.DialogInterface; import android.util.Log; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; public class SignCheck { private Context context; private String cer = null; private String realCer = null; private static final String TAG = "SignCheck"; public SignCheck(Context context) { this.context = context; this.cer = getCertificateSHA1Fingerprint(); } public SignCheck(Context context, String realCer) { this.context = context; this.realCer = realCer; this.cer = getCertificateSHA1Fingerprint(); } public String getRealCer() { return realCer; } /** * 设置正确的签名 * * @param realCer */ public void setRealCer(String realCer) { this.realCer = realCer; } /** * 获取应用的签名 * * @return */ public String getCertificateSHA1Fingerprint() { //获取包管理器 PackageManager pm = context.getPackageManager(); //获取当前要获取 SHA1 值的包名,也可以用其他的包名,但需要注意, //在用其他包名的前提是,此方法传递的参数 Context 应该是对应包的上下文。 String packageName = context.getPackageName(); //返回包括在包中的签名信息 int flags = PackageManager.GET_SIGNATURES; PackageInfo packageInfo = null; try { //获得包的所有内容信息类 packageInfo = pm.getPackageInfo(packageName, flags); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } //签名信息 Signature[] signatures = packageInfo.signatures; byte[] cert = signatures[0].toByteArray(); //将签名转换为字节数组流 InputStream input = new ByteArrayInputStream(cert); //证书工厂类,这个类实现了出厂合格证算法的功能 CertificateFactory cf = null; try { cf = CertificateFactory.getInstance("X509"); } catch (Exception e) { e.printStackTrace(); } //X509 证书,X.509 是一种非常通用的证书格式 X509Certificate c = null; try { c = (X509Certificate) cf.generateCertificate(input); } catch (Exception e) { e.printStackTrace(); } String hexString = null; try { //加密算法的类,这里的参数可以使 MD4,MD5 等加密算法 MessageDigest md = MessageDigest.getInstance("SHA1"); //获得公钥 byte[] publicKey = md.digest(c.getEncoded()); //字节到十六进制的格式转换 hexString = byte2HexFormatted(publicKey); } catch (NoSuchAlgorithmException e1) { e1.printStackTrace(); } catch (CertificateEncodingException e) { e.printStackTrace(); } return hexString; } //这里是将获取到得编码进行16 进制转换 private String byte2HexFormatted(byte[] arr) { StringBuilder str = new StringBuilder(arr.length * 2); for (int i = 0; i 2) h = h.substring(l - 2, l); str.append(h.toUpperCase()); if (i < (arr.length - 1)) str.append(':'); } return str.toString(); } /** * 检测签名是否正确 * @return true 签名正常 false 签名不正常 */ public boolean check() { if (this.realCer != null) { cer = cer.trim(); realCer = realCer.trim(); if (this.cer.equals(this.realCer)) { return true; } }else { Log.e(TAG, "未给定真实的签名 SHA-1 值"); } return false; } public void checkSuccess() { new AlertDialog.Builder(context) .setTitle("签名校验成功") .setMessage("成功!") .setPositiveButton("确定", null) .show(); } public void showCheckErrorTips() { new AlertDialog.Builder(context) .setTitle("签名校验失败") .setMessage("存在签名异常,请在官方下载最新的APP!http://zhangguoye.com") .setCancelable(false) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { System.exit(0); } }) .show(); } }
3.2 修改MainActivity.java
修改MainActivity.java,增加检验签名方法
package com.zhangguoye.app; // 你的包名 import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.util.Base64; import org.apache.cordova.*; import java.io.UnsupportedEncodingException; public class MainActivity extends CordovaActivity { public static String param = ""; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... // 此处增加方法调用 singCheck(); // ... } /** * 增加签名检验方法 **/ private void singCheck() { SignCheck signCheck = new SignCheck(this, "12:23:45:E1:D1:01:A2:12:37:B2:E3:B1:79:21:16:FD:0B:8D:3E:EB"); // 第2步查看签名指纹的SHA1 if (signCheck.check()) { // 签名正常 } else { // 签名异常 signCheck.showCheckErrorTips(); } } }
3.3 其他方案
可以编写安卓的方法,通过ionic层使用javascript调用进行通信,同样实现运行时进行签名的校验。
可以封装成签名校验的cordova插件,供ionic项目进行使用。
4. 打包
4.1 移除android平台
ionic cordova platform rm android
4.2 增加android平台版本
ionic cordova platform add android
若需要指定版本则
ionic cordova platform add android@6.5.0
4.3 覆盖MainActivity.java
在目录下找到此文件并覆盖
platforms/android/src/com/zhangguoye
因为目录可能跟你的不同,你可以直接在项目里搜索此文件进行覆盖
在MainActivity.java当前目录加入文件SignCheck.java
4.4 使用证书进行打包
ionic cordova build android --device --minifycss --minfyjs --optimizejs --prod --release -- -- --keystore=./certification/keystore/zhangguoye --alias=com.zhangguoye.app
注意keystore=./certification/keystore/zhangguoye --alias=com.zhangguoye.app
这一段是配置成你自己的证书路径和证书名称、证书别名
5. 打包完成安装apk
打包完成,安装apk并启动。
此时若是App被人使用其他证书进行二次签名后,会有对应的提示。
确定后会关闭APP
6. 加固原理
这里有一篇介绍安卓加固的原理文章,可了解下:
https://www.cnblogs.com/my-testing-life/articles/12613496.html
android应用标签未完善,Ionic Android进行签名校验验证-应用签名未校验风险的讲解...相关推荐
- android 技能标签功能_iOS和Android用户体验设计差异
摘要:iOS和Android用户体验设计差异 关键词:iOS,Android,用户体验设计 本文将讨论iOS和Android之间的具体设计差异. 基本差异 1.设计规范 iOS和Android遵循不同 ...
- Android Activity标签属性
Android Activity标签属性 Activity 是 Android 系统四大应用组件之一,用户可与 Activity 提供的屏幕进行交互,以执行拨打电话.拍摄照片.发送电子邮件等操作开发者 ...
- 一个快速、完善的Android开发框架整合实践(QuickAndroid)
https://github.com/alafighting/QuickAndroid QuickAndroid 一个快速.完善的Android开发框架整合实践 QA项目简介 本框架QuickAndr ...
- Android NFC 标签读写Demo与历史漏洞概述
文章目录 前言 NFC基础 1.1 RFID区别 1.2 工作模式 1.3 日常应用 NFC标签 2.1 标签应用 2.2 应用实践 2.3 标签预览 2.4 前台调度 NFC开发 3.1 NDEF数 ...
- Android vector标签 PathData 画图超详解
此文章来源于https://www.cnblogs.com/yuhanghzsd/p/5466846.html点击打开链接 Android vector标签 PathData 画图超详解 SVG是一种 ...
- android之tab分页标签的实现方法,Android应用中使用ViewPager和ViewPager指示器来制作Tab标签...
一.ViewPageIndicator开源框架的基本用法我们先得去Github上面下载这个库,下载地址:https://github.com/JakeWharton/Android-ViewPager ...
- [转载]Android Layout标签之-viewStub,requestFocus,merge,include
定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是<viewStub/>, <requestFocus />, ...
- 曝荣耀仍未获得谷歌Android授权;诋毁鸿蒙的OPPO员工离职;微信圈子将停止运营|极客头条...
「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...
- android UI 标签
1.TextView 如下 设置基本的宽度,高度,值,控件位置,默认值等等 <TextViewandroid:layout_width="100dp"android:layo ...
最新文章
- 威胁生存!科学家警告灾难性“气候临界点”已逼近
- Swift-学习Perfect搭建博客
- CF183D T-shirt
- ATM信元的交换方式为?
- @pathVariable 映射URL绑定的占位符
- oracle同义词truncate,详解Oracle DELETE和TRUNCATE 的区别
- linux read01,Linux内置命令之read
- Redis的Errorlog或者启动日志(错误日志)的配置
- html字体代码大全_Vba群发邮件及HTML设置字体格式的代码
- RTX移植到STM32F103
- php 同时导出两个文件_使用orangehill/iseed自动反向生成数据填充文件
- LeetCode(1108)——IP 地址无效化(JavaScript)
- kettle将文件路径定义为_Kettle变量和自己定义java代码的实例应用
- JPYXGSIT故障解决方案
- 推荐一个键盘快捷键库Mousetrap
- 开源的在线视频点播系统,值得分享!
- js监听中文拼音输入开始输入和输入完成的事件,用input事件用拼音输入法的大坑,由这两个事件来解决
- 最新麦子学院嵌入式开发系列培训教程
- 全新 OceanBase 社区版开发者中心 ODC 核心功能解读
- 这款安全好用的手机浏览器,真是一股清流,值得点赞