基础概念
签名:在 APK 中写入一个「指纹」。指纹写入以后,APK 中有任何修改,都会导致这个指纹无效,Android 系统在安装 APK 进行签名校验时就会不通过,从而保证了安全性。
摘要算法: 使用一段简单的看上去随机的不可逆向的固定长度的字符串来表示一个文件的唯一性。 常见的摘要算法如MD5(128个比特位)、SHA-1算法(160/192/256个比特位)。
公钥密码体制:也称非对称算法,特点是 公钥是公开的 ,私钥是保密的。常见的如:RSA。
展开讨论一下RSA:
Android中的签名方案
V1 :基于jarsigner(JDK自带工具,使用keystore文件进行签名) 或 apksigner(Android专门提供的,使用pk8、x509pem进行签名)。keystore和pk8/x509pem可以相互转换。
签名原理:首先keystore文件包含一个MD5和一个SHA1摘要。 这也是很多开放平台需要我们上传的摘要数据 。
签名APK后会在META-INF文件夹下生产CERTRSA、CERTSF、MANIFESTMF三个文件。
在apk中,/META-INF文件夹中保存着apk的签名信息,一般至少包含三个文件,[CERT]RSA,[CERT]SF和MANIFEISTMF文件。这三个文件就是对apk的签名信息。
MANIFESTMF中包含对apk中除了/META-INF文件夹外所有文件的签名值,签名方法是先SHA1()(或其他hash方法)在base64()。存储形式是:Name加[SHA1]-Digest。
[CERT]SF是对MANIFESTMF文件整体签名以及其中各个条目的签名。一般地,如果是使用工具签名,还多包括一项。就是对MANIFESTMF头部信息的签名,关于这一点前面源码分析中已经提到。
[CERT]RSA包含用私钥对[CERT]SF的签名以及包含公钥信息的数字证书。
是否存在签名伪造可能:
修改(含增删改)了apk中的文件,则:校验时计算出的文件的摘要值与MANIFESTMF文件中的条目不匹配,失败。
修改apk中的文件+MANIFESTMF,则:MANIFESTMF修改过的条目的摘要与[CERT]SF对应的条目不匹配,失败。
修改apk中的文件+MANIFESTMF+[CERT]SF,则:计算出的[CERT]SF签名与[CERT]RSA中记录的签名值不匹配,失败。
修改apk中的文件+MANIFESTMF+[CERT]SF+[CERT]RSA,则:由于证书不可伪造,[CERT]RSA无法伪造。
V2 :70新增的
签名后的包会被分为四部分
1 Contents of ZIP entries(from offset 0 until the start of APK Signing Block)
2 APK Signing Block
3 ZIP Central Directory
4 ZIP End of Central Directory
新应用签名方案的签名信息会被保存在区块2(APK Signing Block) 中, 而区块1( Contents of ZIP entries )、区块3( ZIP Central Directory )、区块4( ZIP End of Central Directory )是受保护的, 在签名后任何对区块1、3、4的修改都逃不过新的应用签名方案的检查 。
V3 :90新增的
格式大体和 v2 类似,在 v2 插入的签名块(Apk Signature Block v2)中,又添加了一个新快(Attr块) 。
在这个新块中,会记录我们之前的签名信息以及新的签名信息,以 密钥转轮的方案,来做签名的替换和升级。这意味着,只要旧签名证书在手,我们就可以通过它在新的 APK 文件中,更改签名 。
v3 签名新增的新块(attr)存储了所有的签名信息,由更小的 Level 块,以 链表 的形式存储。
其中每个节点都包含用于为之前版本的应用签名的签名证书,最旧的签名证书对应根节点,系统会让每个节点中的证书为列表中下一个证书签名,从而为每个新密钥提供证据来证明它应该像旧密钥一样可信。
这个过程有点类似 CA 证书的证明过程,已安装的 App 的旧签名,确保覆盖安装的 APK 的新签名正确,将信任传递下去。
注意: 签名方式只支持升级不支持降级,如安装了V2的包,不能覆盖替换为V1的包。
参考
Android App签名(证书)校验过程源码分析
新一代开源Android渠道包生成工具Walle
Android 签名机制 v1、v2、v3
那么安卓需要怎么配置才能支持>
Android为了保证系统及应用的安全性,在安装APK的时候需要校验包的完整性,同时,对于覆盖安装的场景还要校验新旧是否匹配,这两者都是通过Android签名机制来进行保证的,本文就简单看下Android的签名与校验原理,分一下几个部分分析下:
签名是摘要与非对称密钥加密相相结合的产物,摘要就像内容的一个指纹信息,一旦内容被篡改,摘要就会改变,签名是摘要的加密结果,摘要改变,签名也会失效。Android APK签名也是这个道理,如果APK签名跟内容对应不起来,Android系统就认为APK内容被篡改了,从而拒绝安装,以保证系统的安全性。目前Android有三种签名V1、V2(N)、V3(P),本文只看前两种V1跟V2,对于V3的轮密先不考虑。先看下只有V1签名后APK的样式:
再看下只有V2签名的APK包样式:
同时具有V1 V2签名:
可以看到,如果只有V2签名,那么APK包内容几乎是没有改动的,META_INF中不会有新增文件,按Google官方文档:在使用v2签名方案进行签名时,会在APK文件中插入一个APK签名分块,该分块位于zip中央目录部分之前并紧邻该部分。在APK签名分块内, 签名和签名者身份信息会存储在APK签名方案v2分块中,保证整个APK文件不可修改 ,如下图:
而V1签名是通过META-INF中的三个文件保证签名及信息的完整性:
V1签名是如何保证信息的完整性呢?V1签名主要包含三部分内容,如果狭义上说签名跟公钥的话,仅仅在rsa文件中,V1签名的三个文件其实是一套机制,不能单单拿一个来说事,
如果对APK中的资源文件进行了替换,那么该资源的摘要必定发生改变,如果没有修改MANIFESTMF中的信息,那么在安装时候V1校验就会失败,无法安装,不过如果篡改文件的同时,也修改其MANIFESTMF中的摘要值,那么MANIFESTMF校验就可以绕过。
CERTSF个人觉得有点像冗余,更像对文件完整性的二次保证,同绕过MANIFESTMF一样,SF校验也很容易被绕过。
CERTRSA与CERTSF是相互对应的,两者名字前缀必须一致,不知道算不算一个无聊的标准。看下CERTRSA文件内容:
CERTRSA文件里面存储了证书公钥、过期日期、发行人、加密算法等信息,根据公钥及加密算法,Android系统就能计算出CERTSF的摘要信息,其严格的格式如下:
从CERTRSA中,我们能获的证书的指纹信息,在微信分享、第三方SDK申请的时候经常用到,其实就是公钥+开发者信息的一个签名:
除了CERTRSA文件,其余两个签名文件其实跟keystore没什么关系,主要是文件自身的摘要及二次摘要,用不同的keystore进行签名,生成的MANIFESTMF与CERTSF都是一样的,不同的只有CERTRSA签名文件。也就是说前两者主要保证各个文件的完整性,CERTRSA从整体上保证APK的来源及完整性,不过META_INF中的文件不在校验范围中,这也是V1的一个缺点。V2签名又是如何保证信息的完整性呢?
前面说过V1签名中文件的完整性很容易被绕过,可以理解 单个文件完整性校验的意义并不是很大 ,安装的时候反而耗时,不如采用更加简单的便捷的校验方式。V2签名就不针对单个文件校验了,而是 针对APK进行校验 ,将APK分成1M的块,对每个块计算值摘要,之后针对所有摘要进行摘要,再利用摘要进行签名。
也就是说,V2摘要签名分两级,第一级是对APK文件的1、3 、4 部分进行摘要,第二级是对第一级的摘要集合进行摘要,然后利用秘钥进行签名。安装的时候,块摘要可以并行处理,这样可以提高校验速度。
APK是先摘要,再签名,先看下摘要的定义:Message Digest:摘要是对消息数据执行一个单向Hash,从而生成一个固定长度的Hash值,这个值就是消息摘要,至于常听到的MD5、SHA1都是摘要算法的一种。理论上说,摘要一定会有碰撞,但只要保证有限长度内碰撞率很低就可以,这样就能利用摘要来保证消息的完整性,只要消息被篡改,摘要一定会发生改变。但是,如果消息跟摘要同时被修改,那就无从得知了。
而数字签名是什么呢(公钥数字签名),利用非对称加密技术,通过私钥对摘要进行加密,产生一个字符串,这个字符串+公钥证书就可以看做消息的数字签名,如RSA就是常用的非对称加密算法。在没有私钥的前提下,非对称加密算法能确保别人无法伪造签名,因此数字签名也是对发送者信息真实性的一个有效证明。不过由于Android的keystore证书是自签名的,没有第三方权威机构认证,用户可以自行生成keystore,Android签名方案无法保证APK不被二次签名。
知道了摘要跟签名的概念后,再来看看Android的签名文件怎么来的?如何影响原来APK包?通过sdk中的apksign来对一个APK进行签名的命令如下:
其主要实现在 android/platform/tools/apksig 文件夹中,主体是ApkSignerjava的sign函数,函数比较长,分几步分析
先来看这一步,ApkUtilsfindZipSections,这个函数主要是解析APK文件,获得ZIP格式的一些简单信息,并返回一个ZipSections,
ZipSections包含了ZIP文件格式的一些信息,比如中央目录信息、中央目录结尾信息等,对比到zip文件格式如下:
获取到 ZipSections之后,就可以进一步解析APK这个ZIP包,继续走后面的签名流程,
可以看到先进行了一个V2签名的检验,这里是用来签名,为什么先检验了一次?第一次签名的时候会直接走这个异常逻辑分支,重复签名的时候才能获到取之前的V2签名,怀疑这里获取V2签名的目的应该是为了排除V2签名,并获取V2签名以外的数据块,因为签名本身不能被算入到签名中,之后会解析中央目录区,构建一个DefaultApkSignerEngine用于签名
先解析中央目录区,获取AndroidManifest文件,获取minSdkVersion(影响签名算法),并构建DefaultApkSignerEngine,默认情况下V1 V2签名都是打开的。
第五步与第六步的主要工作是:apk的预处理,包括目录的一些排序之类的工作,应该是为了更高效处理签名,预处理结束后,就开始签名流程,首先做的是V1签名(默认存在,除非主动关闭):
步骤7、8、9都可以看做是V1签名的处理逻辑,主要在V1SchemeSigner中处理,其中包括创建META-INFO文件夹下的一些签名文件,更新中央目录、更新中央目录结尾等,流程不复杂,不在赘述,简单流程就是:
这里特殊提一下重复签名的问题: 对一个已经V1签名的APK再次V1签名不会有任何问题 ,原理就是:再次签名的时候,会排除之前的签名文件。
可以看到目录、META-INF文件夹下的文件、sf、rsa等结尾的文件都不会被V1签名进行处理,所以这里不用担心多次签名的问题。接下来就是处理V2签名。
V2SchemeSigner处理V2签名,逻辑比较清晰,直接对V1签名过的APK进行分块摘要,再集合签名,V2签名不会改变之前V1签名后的任何信息,签名后,在中央目录前添加V2签名块,并更新中央目录结尾信息,因为V2签名后,中央目录的偏移会再次改变:
签名校验的过程可以看做签名的逆向,只不过覆盖安装可能还要校验公钥及证书信息一致,否则覆盖安装会失败。签名校验的入口在PackageManagerService的install里,安装官方文档,70以上的手机优先检测V2签名,如果V2签名不存在,再校验V1签名,对于70以下的手机,不存在V2签名校验机制,只会校验V1,所以,如果你的App的miniSdkVersion<24(N),那么你的签名方式必须内含V1签名:
校验流程就是签名的逆向,了解签名流程即可,本文不求甚解,有兴趣自己去分析,只是额外提下覆盖安装,覆盖安装除了检验APK自己的完整性以外,还要校验证书是否一致只有证书一致(同一个keystore签名),才有可能覆盖升级。覆盖安装同全新安装相比较多了几个校验
这里只关心证书部分:
Android V1及V2签名签名原理简析
仅供参考,欢迎指正
密码学的三大作用:加密( Encryption)、认证(Authentication),鉴定(Identification)
加密 :防止坏人获取你的数据。
鉴权 :防止坏人假冒你的身份。
认证 :防止坏人修改了你的数据而你却并没有发现。
1 URLEncode和URLDecoder 作用:URLEncode就是将URL中特殊部分进行编码。URLDecoder就是对特殊部分进行解码。
为什么URL要encode原因呢?
url转义其实也只是为了符合url的规范而已。因为在标准的url规范中 中文和很多的字符 是不允许出现在url中的。
2 Base64编码
为什么要进行Base64编码?
在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。
应用场景:主要是对于二进制数据进行编码,(文件、、加密后的二进制数据)
3 消息认证算法
要确保加密的消息不是别人伪造的,需要提供一个消息认证码(MAC,Message authentication code) 。
消息认证码是带密钥的hash函数,基于密钥和hash函数(单向散列函数)。
密钥双方事先约定,不能让第三方知道。
消息发送者使用MAC算法计算出消息的MAC值,追加到消息后面一起发送给接收者。
接收者收到消息后,用相同的MAC算法计算接收到消息MAC值,并与接收到的MAC值对比是否一样。
消息认证码的作用:检查某段消息的完整性,以及作身份验证。
防止重放 攻击可以有 3 种方法:
序号
每条消息都增加一个递增的序号,并且在计算 MAC 值的时候把序号也包含在消息中。这样攻击者如果不破解消息认证码就无法计算出正确的 MAC 值。这个方法的弊端是每条消息都需要多记录最后一个消息的序号。
时间戳
发送消息的时候包含当前时间,如果收到的时间与当前的不符,即便 MAC 值正确也认为是错误消息直接丢弃。这样也可以防御重放攻击。这个方法的弊端是,发送方和接收方的时钟必须一致,考虑到消息的延迟,所以需要在时间上留下一定的缓冲余地。这个缓冲之间还是会造成重放攻击的可趁之机。
nonce
在通信之前,接收者先向发送者发送一个一次性的随机数 nonce。发送者在消息中包含这个 nonce 并计算 MAC 值。由于每次 nonce 都会变化,因此无法进行重放攻击。这个方法的缺点会导致通信的数据量增加。
4 对称加密算法
特点:加解密只有一个密钥。优点:速度快、效率高。缺点:密钥交换问题。算法:AES(256字节,主流)、DES(8字节,淘汰)。
密钥交换问题如何解决,MAC同样也有这个问题,可以使用非对称加密传输,或者私下约定,密钥管理中心。
5 非对称加密
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密(这个过程可以做数字签名) 。 非对称加密主要使用的是RSA算法。
特点:公/私钥机制。优点:只需要交换公钥,安全。缺点:加解密速度慢,特别是解密。算法:RSA。应用:数字签名。
数字签名 :
简单解释:
A:将明文进行摘要运算后得到摘要(消息完整性),再将摘要用A的私钥加密(身份认证),得到数字签名,将密文和数字签名一块发给B。
B:收到A的消息后,先将密文用自己的私钥解密,得到明文。将数字签名用A的公钥进行解密后,得到正确的摘要(解密成功说明A的身份被认证了)。
数字证书 :
6 Android端 AES+RSA结合实践
基本流程
Android端
服务器端
基本上如下图所示的流程:
求问android怎么在代码里获得系统文件的读写权限?
本来以为就没有办法在应用程序这一层改系统时间了,后来在网上搜了好久,知道这个目的还是可以达到的。
第一个方法简单点,不过需要在Android系统源码的环境下用make来编译:
1 在应用程序的AndroidManifestxml中的manifest节点中加入
android:sharedUserId="androiduidsystem"这个属性。
2 修改Androidmk文件,加入LOCAL_CERTIFICATE := platform这一行
3 使用mm命令来编译,生成的apk就有修改系统时间的权限了。
第二个办法麻烦点,不过不用开虚拟机跑到源码环境下用make来编译:
1 同上,加入android:sharedUserId="androiduidsystem"这个属性。
2 使用eclipse编译出apk文件,但是这个apk文件是不能用的。
3 用压缩软件打开apk文件,删掉META-INF目录下的CERTSF和CERTRSA两个文件。
4 使用目标系统的platform密钥来重新给apk文件签名。这步比较麻烦,
首先找到密钥文件,在我的Android源码目录中的位置
是"build argetproductsecurity",下面的platformpk8和platformx509pem
两个文件。
然后用Android提供的Signapk工具来签名,signapk的源代码是
在"build oolssignapk"下,
用法为"signapk platformx509pem platformpk8 inputapk outputapk",
文件名最好使用绝对路径防止找不到,也可以修改源代码直接使用。
这样最后得到的apk和第一个方法是一样的。
最后解释一下原理,首先加入android:sharedUserId="androiduidsystem"这个属性。通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中。那么把程序的UID配成androiduidsystem,也就是要让程序运行在系统进程中,这样就有权限来修改系统时间了。
只是加入UID还不够,如果这时候安装APK的话发现无法安装,提示签名不符,原因是程序想要运行在系统进程中还要有目标系统的platform
key,就是上面第二个方法提到的platformpk8和platformx509pem两个文件。用这两个key签名后apk才真正可以放入系统进程中。第一个方法中加入LOCAL_CERTIFICATE := platform其实就是用这两个key来签名。这也有一个问题,就是这样生成的程序只有在原始的Android系统或者是自己编译的系统中才可以用,因为这样的系统才可以拿到 platformpk8和platformx509pem两个文件。要是别家公司做的Android上连安装都安装不了。试试原始的Android 中的key来签名,程序在模拟器上运行OK,不过放到G3上安装直接提示"Package has no signatures that match those in shared user androiduidsystem",这样也是保护了系统的安全。
android怎么在代码里获得系统文件的读写权限Java代码 1、必须是Android系统开发人员,否则你无法修改initrc等文件。 2、你的应用程序必须要获得system权限。 在应用层 你要想用代码获得系统文件权限,除非你手机root了 要么你自己坐rom。。。。 自己修改 init,rc
win10怎么获得修改系统文件的权限方法/步骤
1
首先找到你要 *** 作的文件夹,这里用一个声卡相关的文件夹做例子。选中文件夹。右击它。选择文件的属性,安全--->高级。
2
更改所有者,如图所示。在输入对象名称那儿,输入你的账户名称,我的是微软账户。输入完之后确定。
3
回到刚才的界面,你会看到所有者已经改变了,变成了你的账号。然后确定退出,回到文件夹。(一定要确定后退出回到文件中,才能进行下一步)
4
再次回到刚才的界面。禁止所有继承。
5
添加用户。输入账号,我输入的是微软账号。输入后确定。
手机获得root 权限 怎么找到系统文件通过第三方软件获得Root权限,可以访问和修改手机 *** 作系统里几乎所有的文件,但这样 *** 作有可能影响手机的稳定性,出现死机、重启等人为性故障。
另外获取权限后一般对存储器和CPU等主板上主要部件引起不良。Root属于修改 *** 作系统软件,按照条例不属于包修范围。为了提升顾客满意度,对Root顾客提供免费升级固件服务,如果Root已影响到手机硬件需要更换主板,则需要收取主板费用。
若您的机器Root后需将机器恢复到原来的系统版本,请将机器送到服务中心,由售后工程师帮助检查处理。自行将设备恢复出厂设置是无法取消Root权限的。
求问如何恢复系统文件的默认权限?对于已经获取所有权限的文件,建议大家还是恢复到原来的状态。今天就跟大家分享一下如何恢复系统文件的默认权限,Windows 7和Windows 8系统都是一样的 *** 作步骤。这里以平时最常修改的hosts文件为例,下图显示已获取hosts文件所有权限。已获得所有权限的hosts文件恢复权限有点类似于于逆向 *** 作,首先点选Administrators组(上图蓝色条),然后点击下方的“高级”按钮,切换到“所有者”标签。高级安全设置-所有者在上面的窗口中,点击“编辑”按钮打开新窗口来更改所有者。编辑所有者到这一步,你会发现可更改的所有者并没有当初替换时的TrustedInstaller,怎么办?别急,点击“其他用户或组”来添加它。在新开的窗口里,输入:NT SERVICE\TrustedInstaller,注意前面的NT SERVICE一定要加上,否则系统不认。添加TrustedInstaller用户完成后点击确定回到上一窗口,此时会看到TrustedInstaller用户出现了,接下去就是选择它,然后一路确定退出各个窗口。文件所有权恢复到默认状态
如何用代码读取查看文件的读写权限???File类里面就有canRead,canWrite,canExecute方法啊。 查看原帖>>
麻烦采纳,谢谢!
获得root权限后怎么样删除系统文件啊?用re
新手求助,获得TOOR权限后,怎么替换系统文件呀!先耐心的把这里的帖子看上几页,再多百度百度资料,不要手机一上手就玩这些要root权限的内容,容易出问题,到时候问题越来越多。。。建议至少2周后再做这些事情,对你会很有帮助。 查看原帖>>
iMac win7下怎么获得权限能读写Mac的文件对于一般文件来说,是不需要开启administrator账户的,只需要一个简单的办法就OK啦!比如说,对待下面的这种类型的文件夹。
2
我们只需要击右键,选择“管理员取得所有权”即可。
3
对于一些程序文件来说,只需要你击右键,选择“以管理员身份运行”,也是一个非常便捷的获得管理员权限的办法。
END
开启Administrator账户的方法
Windows 7系统中,administrator账户并不是默认开启的,那么就需要我们手动开启,这也不是很难的啦!对计算机图标,击右键,选择管理。
打开界面后,选择本地用户和组,单击用户,选择administrator账户即可。
3
打开,administrator账户之后,按照以下的 *** 作来进行就行了。
4
这样,在开始登陆的界面,即可以出现administrator账户了,选择此账户即可获得管理员最高权限,不过建议一般来说此账户还是不要开启的好,如果此账户受损,再创建帐户很容易失败。还有,在第一次开启此账户时,是不需要密码的。
android怎么获取文件夹权限代码这个问题其实LBE已经解决了。 1在2012隐私保护版中,每次运行时请求系统root,创建一个开机启动服务libloadso,专门用于处理lbe自身的root请求。 2在2013免root版中,首次运行时自动获取系统root,并把破解过的su文件复制到/system/xbin/sv ,然后给6755的权限,专门用于处理lbe自身的root请求。 上述两种方案,均为程序自带root管理,用于解决其自身root请求。 以下代码即为方案2的原理,附件中为修改过的su文件。 安卓的su文件,基本原理为 1234567if (pid=DB(Allow)) then "get uid=0 root" 白名单,程序获取rootelseif (pid=DB(Disable)) Return 黑名单,返回空else View"superuseractive" 数据库无记录,“授权管理”d出root请求窗口endif修改后的su文件 1if (pid<>"") then "get uid=0 root" 无条件,返回root 我反编译bapk,然后把java应用调用runtimeexec("su")的代码全部改为runtimeexec("sa"), 然后重新打包签名好。安装这个软件。 用RE文件管理器把上面附件的su改名为sa,复制到/system/xbin/sa并改权限rwsx-rsx-r。 以后使用bapk,获取root权限没有任何提示。 suzip大小:24985K 已经过百度安全检测,放心下载 点击下载下载量:133
所有的概念都基于一个非常重要的基础:
rsa 非对称加密算法 :
先感受下几个概念
PKI。
PKI是公钥基础设施(Public Key Infrastructure) 包括PKI策略、软硬件系统、证书机构CA、注册机构RA、证书发布系统和PKI应用等。
我们关注就俩东西: PKCS 证书机构CA 。前者是定义加密算法,签名,证书相关的各种事情采用的协议。后者可以为我们颁发权威的证书。
PKCS :
PKCS(The Public-Key Cryptography Standards )是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。RSA算法可以做加密、解密、签名、验证,还有RSA的密钥对存储。这些都需要标准来规范,如何输入,如何输出,如何存储等。
PKCS。全称是公钥密码学标准, 目前共发布过 15 个标准,这些标准都是协议。总结一下 就是对加密算法,签名,证书协议的描述。下面列举一些常用的协议,这些协议在本文都会对应上。
这些协议具体的实现就体现在openssl等工具中, 以及jdk工具keytool jdk java第三方库bouncycastle。
比如用openssl 如何生成公/私钥(PKCS#1)、签名(PKCS#1 )、签名请求文件(KCS#10)、 带口令的私钥(PKCS#8)。 含私钥的证书(PKCS#12)、证书库(PKCS#12)
其中涉及到算法的基础协议PKCS#1等,由于涉及到密码学原理所以我们并不需要深究它,只要知道怎么做就可以了。
现实中我们要解决这样一种情况:
客户端和服务器之间的数据要进行加密。需要两个达成同一个对称秘钥加密才行,那么这个秘钥如何生成,并在两边都能拿到,并保证传输过程中不被泄露。 这就用到非对称加密了。 后续的传输,就能用这个 对称秘钥来加密和解密了。
还有这样一个问题:
就是客户端如何判断服务端是否是合法的服务端。这就需要服务端有个id来证明它,而这个id 就是证书,而且必须是权威机构颁发的才能算是合法的。
因为客户端即浏览器,认定证书合法的规则必须通过第三方来确认 即ca颁发的证书。否则就我可能进了一个假网站。
而这两个问题 都是ssl协议要解决的内容。
所以ssl协议做了两件事情,一是验证身份,二是协商对称秘钥,并安全的传输。 而实现这个过程的关键数据模型就是证书, 通过证书中的ca对证书的签名,实现了身份验证,通过证书中的公钥,实现对对称秘钥加密,从而实现数据保密。 其实还顺手做了一件事情就是通过解密签名比对hash,保证了数据完整性。
明白ssl协议 首先明白几个重要的概念:
证书: 顾名思义就是提供了一种在Internet上验证通信实体身份的方式,数字证书不是数字身份z,由权威公正的第三方机构,即CA(例如中国各地方的CA公司)中心签发的证书, 就是可以认定是合法身份的。客户端不需要证书。 证书是用来验证服务端的。
一般的证书都是x509格式证书,这是一种标准的证书,可以和其他证书类型互相转换。完整来说证书包含,证书的内容,包括 版本号, 证书序列号, hash算法, 发行者名称,有效期, 公钥算法,公钥,签名(证书原文以及原文hash一起签名)而这个内容以及格式 都是标准化的,即x509格式 是一种标准的格式。
签名: 就用私钥对一段数据进行加密,得到的密文。 这一段数据在证书的应用上就是 对证书原文+原文hash进行签名。
谁签的名,就是用谁的私钥进行加密。就像身份z一样, 合法的身份z我们都依据是政府签的,才不是假证, 那就是浏览器会有政府的公钥,通过校验(解密)签名,如果能够解密,就可以确定这个就是政府的签名。就对了。
hash算法 :对原始数据进行某种形式的信息提取,被提取出的信息就被称作原始数据的消息摘要。比如,MD5和SHA-1及其大量的变体。 hash算法具有不可逆性,无法从摘要中恢复出任何的原始消息。长度总是固定的。MD5算法摘要的消息有128个比特位,SHA-1算法摘要的消息最终有160比特位的输出。
ca机构: 权威证书颁发机构,浏览器存有ca的公钥,浏览器以此公钥来验证服务端证书的合法性。
证书的获取: 生成证书申请文件csr(涉及到PKCS#10定义的规范)后向ca机构申请。 或者自己直接通过生成私钥就可以一步到位生成自签名证书。 自签名证书就是用自己的私钥来签名证书。
那么为了体现到 证书身份认证、数据完整、保密性三大特性 ,证书的简化模型可以认为包含以下两个要素:服务器公钥,ca的签名(被ca私钥加密过的证书原文+原文hash),
身份认证:
浏览器存有ca公钥,用ca公钥解密网站发给你的证书中的签名。如果能解密,说明该证书由ca颁发,证书合法。 否则浏览器就会报警告,问你是否信任这个证书,也就是这个网站。这时候的证书可以是任何人签发的,可以自己签发的。 但是中间人攻击。 完全伪造新的证书, 这就没有办法了。 所以还是信任证书的时候要谨慎。
数据完整:
如果你信任该证书的话,这时候就会用证书中的公钥去解密签名,如果是ca签发的证书,那么之前就已经通过ca的公钥去解密签名了。 然后得到证书hash,然后在浏览器重新对证书做hash,两者比对一致的话,说明证书数据没有被篡改。
保密性:
使用证书的公钥对对称秘钥加密保证传输安全,对称秘钥生成后,后续的传输会通过对称秘钥来在服务端和客户端的加解密。
那么ssl协议的具体过程就是:
4网站接收浏览器发来的数据之后 使用自己的私钥校验签名,并对原文进行hash 与解密出的hash 做比对检查完整性。然后发送编码改变通知,服务器握手结束通知(所有内容做hash )。 发送给客户端校验。
5 客户端校验,校验成功后,之后就用 对称秘钥进行通信了。
总共的过程是 c-s-c- s-c 四次握手。
四次握手简单来说分别是:
1请求获取证书
2服务端返回证书,客户端验证了证书的合法性和完整性,同时生成了对称秘钥。
3客户端把加密的 对称秘钥发给服务器。服务器检查真实性和完整性。
4服务端返回握手结束通知,客户端再检查一次真实性和完整性。
前两次握手是明文, 后两次握手是密文。 所以都要检查身份真实性和数据完整性。
ca的作用:
ca起到一个权威中间人的角色,如果脱离了ca, 那么证书还是证书,还能加密,保证数据完整性。 但是无法应用在客户端去认定服务器身份合法这个场景下。
下面就详细说下 脱离了ca签发的证书的应用:
自签名证书:
证书如果没有权威机构的签名,就是没有权威机构给你签发身份z。 那么这时候身份认证的场景变了。
这时候的认证场景就变成了,不再是某个官方权威说了算,而是假设第一次碰到这个证书,会认为,这个证书与之捆绑的实体之间是合法的并做记录。如果当这个实体下次捆绑了另一个证书,那么就是非法的。
这种情况常用于android中安装和校验app的时候,会先假设第一次安装的是合法的应用,认定这个app证书中的公钥是合法的公钥。然后通过自签名的证书,校验签名,就能实现后续安装是否合法以及完整性。
android中的如何对app进行身份认定和不被篡改:
android系统在安装app时候会进行校验applicationId,applicationId 不同会认定为不同应用。相同应用,第二次安装会校验证书是否和之前app的证书相同,如果相同则两个包很可能来自同一个身份。 如果证书不同,也就是该包被另一个身份用自己的私钥重新签名过,就会拒绝安装。 然后通过公钥来解密签名,如果能解密,说明身份是ok的。否则拒绝安装。比对解密签名后的hash 与apk包内的certsf文件(该文件是apk内所有文件生成的hash文件)是否一致,如果相同则认定为没有被篡改。
android在提交应用商店的问题:
应用商店也会校验 后续的上传和第一次上传时的证书,以及类似上述的后续的一系列校验。防止合法的开发者平台被盗后,上传非法应用。
android在接入第三方sdk的问题:
接入第三方sdk 会提交applicationId 和 sha1 值。 这个sha1值就是对 证书原文的签名后的sha1,也就是证书指纹。这个证书是证书库里最初的那个证书(x509格式),而不是对apk签名后生成的证书(PKCS#7)。一般的证书签名的主体是证书原文本身,而对apk签名还额外会对apk所有文件生成的hash值文件(certsf)进行一次签名。
第三方平台会记录 applicationId 与sha1 的对应关系。 当有假冒app试图接入时候,由于会对app内的PKCS#7证书转换为原始的x509格式证书,重新生成sha1值,与用户提交sha1 比对, 如果相同则说明证书很可能是ok的。 因为sha1就是证书的指纹。 之后就会通过证书中的公钥来校验签名,从而最终确认身份合法性以及信息完整性。
第三方平台之所以需要用户去提交证书指纹sha1值,多了这一步,就意味着你的证书是可以更换的,一旦更换了证书,就必须提交新的指纹给我,然后我来做匹配。而应用商店没有这个功能, 一旦你的证书的私钥丢了, 那就必须重新建一个新的app。
总结来看证书的身份认定机制:
在ssl协议下,这种场景是 浏览器用于认定合法的服务器身份。 在自签名证书下,需要用户选择是否信任该证书。
在android app采用自签名证书的场景下, 证书起到了 假设第一次的证书合法,公钥合法,后续如果证书不一致或不能够完成签名校验,就是非法。
证书库:
证书库应该满足PKCS#12协议。 但是jdk提供了制作证书的工具keytool 可以生成keystore类型的证书库,后缀为jks。 keystore pk12可以通过keytool命令互相转换。
证书库是个证书的容器, 可以用来创建数字证书。 在keystore证书库中,所有的数字证书是以一条一条(采用别名alias区别)的形式存入证书库的。证书库中的证书格式为pk12,即包含私钥。 如果导出证书的话, 可以导出为x509不包含私钥的格式 或者pk12包含私钥的证书。 也可以也可以用-import参数加一个证书或证书链到信任证书。
android中一般都采用读取证书库的方式,通过证书库来创建一个证书,通过alias来区分。 所以在签名的时候,一个alias是一个证书,不同的alias是不同的证书,不要搞错了。
几个关系:
证书和非对称加密算法的关系:
证书代表一个身份的主体,包含了非对称秘钥体系中的公钥,以及用私钥对证书签名。这种组织结构,把非对称加密算法从加密的功能,拓宽到了用于身份认证,信息完整性上。这体现在了证书的作用。 本质还是利用了非对称加密算法的特性。
ssl协议和证书的关系。
因为证书解决了客户端对服务器的身份认证(自签名证书除外),同时也解决了加密,和信息完整性,所以ssl协议基于证书来实现。
利用 Android 密钥库系统,您可以在容器中存储加密密钥,从而提高从设备中提取密钥的难度。在密钥进入密钥库后,可以将它们用于加密 *** 作,而密钥材料仍不可导出。此外,它提供了密钥使用的时间和方式限制措施,例如要求进行用户身份验证才能使用密钥,或者限制为只能在某些加密模式中使用。
密钥库系统并不是让程序直接进行存储程序的私密信息的,比如说用户账号密码,其提供了一个密钥安全容器,保护密钥材料免遭未经授权的使用,一个应用程序可以在密钥库中存储多个密钥并且只允许应用自身访问,应用程序可以在密钥库系统中生成,存储,获取存储其中的公钥或者私钥,因此可使用密钥库系统中的密钥来进行数据的加密。
密钥库系统由 KeyChain API 以及在 Android 43(API 级别 18)中引入的 Android 密钥库提供程序功能使用。
安卓系统提供了下面几种KeyStore类型:
各种类型的详细说明可以参考: >
以上就是关于Android基础『V1V2V3签名』全部的内容,包括:Android基础『V1V2V3签名』、android 基于okHttpClient开发https自签名请求、Android V1及V2签名原理简析等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)