精华内容
下载资源
问答
  • 2 Android使用数字签名的场景 2.1 未签名的APK VS 签名后的APK 2.2 应用层面:Android对APK的签名要求 2.2.1 Android拒绝安装没有签名的APK 2.2.2 Android不校验证书的合法性 2.2.3 当签名不匹配时,APK升级会...

    目录

    1 数字签名介绍

    1.1 背景

    1.2 机制

    1.3 使用

    1.3.1 ssh-keygen

    1.3.2 keytool

    2 Android使用数字签名的场景

    2.1 未签名的APK VS 签名后的APK

    2.2 应用层面:Android对APK的签名要求

    2.2.1 Android拒绝安装没有签名的APK

    2.2.2 Android不校验证书的合法性

    2.2.3 当签名不匹配时,APK升级会失败

    2.3 系统层面:Android基于数字签名的一些机制

    2.3.1 四种不同类型的签名

    2.3.2 应用的授权

    2.3.3 SELinux根据签名给APK打标签(Labling)

    3 总结


    本文以Android 7.1的代码为蓝本,部分源码在不同Android版本上略有区别。

    1 数字签名介绍

    本节的内容概要如下:

    • 首先,介绍数字签名的产生背景,有什么用途以及怎么用,涉及到经常被拿出来比对的概念:数字签名(Digital Signature)电子签名(Electronic Signature)

    • 然后,介绍数字签名的运行机制,数据加密和认证的过程,涉及到的重要概念:密钥对(Key Pair),即私钥(Private Key)和公钥(Public Key)

    • 最后,通过介绍两个与数字签名相关的工具ssh-keygenkeytool,一个密钥管理文件keystore,引申出几个重要的概念:证书(Certificate)证书链(Certificate Chain)证书认证机构(Certificate Authority)

    1.1 背景

    Digital Signature直译成中文就是数字签名,是Whitfield Diffie和Martin Hellman早在1976年就提出的概念,以他们名字命名的Diffie-Hellman Key Exchange算法可以用于在公开网络上传送密钥。 随后,由Ron Rivest, Adi Shamir和Leonard Adleman三人发明的RSA算法,被广泛运用到数字签名中。首个投放到市场的数字签名应用在1989年发布,采用的算法就是RSA。

    签名有什么用呢?

    生活中,大家一定有签名表身份的经历,譬如:在刷银行卡消费时,需要签上自己的大名,收银员有时还会对比一下你签的名与银行卡上签名栏是否匹配;在签署合同时,往往需要潇洒的挥上自己的大名,甚至手抹红印,按下指纹。这些都是为了确定行为人的身份,作为后续问题追溯的依据。数字签名的签名两字正是源于生活,意在确定身份,而数字两字表明其是签名的一种类型:基于密码学的签名方式。被数字签名广泛采用的RSA算法就是一种加密算法。

    数字签名怎么用呢?

    在网络发送信息时,存在安全问题,因为在发送者和接收者之间可能存在第三者,截获发送者信息,进行篡改后,再发送给接收者。为了解决这类安全问题,发送者可以对数据进行数字签名,当接收者拿到一堆签名后的数据时,可以对数据进行校验,一旦校验成功,接收者可以信心满满的说:

    • 这些数据一定是某人发送过来的,可以通过其他机构确定发送人的资质。
    • 发送者不可抵赖这是自己发送的,一旦接收者一口咬定数据是来源于某位发送者,那发送者只能心服首肯。
    • 这些数据一定没有被篡改,否则不会通过校验。

    这其实就是数字签名的三大特性:可认证性(authentication)、不可抵赖性(non-repudiation)和完整性(integrity)。即便收到被第三者篡改的数据,接收者也可以确定数据不是来源于受信的发送者,而且数据肯定被动过。

    自古以来,手写签名、按压指纹这种传统的签名方式都是具有法律效应的。在电子信息如此发达的今天,电子签名(Electronic Signature)也是被很多国家和地区(欧盟、美国)也被立法保护。读者在接触数字签名的概念时,往往会关联到电子签名的概念,前者属于技术实现的范畴,后者属于人文律法的范畴。

    人们认可电子签名在法律上的有效性,而数字签名采用一定的加密算法,来保障电子签名的这种有效性。诚然,加密算法总有过时的一天,譬如广泛应用的低位数的RSA算法就已经被破解了,这时候,电子签名的有效性就消失了,需要进一步更新数字签名的算法,继续维持电子签名的法律有效性。

    这里,还需要说明一点,并非所有的电子签名实现都是采用数字签名。

    1.2 机制

    数字签名是如何保证可认证、不可抵赖和完整性的呢?这得从数字签名的算法说起。数字签名的实现包含三个算法:

    1. 密钥生成算法。数字签名采用的是非对称密钥生成算法,即会生成一对密钥:私钥和公钥。用私钥加密的数据,只能用对应的公钥解密。私钥是应该要保护起来,不会泄露给其他人;公钥是完全公开的,会随着加密数据一起在公开网络上传送。

    2. 签名算法。给定私钥(private key)和数据(message),可以生成一个签名(signature)。

    3. 签名验证算法。给定数据(message)、公钥(public key)和签名(signature),可以解密数据并验证数据的来源和完整性。

    密钥有对称(symmetric)和非对称(public)之分。对称密钥只有一个,同时用于加密和解密,就像我们用同一把钥匙开门和锁门,谁拿到钥匙,谁就掌握了房间的使用权。DES和AES这种加密算法采用的是对称密钥,而上文提到的RSA算法采用的是非对称密钥。

    下图示意了数字签名的运行机制:

    数字签名机制

    • 对待发送的数据明文进行Hash,通常可采用MD5或SHA算法,然后采用私钥对Hash值进行加密,得到签名。将数据明文和签名一同发送出去。为什么要先对原始数据进行Hash后再用私钥加密呢?因为原数据可能比较大,直接使用私钥加密将会非常耗时。

    • 接收数据以后,会经过签名验证,其实就是比较两个Hash值:采用同样的Hash算法对数据明文进行解密,得到一个Hash值;采用公钥对签名进行解密后,得到原始的Hash值。如果两个Hash值相同,则说明数据没有被篡改而且来源可信:

      • 如果用公钥解密成功,则说明公钥与签名的私钥是唯一配对的,即一定是某个私钥的签名,这就保障了来源不可抵赖。

      • 如果数据被篡改,则接收到数据的Hash值与解密后的Hash值不会相同,这就保障了完整性。

      • 接收到的公钥是可以由第三方权威机构(Certificate Authority)认证的,因此接收方可以验证来源是否可靠,这就可以保障来源的可认证性。关于CA认证我们后文再展开。

    说了这么多,其实数字签名最神奇的地方就在于密钥对:用私钥加密后的数据只能用对应的公钥解密。 RSA算法的理论根基是欧拉定理,可以参见RSA算法原理介绍。 

     

    1.3 使用

    了解数字签名的基本概念之后,就需要进一步了解一些数字签名的使用工具和衍生概念。

    1.3.1 ssh-keygen

    在使用SSH(Secure SHell)进行远程登录或其他网络请求时(譬如下载git库),会接触到ssh-keygen。相比Telent, FTP这些协议,SSH是安全的,因为可以使用ssh-keygen生成一对密钥,对通信过程进行加密,防止第三方攻击。

    举一个最常见的例子,github上的开源项目均支持通过SSH协议进行下载,这就需要在github上添加一个SSH Key,否则无法正常下载github上的项目。

    首先,会先在本地使用ssh-keygen命令生成一个密钥对:

    $ ssh-keygen
    Generating public/private rsa key pair.
    Enter file in which to save the key (~/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in ~/.ssh/id_rsa.
    Your public key has been saved in ~/.ssh/id_rsa.pub.
    The key fingerprint is:
    ac:70:ea:54:20:75:ce:8e:ec:ed:36:8f:b2:4a:3d:26 xo@X
    The key's randomart image is:
    +--[ RSA 2048]----+
    |    . .          |
    |   . +           |
    |  . . o          |
    |   o + .         |
    |    + + S        |
    |   o * .         |
    |  E B o          |
    | . =.oo.         |
    |  ..o+oo.        |
    +-----------------+

     

    该命令执行完后,会在用户目录下的.ssh子目录生成两个文件:id_rsaid_rsa.pub

    然后,便是将id_rsa.pub的文件内容粘贴到github的SSH Key中。完成配置后便可通过SSH下载远程代码,知其然却不知其所以然。在理解了数字签名的基本概念后,再来看这个过程:

    • ssh-keygen默认采用RSA算法生成了私钥(id_rsa)和公钥(id_rsa.pub)。上文中采用的是RSA 2048位的算法,因为256,512位的RSA算法已经被破解了。这里需要提出的是,除了RSA,还有其他密钥对的生成算法,譬如DSA(Digital Signature Algorithm)、EdDSA(Edwards-curve Digital Signature Algorithm)等,可以通过ssh-keygen-t参数指定密钥对的生成算法。

      使用ssh-keygen生成密钥对时,会提示输入一个口令(passphrase),用来保护私钥。口令采用的对称密钥加密算法,简单来说,口令就像银行卡密码一样,需要记在脑子里。

      公钥通常比较长,上文中RSA算法生成的公钥是2048位,为了便于描述和比对,采用MD5算法将公钥映射成128位的Hash值,通常用16进制表示,这一串Hash值就叫做指纹(Fingerprint)

    • 将公钥粘贴到github的SSH Key配置项中,能够免去不断输入用户名和密码的烦恼;同时,这说明公钥是完全公开的,但私钥(id_rsa)仍然是保存在本地的。当github收到从客户端发起请求时,会利用客户端的公钥对一串随机数进行加密操作,然后将密文发送给客户端;客户端在收到密文后,会用配对的私钥进行解密,如果解密成功,便可建立一个受信的连接,不用再通过用户名和密码鉴权。

    除了github,还有很多代码管理工具都支持SSH,譬如gitlab,oschina,gerrit等,其操作过程都是一致的。因为SSH利用数字签名,建立了安全的连接。

    1.3.2 keytool

    keytool是JDK的一个工具,用于密钥和证书的管理。keytool的主要操作对象是keystore文件,该文件一般以.keystore或.jks(Java KeyStore)为后缀名,用于密钥和证书的存储,其存储结构如下图所示:

    keystore的存储结构

    keystore可以存储多个密钥对(Key Pair),每一个密钥对包含私钥(Private Key)和多个证书(Certificate)。想必诸位读者一定心生怪异了,上文说的密钥对都是一个私钥和一个公钥配对,然而keystore中存储的却是私钥和多个证书的配对,到底密钥对是怎么一样对应关系呢?这里有必要把证书和公钥的关系说明清楚了。

    证书(Certificate)

    如其名,用来证明真伪,就像一家企业的营业执照、大学生的毕业证一样,可用来证明其标的物的合法性,数字签名中的证书就是用于证明公钥的合法性。前文中提过,数字签名算法具备可认证性,然而公钥是完全公开的,很容易被伪造,这样一来,给定一个公钥是无法认证其合法性的,因此,需要给公钥“颁发”一个证书,其实现手段就是给公钥再签名一次,得到的结果就是证书。上图中,展示了一个完整的证书所包含的属性:Version、Subject、Issuer、Valid From、Valid Until、Public Key(待签名的公钥)、 Signature Algorithm(对公钥签名采用的数字签名算法)、Fingerprint(对公钥签名的公钥)。

    至此,我们知道证书和公钥的关系了:证书就是对公钥再次签名产生的结果,证书包含被签名的公钥、公钥拥有者的信息以及对公钥进行签名的公钥。 接下来,还有两个重要的概念:证书认证机构CA(Certificate Authority)证书链(Certificate Chain)。这两个概念在数字签名体系中经常出现,但并不容易理解。

    证书认证机构CA(Certificate Authority)证书链(Certificate Chain)

    上述证书的生成过程会导致一个无限的链条:要得到证书,就需要给公钥进行数字签名,这就有两个公钥了:证书本身的公钥(即证书中的Public Key,用公钥A表示)和数字签名算法的公钥(即证书中的Fingerprint,用公钥B表示),要保证公钥B的合法性,我们可以对公钥B再进行数字签名,就又会引入一个新的公钥C,由此类推,还会有公钥D、E、F…,公钥合法性的保证就像链条一样:层层相扣,无穷无尽。怎么办呢?要打破这个无限的链条,就需要有一个权威机构,来统一颁发证书,这个机构就是CA(Certificate Authority),只要是CA颁发的证书,就不需要再签名了,就是权威的。然而,全世界需要的证书太多了,光靠一个CA是忙不过来的,CA得授权一些代理,这些代理也可以颁发证书,代理颁发的证书也被认为是合法可信的,这就形成了一个证书认证的链条,即证书链。我们再回过来头来看一下keystore文件的结构:一个私钥(Private Key)与多个证书(Certificates)组成密钥对(Key Pair),其实多个证书的结构就是证书链

    要理解CA证书链,还是可以举毕业证的例子,我们的政府就可以看做一个CA,政府授权给教育部,教育部具备颁发和认证毕业证的职能;教育部再授权给各个高校,高校具备颁发自己学校毕业证的职能,教育部和高校就是不同级别的代理,授权过程就像链条一样。当我们要认证一个毕业证的真伪时,先拿到所属高校认证一下,如果高校无法确定合法,就拿到教育部认证一下,这种对毕业证的颁发和逐级认证的过程,就可以理解为证书链

     

    有了这么多概念储备后,就可以轻松理解keytool这个工具的使用了。如果将keystore看做密钥和证书管理的数据库,那么keytool就是这个数据库增、删、改、查的接口。 笔者在网上搜索keytool的使用,基本都是罗列keytool命令的各中参数,真心记不住啊!好在Eclipse/Android Studio这些IDE都集成了keysotre的图形化工具,为开发人员带来了在签名的便利。

    当然,除了Eclipse/Android Studio里面的keystore操作工具,还有很多其他好用的工具,笔者通过KeyStore Explorer工具打开Android的debug.keystore文件(位于~/.android/,存储了Android应用的默认签名),可以看到如下信息:

    keystore的存储内容

    通过keytool命令可以显示出相同的内容:

    duanqizhi@xo:~$ keytool -list -v -keystore ~/.android/debug.keystore
    Enter keystore password: # 此处需要输入keystore的口令: android
     
    Keystore type: JKS
    Keystore provider: SUN
     
    Your keystore contains 1 entry
     
    Alias name: androiddebugkey
    Creation date: Jul 1, 2015
    Entry type: PrivateKeyEntry
    Certificate chain length: 1
    Certificate[1]:
    Owner: CN=Android Debug, O=Android, C=US
    Issuer: CN=Android Debug, O=Android, C=US
    Serial number: 588a6601
    Valid from: Wed Aug 18 08:03:38 CST 2017 until: Fri Aug 11 08:03:38 CST 2047
    Certificate fingerprints:
          MD5:  DD:89:BB:7A:E2:49:66:E0:B5:2F:9C:CF:DB:3B:AB:26
          SHA1: 7B:DE:EF:7E:4A:25:8E:F8:08:0B:8D:28:32:0A:0A:3C:C6:50:D5:CB
          SHA256:
    27:E0:B8:9C:6B:4F:C6:88:25:7E:34:6E:93:7D:6C:F2:58:AC:64:02:2A:44:BB:17:23:19:E8:F4:8C:17:E6:30
          Signature algorithm name: SHA256withRSA
          Version: 3
     
    Extensions:
     
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
      KeyIdentifier [
      0000: 34 D2 8F 7A D4 AE FB 04   A8 0D 0E 7A D6 8C 3C 00 4..z.......z..<.
      0010: 9B 71 5A 61                                        .qZa
      ]
    ]
    
    *******************************************
    *******************************************

    可以为keystore文件设置一个口令,增强访问的安全限制。Android的debug.keystore口令就是android,我们通过Eclipse/Android Studio开发应用时,默认就会使用debug.keystore进行签名。该文件描述了以下信息:

    • keystore的文件格式为JSK(Java Key Store),技术提供商为SUN公司。

    • keystore存了一个记录:名为androiddebugkey的密钥对,其中有一个私钥和一条证书链,证书链中只有一个证书。

    • 证书的持有者和发布者都是CN=Android Debug, O=Android, C=US,Common Name是Android Debug,Organization Name是Android,Country是US。

    • 证书的有效期2017-8-18到2047-8-11;分别用MD5,SHA1,SHA256三种不同的Hash算法计算出了证书的指纹。

    • 证书中的公钥是采用RSA 1024算法生成的,格式是X.509,上述所定义的各种属性字段,就是X.509的标准。

    本节不再罗列keytool命令的其他参数,后文中还会使用keytool查看APK的签名信息。其实,最重要的还是理解几个关键概念:证书证书链证书认证机构,在当下的安全体系中,这几个概念出现的相当多,最有名的当属HTTPS

    2 Android使用数字签名的场景

    笔者把Android中数字签名的应用场景分为应用和系统两个层面,先抛出具体的场景,后文中再通过源码分析这些场景的实现方式。

    • 应用层面:Android对APK的签名要求

      • Android拒绝安装没有签名的APK
      • Android并不校验证书的合法性
      • 当签名不匹配时,APK升级会失败
    • 系统层面:Android基于数字签名的一些机制

      • 编译Android系统时,会根据不同应用的类型进行签名
      • Android基于数字签名来判定是否给应用授权
      • Android基于数字签名来标记APK的SELinux Lable

    2.1 未签名的APK VS 签名后的APK

    Android中的数字签名主要是针对APK的,因此有必要先介绍APK签名前后的差异。使用JDK的工具jarsigner便可对APK进行签名。

    duanqizhi@xo:~$ jarsigner -verbose \
       -keystore ~/.android/debug.keystore \
       -signedjar app-signed.apk app-unsigned.apk \
       androiddebugkey
    Enter Passphrase for keystore:  #此处输入密钥android
      updating: META-INF/MANIFEST.MF
        adding: META-INF/ANDROIDD.SF
        adding: META-INF/ANDROIDD.RSA
       signing: AndroidManifest.xml
       signing: classes.dex
       signing: res/anim-v21/design_bottom_sheet_slide_in.xml
       signing: res/anim-v21/design_bottom_sheet_slide_out.xml
       signing: res/anim/abc_fade_in.xml
       ... #此处省略很多对其他文件的signing日志
       signing: resources.arsc
    jar signed.

    该命令使用了前文介绍的Android Studio默认的keystore文件,其中存放了一对别名为androiddebugkey的密钥对。加上-verbose参数可以打印出具体对哪些文件进行过签名。

    APK文件其实就是压缩包,可以通过zip或tar等工具直接解压打开,对比签名前后的APK内容如下:

    app-unsigned                    app-signed
    ├── AndroidManifest.xml         ├── AndroidManifest.xml
    ├── classes.dex                 ├── classes.dex
    ├── META-INF                    ├── META-INF
    │   │                           │   ├── ANDROIDD.RSA
    │   │                           │   ├── ANDROIDD.SF
    │   └── MANIFEST.MF             │   └── MANIFEST.MF
    ├── res                         ├── res
    └── resources.arsc              └── resources.arsc

    由此可见,APK签名前后,只有META-INF目录发生了变化,签名后会更新MANIFEST.MF文件,会增加ANDROIDD.SFANDROIDD.RSA这两个文件,这与使用jarsigner签名时的日志输出是一致的。那么,META-INF/目录下,变化的这三个文件到底是什么呢?

    MANIFEST.MFANDROIDD.SF都是文本文件,直接打开可以看到其文件内容,通过bcompare对比工具查看其文件差异,截图片段如下图所示:

    清单文件

    MANIFEST.MF是APK包含文件的清单列表,记录了APK中每一个文件的SHA256摘要,前文介绍数字签名的时候说过,签名算法很耗时,因此不是对原文件执行加密算法,而是先生成原文件的摘要,再对摘要进行签名。由此,可以推断出ANDROIDD.MF文件的内容就是摘要密文。

    ANDROIDD.RSA其实是数字证书,RSA的文件后缀表示证书中包含了一个基于RSA算法生成的公钥。通过前文介绍的keytool命令,便可打印出该证书的信息,这与前文中keystore中打印的证书信息是一致的:

    duanqizhi@xo:~/app-signed/META-INF$ keytool --printcert
    -file ANDROIDD.RSA
    Owner: CN=Android Debug, O=Android, C=US
    Issuer: CN=Android Debug, O=Android, C=US
    Serial number: 588a6601
    Valid from: Wed Aug 18 08:03:38 CST 2017 until: Fri Aug 11 08:03:38 CST 2047
    Certificate fingerprints:
          MD5:  DD:89:BB:7A:E2:49:66:E0:B5:2F:9C:CF:DB:3B:AB:26
          SHA1: 7B:DE:EF:7E:4A:25:8E:F8:08:0B:8D:28:32:0A:0A:3C:C6:50:D5:CB
          SHA256:
    27:E0:B8:9C:6B:4F:C6:88:25:7E:34:6E:93:7D:6C:F2:58:AC:64:02:2A:44:BB:17:23:19:E8:F4:8C:17:E6:30
          Signature algorithm name: SHA256withRSA
          Version: 3
     
    Extensions:
     
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
    KeyIdentifier [
    0000: 34 D2 8F 7A D4 AE FB 04   A8 0D 0E 7A D6 8C 3C 00 4..z.......z..<.
    0010: 9B 71 5A 61                                        .qZa
    ]
    ]

    至此,APK签名前后的差异已经分析完毕。签名会在APK中的META-INF/目录下添加证书ANDROIDD.RSA和密文ANDROIDD.SF,有了这两个文件,就可以对APK进行校验了。

    2.2 应用层面:Android对APK的签名要求

    2.2.1 Android拒绝安装没有签名的APK

    通过命令行adb install安装一个没有签名的APK时,会提示INSTALL_PARSE_FAILED_NO_CERTIFICATES错误:

    duanqizhi@xo:$ adb install app-release-unsigned.apk
    5927 KB/s (2357317 bytes in 0.388s)
    Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES: Package /data/app/vmdl1995237626.tmp/base.apk has no certificates at entry AndroidManifest.xml]

     同时,会出现如下日志:

    1034  1271 E PackageInstaller: Commit of session 1995237626 failed: Package /data/app/vmdl1995237626.tmp/base.apk has no certificates at entry AndroidManifest.xml
    1034 11776 W System.err: java.lang.SecurityException: Caller has no access to session 1995237626
    1034 11776 W System.err: at com.android.server.pm.PackageInstallerService.abandonSession(PackageInstallerService.java:737)
    1034 11776 W System.err: at android.content.pm.IPackageInstaller$Stub.onTransact(IPackageInstaller.java:97)
    1034 11776 W System.err: at android.os.Binder.execTransact(Binder.java:574)

    要深入理解这些日志,需要对adb安装APK的原理有了解,然后才能分析Android是如何在APK安装路径上植入签名检查的。

    通过adb安装APK的时序可以分为三步:创建安装Session拷贝APK到手机上安装APK。这里引入了Session(会话)的概念,之所以要用Session,是为了保证安装过程中的数据不会丢失:如果一个APK的安装因为某种原因中断,那么下次系统重启后仍可以继续之前的安装过程。了解Session的用意后,我们接着分析adb安装APK的时序:如下图所示:

    APK的安装过程

    1. 创建安装的Session。这里出现的关键类是Pm.java,它是包管理相关的命令解析器。通过命令行输入adb installadb shell package命令就会交由Pm进行解析,对输入的命令解析完后,真正创建Session的操作是通过跨进程调用到PackageInstallerService.java中完成的。PackageInstallerService是运行在系统进程的,伴随着PackageManagerService的创建而创建,它的主要职责就是为安装APK服务,提供了很多操作Session的接口,其内部会维护所有安装的Sesssion,并将其Session的信息保存到磁盘文件/data/system/install_sessions.xml中,如果有安装有中断,则下次从该文件中读取信息便可恢复Session。

    Pm.run()
     └── Pm.runInstall()
         └── Pm.doCreateSession()
             └── IPackageInstaller.createSession()
                 └── Binder.execTransact()
                     ...
                     └── PackageInstallerService.createSession()

     

    2. 拷贝APK到手机。Session创建完后,要做的第一件事就是将待安装的APK拷贝到手机上,拷贝到手机上的哪个目录呢?创建Session的时候会根据APK的安装属性来做判定:如果安装到内置存储空间(通常就是Data分区),那会将APK拷贝到/data/app/vmdl+sessionId+.tmp/目录下;如果安装到外置存储空间(通常就是SD卡),那么将APK拷贝到外置存储空间/smdl+sessionId+.tmp/目录下,此处的sessionId是唯一的。在上文的日志中出现的/data/app/vmdl1995237626.tmp/base.apk其实表示当时安装的sessionId是1995237626

    3. 安装APK。前面的步骤创建了一个Session,保存了一些安装信息,并将APK拷贝到手机上,这个状态称为Staged,是一个临时状态,在安装APK时可以看到很多与Stage相关的关键字。对于一个Session而言,需要进行提交(commit),交给系统完成后续的安装操作。上文的时序图并没有把完整的函数调用逻辑示意出来,其实Session的commit操作路径还是较长的,具体如下:

     Pm.run()
     └── Pm.runInstall()
         └── Pm.doCommitSession()
             └── PackageInstaller.commit()
                 └── IPackageInstallerSession.commit()
                     └── Binder.execTransact()
                         ...
                         └── PackageInstallerSession.commit()
                             └── sendMessage(MSG_COMMIT)
    
     Handler.Callback.handleMessage(MSG_COMMIT)
     └── PackageInstallerSession.commitLocked()
         └── PackageInstallerSession.validateInstallLocked()
             └── PackageParser.parseApkLite()
                 └── PackageParser.collectCertificates()
                     └── PackageParser.loadCertificates()
         └── PackageManagerService.installStage()

     本文不再赘述路径上各函数的功能,只提出一点:要想知道APK中是否包含签名,就需要对读取APK文件的内容,这是由PackageParser.parseApkLite()完成的,在读取APK时,就会去找签名,这是通过PackageParser.loadCertificates()完成的。如果找不到签名,则会INSTALL_PARSE_FAILED_NO_CERTIFICATES异常,中断安装过程;如果找到签名,则会继续调用**PackageManagerService.installStage()完成后续的安装操作,更多安装操作的细节,请参考Android包管理机制一文。

    我们可以从数据库的事务操作来理解一个session,安装一个APK就可以理解为向系统添加一项APK记录的事务操作。创建一个事务(createSession),表达操作意图(writeSession),然后将事务提交(commitSession)。剩下的事情就交由系统完成了,系统进程会进入APK的安装阶段。

    理解了APK安装过程后,我们再回过头来看一下上文中提示安装错误的日志:

    1034  1271 E PackageInstaller: Commit of session 1995237626 failed: Package /data/app/vmdl1995237626.tmp/base.apk has no certificates at entry AndroidManifest.xml
    

    对于1995237626这个Session而言,Commit的时候出现了错误,这表示Session已经进入到了Commit阶段,APK已经拷贝到手机上/data/app/vmdl1995237626.tmp/base.apk(取名为base.apk是与APK的拆分有关,如果没有拆分,那base.apk就是待安装的APK)。出错的原因是找不到AndroidManifest.xml这个文件的证书,其实就是没有APK中没有签名信息啦~

    2.2.2 Android不校验证书的合法性

    Android拒绝安装没有签名的APK,但Android并不会校验APK证书的有效性,即只要签名正确,不管证书是不是合法的,Android都会安装。我们可以使用jarsigner工具对APK的证书进行校验,会出现如下的警告,但APK依旧可以正常安装。

    duanqizhi@xo:~$ jarsigner -verify app-signed.apk
    jar verified.
    
    Warning:
    This jar contains entries whose certificate chain is not validated.
    This jar contains signatures that does not include a timestamp.
    Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2047-08-11) or after any future revocation date.
    

    由于Android并不校验证书的合法性,因此我们无法判定一个安装的应用是否经由正规的公司发布。譬如,我们可以给微信进行重新签上自己生成的签名,还是可以正常安装,但这已经不是腾讯发布的微信了,Android系统对此并不感知。当然,微信自己会进行签名校验,发现签名不对会选择自行退出,但对于市面上绝大多数应用而言,都没有自校验签名。因此也就出现了一些无良的开发者,窃取别人的劳动成果,在已有APK中植入广告,重签名进行发布。

    数字签名的证书是可以交由第三方机构认证的,即由CA(Certifiacte Authoriy)颁发的证书是得到认可的。基于此,应用市场(譬如应用宝、豌豆荚等)可以对上架的应用进行证书的校验。

    2.2.3 当签名不匹配时,APK升级会失败

    如果一个APK的前后两个版本签名不一致,Android是拒绝升级的,这是一种基于数字签名对应用的保护机制。在此限定下,应用开发者需保持其签名一直不变。

    本文不再细述APK升级安装的过程,这个过程由PMS处理,读者其实可以猜到,无非就是在安装多了一个环节:与已安装的同包名应用进行签名比对。具体的细节可以参考Android包管理机制文中的应用安装一节。

    举一个例子,对一个应用签两次不同的名,通过adb install -r命令重复安装,便会升级签名不匹配的错误:

    duanqizhi@xo:~$ adb install -r app-signed-changed.apk
    1904 KB/s (2407277 bytes in 1.234s)
    Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.xo.demo signatures do not match the previously installed version; ignoring!]
    

    2.3 系统层面:Android基于数字签名的一些机制

    2.3.1 四种不同类型的签名

    Android预置的系统应用都是需要签名的,包括联系人、相机、设置等。Android设计了四种不同类型的签名:platformsharemediatestkey,默认置于在源码的build/target/product/security目录下,分别用于给不同类型的系统应用进行签名。从Android Lollipop开始,Android还对boot.img和system.img进行签名以防被篡改,所以在原来四组签名的基础上又增加了verity

    build/target/product/security
    ├── (media.pk8, media.x509.pem)       #用于给MediaProvider, Gallery等签名
    ├── (platform.pk8, platform.x509.pem) #用于给Settings, Phone等签名
    ├── (shared.pk8, shared.x509.pem)     #用于给Launcher, Dailer等签名
    ├── (testkey.pk8, testkey.x509.pem)   #用于给一般应用签名
    └── (verity.pk8, verity.x509.pem)     #用于给boot.img和system.img签名

     一共有五组密钥对,.pk8为私钥, .509.pem为证书(包含公钥),本质上,它们都是密钥对,并没有区别,只不过Android做了逻辑上的区分,后文我们再来介绍不同类型的签名各有什么用。先来看如何给系统应用设定签名类型,以下是packages/apps/Settings/Android.mk的内容片段,表示要编译Settings这个模块:

    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)
    ...
    LOCAL_PACKAGE_NAME := Settings
    LOCAL_CERTIFICATE := platform  #表示Settings需要采用platform密钥对进行签名
    LOCAL_PRIVILEGED_MODULE := true
    ...
    include $(BUILD_PACKAGE)

     

    设置Makefile的LOCAL_CERTIFICATE变量,就可以指定APK的签名类型了,编译系统会根据设定的变量值选取密钥对。

    在AOSP的源码中,上述的密钥对是完全公开的,只是为了完成签名操作,并没有安全性可言。OEM设备厂商都会自行生成密钥对,并将私钥(.pk8文件)保护起来。

    2.3.2 应用的授权

    Android包管理机制一文中,详细介绍了系统如何给应用授权,本文不再赘述,仅把与数字签名相关的应用授权提炼出来。

    先来看一个特殊的APK:framework-res.apk,其包名为android,在它的AndroidManifest.xml文件中,定义了一些系统权限:

      <!-- 安装应用的权限 -->
      <permission android:name="android.permission.INSTALL_PACKAGES"
          android:protectionLevel="signature|privileged" />
      <!-- 卸载应用的权限 -->
      <permission android:name="android.permission.DELETE_PACKAGES"
          android:protectionLevel="signature|privileged" />

     

    所有定义的权限都有一个protectionLevel属性,它表示一个权限的保护级别。其中部分权限的protectionLevel值包含signature,表示该权限的申请者必须与framework-res.apk的签名相同,系统才会授予申请者该权限。从framework-res.apk的Android.mk中,可以看出它签名类型为platform,这也就意味着如果想要获取系统中protectionLevel为signature的权限,就必须使用platform密钥对来签名应用。

    除了framework-res.apk,其他应用也可以定义属于自己的权限,同样可以设定protectionLevel,通过Android的权限授予机制来保护API,防止滥用。譬如在packages/apps/Launcer3/AndroidManifest.xml中,就定义了如下权限:

    <permission
        android:name="com.android.launcher3.permission.WRITE_SETTINGS"
        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
        android:protectionLevel="signatureOrSystem"
        android:label="@string/permlab_write_settings"
        android:description="@string/permdesc_write_settings"/>

    这就表明要想获取com.android.launcher3.permission.WRITE_SETTINGS这个权限,申请者要么与Launcher3具有相同的签名,要么是一个系统应用。

    正常情况下,普通的应用是无法获取一些受保护系统权限的,因为无法获得与系统应用相同的签名。试想如果一个恶意的应用获取了静默安装的系统权限,每天偷偷的下载安装应用,这是一件多么恐怖的事情。

    Android基于数字签名设计的应用授权,是一种灵活的授权机制,因为仅仅通过是否为系统应用来判定是否授权,有很多局限,譬如一些受信的应用没有安装在系统分区,就无法获取系统权限;两个普通的应用之间也无法定义受保护的权限。 有了数字签名,就相当于多了一种受信机制。两个不同的APK,签名相同,意味着来源相同,彼此是受信的。

    2.3.3 SELinux根据签名给APK打标签(Labling)

    Android Lollipop强制使用SELinux后,极大的增强了Android系统的安全性,关于SELinux的运行机制,各位读者可以从网上搜罗很多,本节意不在此,仅是为了介绍Android如何结合SELinux和数字签名为APK打上标签(所谓“标签”,是为了后文中描述的方便,在SELinux的概念中,其实叫SELinux Context)。有一些必要基础的背景知识:

    • 在SELinux环境下,所有的文件和进程都有标签(通过ls -Zps -Z命令可以查看),这个标签称为SELinux Context,是SELinux的权限控制的基础。

    • 部分标签是事先定义好的,譬如system/sepolicy/file_contexts文件中所定义的一些系统文件和目录的标签;部分标签是根据规则生成的,譬如在fork子进程时,会根据TE(Type Enforcement)文件中定义的规则,为子进程打上标签。

    以Settings为例,手机上的系统分区会存在Settings.apk这个静态的文件,运行ls -Z命令可以查看其SELinux标签:

    angler:/system/priv-app/Settings # ls -Z
    -rw-r--r-- 1 root root u:object_r:system_file:s0 Settings.apk

    Settings.apk的标签为u:object_r:system_file:s0,表示:

    • 该文件属于SELinux的用户u,Android下的SELinux只定义了一个用户,就是u

    • 该文件的角色为object_r,SELinux的规则文件中为不同的角色定义了不同的权限

    • 该文件的域为system_file,域的概念不是很好理解,姑且将其理解为操作对象,还有其他的域,譬如system_data_file, apk_data_file等,SELinux的规则文件中定义了一个角色对不同对象的操作权限

    • MLS(Multi-Level Security)级别0,目前Android中所有Label的级别都是S0,此处不展开讨论

    这个静态的Settings.apk文件的SELinux标签是怎么打上去的呢?在system/sepolicy/file_contexts文件中做了如下定义:

    ...
    #############################
    # System files
    #
    /system(/.*)?		u:object_r:system_file:s0
    /system/bin/atrace	u:object_r:atrace_exec:s0
    /system/bin/e2fsck	--	u:object_r:fsck_exec:s0
    /system/bin/fsck\.f2fs	--	u:object_r:fsck_exec:s0
    /system/bin/fsck_msdos	--	u:object_r:fsck_exec:s0
    /system/bin/toolbox	--	u:object_r:toolbox_exec:s0
    ...

    上面的代码片段表示对于/system/目录下的所有文件,如果没有特殊的指定,其SELinux标签就为u:object_r:system_file:s0/system/子目录也可以再重新指定,譬如/system/bin/toolbox,虽然也在/system目录下,但具体指定了其标签为u:object_r:toolbox_exec:s0

    当Settings运行起来后,系统中就存在一个Settings进程,通过运行ps -Z命令查看:

    angler:/system/priv-app/Settings # ps -Z | grep settings
    u:r:system_app:s0 system S com.android.settings
    

    对于Settings进程而言,SELinux标签的角色为r,域为system_app,这个标签与静态的Settings.apk文件不同,它是依据APK的签名打上去的,Android设计了一套为应用进程打标签的机制:维护签名到SELinux标签的映射表,记录在system/sepolicy/mac_permissions.xml中,其初始内容如下所示:

    <?xml version="1.0" encoding="utf-8"?>
    <policy>
        <signer signature="@PLATFORM" >
          <seinfo value="platform" />
        </signer>
    </policy>
    

    以上内容只是一个模板,表达的意思是:签名为@PLATFORM的APK所在的进程,其seinfo为platform。@PLATFORM编译后会被替换成真实的platfrom类型的签名,以下是mac_permissions.xml经过编译后的结果:

    <?xml version="1.0" encoding="iso-8859-1"?>
    <policy>
      <signer signature="308204a83...8b1b357">
        <seinfo value="platform"/>
      </signer>
    </policy>
    

    对于在Android.mk中声明LOCAL_CERTIFICATE := platform的应用来说,其seinfo就被标记为platform了,那么seinfo又是什么呢?frameworks/base/core/java/android/content/pm/ApplicationInfo.java文件中有其定义:

        /**
         * String retrieved from the seinfo tag found in selinux policy. This value
         * can be overridden with a value set through the mac_permissions.xml policy
         * construct. This value is useful in setting an SELinux security context on
         * the process as well as its data directory. The String default is being used
         * here to represent a catchall label when no policy matches.
         *
         * {@hide}
         */
        public String seinfo = "default";
    

    ApplicationInfo这个对象是表示一个应用程序的信息,其中一个属性就是seinfo,默认取值为default,最终取值会依据mac_permissions.xml而定。在system/sepolicy/seinfo_contexts文件中,定义了不同seinfo映射到的SELinux标签:

    isSystemServer=true domain=system_server
    user=system seinfo=platform domain=system_app type=system_app_data_file
    user=bluetooth seinfo=platform domain=bluetooth type=bluetooth_data_file
    user=nfc seinfo=platform domain=nfc type=nfc_data_file
    user=radio seinfo=platform domain=radio type=radio_data_file
    user=shared_relro domain=shared_relro
    user=shell seinfo=platform domain=shell type=shell_data_file
    user=_isolated domain=isolated_app levelFrom=user
    user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
    user=_app isAutoPlayApp=true domain=autoplay_app type=autoplay_data_file levelFrom=all
    user=_app isPrivApp=true domain=priv_app type=app_data_file levelFrom=user
    user=_app domain=untrusted_app type=app_data_file levelFrom=user
    

    Settings进程的seinfo为platform,进程所属的用户为system,那就匹配到了“user=system seinfo=platform domain=system_app type=system_app_data_file”这一条,表示Settings进程的域为system_app,其可操作的文件类型为system_app_data_file

    当APK的签名在mac_permissions.xml中没有匹配成功时,会默认设置seinfo为default,这样最终APK的应用进程的域就为untrusted_app。感兴趣的读者可以自行通过上文中的命令查看。

    用下图总结一下为应用进程打标签的过程:

    APK打标签的过程

    • 对APK进行扫描的时候,根据mac_permissions.xml中定义的签名=>seinfo映射,设置APK所对应的应用进程的seinfo属性

    • 当APK的应用进程启动时,根据seapp_contexts中定义的seinfo=>SELinux Context映射,设置进程的SELinux标签

    3 总结

    本文的目的是为了介绍数字签名在Android中的应用场景。

    首先,介绍了数字签名的背景,机制和常见的使用工具。对于数字签名(Digitial Signature)、电子签名(Electronic Signature)、证书(Certificate)、证书链(Certificate Chain)、证书认证机构(Certificate Authority)等概念做了比较通俗的解释。数字签名的实现基于非对称密钥算法,主要有签名和校验两个机制。使用数字签名可以保障可认证性(Authentication)、不可抵赖性(Non-repudiation)和完整性(Integrity),因此应用场景非常之广泛,譬如SSH、HTTPS、网银U盾、电子合同等。

    然后,分析了Android基于数字签名实现的一些安全机制,包括拒绝安装没有签名的应用、拒绝升级签名不匹配的应用、基于签名给应用授权、SELinux环境下基于签名打标签。在Android源码中,都能够找到这些机制的实现,读者可以重点学习Android是如何将数字签名机制嵌入到已有的代码流程中的。

    最后,数字签名还可以衍生出一些有意思的变种,譬如如何做到可抵赖(Repudiation),这在间谍领域是很有必要的,基于本文一开始提到的Diffie-Hellman Key Exchange算法就可以实现可抵赖性,有兴趣的读者可以继续研究。

    展开全文
  • 多重签名本质上很简单,就是在单个数字签名校验的基础上做一些组合。但这些简单的组合,却创造出了很多种有趣的应用。 基本原理 比特币的交易一般用的单个签名校验,可以这样理解:C把钱放进一个储物柜,然后用B...

    多重签名本质上很简单,就是在单个数字签名校验的基础上做一些组合。但这些简单的组合,却创造出了很多种有趣的应用。

    基本原理

    比特币的交易一般用的单个签名校验,可以这样理解:C把钱放进一个储物柜,然后用B的公钥给储物柜加锁,只有B能使用自己的私钥开锁,把钱取出来。而多重签名的交易,则可以理解为:C把钱放进储物柜后,不仅用B的公钥给储物柜加锁,还用自己的公钥加锁,甚至还使用第三方A(如中介或仲裁者)的公钥再加一道锁。而且这个储物柜非常智能,可以设置开了几道锁后,储物柜的门才打开。这样设定不同的开锁要求就可以得到不同的应用模型。

    应用场景

    共同账户

    例如夫妻双方建立的联合账户,有两种形式。一种是类似零钱账户,夫妻中任何一人都可以从中取钱,方便平时的小额消费。另一种类似储蓄账户,需要夫妻双方都同意,才能从中取钱,这样可以保证大额账户不会被单方面支出,保护共同财产的安全。前者相当于只需要开一道锁的储物柜,后者相当于两道锁都要开的储物柜。类似的还有公司合伙人的联合账户,可以设置需要多少人同意才能动用账户中的资金。

    托管和仲裁

    在淘宝上购物时,我们支付的货款会先由淘宝托管,等确认收货后,再由淘宝把货款转给商家。比特币也可以实现类似功能,而且托管方受到更多的约束,更难以作恶。在这种场景下,消费者和商家建立一个托管账户,消费者转账到这个托管账户时,用自己和商家以及仲裁方的公钥给账户加锁。接下来有三种情况:

    • 消费者收到的商品没有问题,跟商家达成一致,两者用自己的签名来解锁账户,并把钱转给商家。
    • 商品有问题,消费者要求退款,商家也同意,操作跟第一种情况类似,只不过最后把托管账户里的钱退给消费者,或者是以一定比例退款,其它的钱转给商家。
    • 商品有问题,但商家不同意退款,由仲裁者裁决。不管仲裁者最后是跟谁达成一致,最终都会得到两个签名来解锁账户,然后把钱转给卖家,或者是部分或全额退款给消费者。

    微支付

    比特币的《开发者指南》中有个微支付的例子。A为B兼职审核论坛发帖,A希望每审核一篇帖子就收到一份报酬,但因为比特币的交易费用,小额支付成功太高不划算。所以他们设计这样一套方案:

    • A和B设立一个共同账户,这个账户要两个人都签字同意才能取钱出来。B签署一份协议,转钱到这个共同账户,作为准备金,但这时并不公布这份协议。
    • B签署另一份协议,延迟24小时把共同账户的钱转回给自己。B和A都在这份协议上签字,但这份协议暂时不公开,只作为B在A没有正常工作时能收回准备金的凭据。然后A会公布第一份协议。
    • 接下来A开始工作,他每完成一个任务,会要求B签署一份新版本的不带时间锁定的退款协议,按照A已完成的工作量进行转账和退款。A可以随时在协议上签字然后公布,获得已完成部分工作的报酬。但A不会立即这么做,因为主链交易成本太高。
    • 重复上一步的过程,直到A完成一天的工作后,或是到第二份协议时间锁定到期前,A在退款协议的最后版本上签字并公布,从而获取自己的劳动报酬,并把剩余的部分退回到B的账户。

    从上面的流程看,在整个中间过程中,要准备很多份协议(交易),但并不公布出来,只在线下协商。最终被公布的是最开始的和最后的这两份协议,也就是实际上只有两个交易被广播到比特币网络中,这样就大幅降低了总的交易成本。

    上面这个流程也是RSMC(Revocable Sequence Maturity Contract - 序列到期可撤销合约)的一种形式。把RSMC通道联成网络,就有了HTLC(Hashed Timelock Contract - 哈希时间锁定合约)。这就是闪电网络(Lightning Network),比特币的一种“低手续费的极速转账”技术。

    总结

    从上面的场景来看,多重签名的应用一般是设立虚拟的联合或托管账户,先将交易款项或准备金转到这个账户里,后续再通过协商或仲裁达成一致,将虚拟账户的钱以一定的比例分别转给起初的交易各方。这其实就是基于脚本的合约,需要的时候还可以结合第三方的仲裁和担保,以满足复杂应用场景的需求。

    展开全文
  • 数字签名

    2017-03-30 10:28:53
    数字签名原理 客户端处理 要传输的二进制数据可使用对称加密算法AES加密(报文) 对报文进行HASH提取报文摘要(指纹) ...数字签名的应用场景 需要严格验证发送方身份信息情况 使用数字签名能够让接收

    数字签名原理

    • 客户端处理
      • 要传输的二进制数据可使用对称加密算法AES加密(报文)
      • 对报文进行HASH提取报文摘要(指纹)
      • 发送方使用RSA(私钥)对报文摘要进行加密(数字签名)
      • 把数字签名附着在报文的末尾一起发送给接收方
    • 服务端处理
      • 对报文HASH得到报文摘要
      • 使用RSA(公钥)对数字签名进行解密
      • 判断是否与报文摘要相同,如果一致说明数据有效

    数字签名的应用场景

    • 需要严格验证发送方身份信息情况
    • 使用数字签名能够让接收方确信对象是数字签名者本人

    数字签名的安全性

    • 能够有效的保证数据来源,数据完整性防止被人伪造
    • 前提条件–用于验证数字签名的公钥是正确的,如果公钥是伪造的则无法进行签名验证
    展开全文
  • 【密码学】基础知识-1-数字签名与数字证书在基于非对称密钥加密的通信过程的应用 非对称密钥加密:​​​ 又称公钥加密,公钥加密有一对密钥对,公钥和私钥,公钥即为公开(告诉别人)的密钥,私钥则不公开。(私钥...

    【密码学】基础知识-1-数字签名与数字证书在基于非对称密钥加密的通信过程的应用

    由于文章发布时,作者对文章做了调整导致csdn和公众号的信息不对称。更新后的文章在公众号配有图片并修正了纰漏,如果有兴趣的小伙伴可以在扫描文章末尾公众号前往公众号查看惹~

    非对称密钥加密:​​​
    又称公钥加密,公钥加密有一对密钥对,公钥和私钥,公钥即为公开(告诉别人)的密钥,私钥则不公开。(私钥一般是随机数生成器生成的,就像你注册一个账号时,密码是自己设置的)在密钥对中,一种密钥加密的数据必定能使用另一种密钥解密。其中,公钥用来给数据加密,私钥用来解密公钥加密的数据。
    场景1:
    现在假设你是吴彦祖分祖,有一对密钥对(公钥+私钥),你把你的公钥广播给你的朋友们和女朋友,私钥自己保留。

    摘要算法(哈希/散列算法):
    通过一个函数(哈希函数),把任意长度的数据转换为一个长度固定的数据串。就是说,无论你输入是任意类型 任意长度的明文,输出的密文的长度都是固定的。​数字签名:假如你想要传输一封信给你女朋友时,先将信的内容通过摘要算法生成信件内容的摘要​​,再用自己的私钥对摘要进行加密,加密所生成的内容就是数字签名,然后把数字签名附在信件上。​签名验证:你的女朋友收到了你的信件后,取下你的数字签名,然后用你广播出去的公钥解开数字签名,得到摘要(姑且称摘要1),证明了这封信是你发送的,然后你朋友再对信件内容使用哈希函数并得到一个摘要(姑且称摘要2),用摘要2与上面的摘要1对比。若两个摘要相同,则证明了信件内容没有被修改。

    场景2:
    由于你长得很帅,此时冒出一个绿茶🍵婊⌚,用尽“爱情三十六计”接近你女朋友并和你女朋友成为了好盆友,然后她偷偷用了你女朋友的电脑,用自己的公钥换走了你女朋友的公钥…… 此时你女朋友拥有的是绿茶的公钥,但是你女朋友浑然不知并且还认为这是你的公钥。因此,绿茶就可以用她的私钥做出“数字签名”写信给你女朋友,让你女朋友用假的公钥解密(绿茶的公钥并非是你的公钥)……
    摇摇欲坠的爱情~ (˘̩̩̩ε˘̩ƪ)
    后来你女朋友觉得不对劲,发现了这个bug—没办法确认她手中的公钥是否是你的。她就想出一个办法:,让你去找一个“证书中心”(结婚证❌)……

    数字证书:​
    可认为是一种身份证,用于标识你的身份。数字证书由权威机构(certificate authority,简称CA)颁发​并且用非对称加密算法加密。权威机构中的认证者拥有属于自己的密钥对(公钥和私钥)​。如果某个小可爱需要生成自己的数字证书,就将本人的公钥和一些个人信息提交给认证机构。(私钥自己保留,别傻傻的交出去)然后,认证者将你的公钥和个人信息用他的私钥加密,生成的就是数字证书。
    整个通信过程总结:
    你给你女朋友发信息:
    1.你先用自己的私钥对信息(一般是信息的摘要)进行签名
    2.你接着使用你女朋友的公钥对信息内容和签名信息进行加密。
    你女朋友收到你的信件:
    1.你女朋友用自己的私钥解密你用她的公钥加密的内容,得到信件内容和数字签名。
    2、你女朋友得到解密后的明文再用你的公钥解签你用自己的私钥加密的签名。(分界线)

    场景3:​你很赞成你女朋友的办法,就去找了相关的权威机构(CA),把自己的公钥和一些个人信息交给CA,CA用自己的私钥加密你的公钥和个人信息,生成数字证书。于是你写信的时候不仅在信件上附上了数字签名,还附上了数字证书。当你女朋友收到你“爱的信件”时,她用CA的公钥解开数字证书,把绿茶的公钥(此时你女朋友傻乎乎的认为这是你的公钥)和数字证书中你的公钥一对比,发现不匹配。于是,绿茶的阴谋不攻自破。然后,天雷继续勾地火,你们又继续幸福快乐的生活在一起……(u guys 最喜欢的happy ending~)┑( ̄_ ̄)┍

    如果大家觉得我写的还行,欢迎大家关注我的公众号,我会在上面不定期发布我的学习记录和心得ᕙ(`▿´)ᕗ,可以搜索zk_13556224805,或搜索下面二维码( ̄▽ ̄)~*
    在这里插入图片描述

    展开全文
  • 在这篇文章里将为大家介绍数字证书的生成...而数字签名的应用场景有点相反,数字签名是企业为客户端确认数据来源的准确性而提供的服务。一般应用于政府机关、行政部门、金融行业、资讯行业等企业的数据发布上。数据都是
  • 笔者在前面几篇文章中,一口气分别介绍了【对称加密算法、非对称加密算法、信息摘要算法】,从中读者能大致了解到各种算法的应用场景是怎么样的。这一次,我们将进一步介绍【非对称加密算法】和【消息摘要算法】的...
  • 文章标题数字签名数字证书数字证书的应用场景 数字签名 数字签名是拿来对数据做认证的,帮助接收者确认数据是否真实有效。 就像你在合同上签名,合同生效后,内容就不能再改动了。两者作用是一样的,区别在于认证的...
  • 接下来几期内容我们将围绕“数字签名”而展开,从法律条文、场景应用、解决方案、技术管理等方面进行详细剖析。数字签名与电子签名是紧密地联系在一起,2000年美国《全球和国家商业电子签名(ESIGN)法案》、...
  • 现在对这些加密、解密应用场景来进行剖析。 场景1: 对银行卡验证。通过翼支付快捷验证接口,商户可以验证用户银行卡、户名、身份证号、银行卡预留手机号这四要素信息。 前提条件: 我方知道翼支付端公钥,...
  • 对比APK的数字签名是否一致

    千次阅读 2014-02-19 18:44:42
    目前在做一个应用商店项目,有一个场景:比如手机上已经安装了一个被篡改过QQ应用,通过本应用商店下载了一个官方版QQ应用,在替换安装时提示签名不一致,安装失败,那么这时需要卸载掉已安装QQ,再安装官方...
  • 结果表明:基于辫群的签名方案的签名效率要远远高于基于RSA的方案,但是签名的验证过程较慢,因此适合于那些签名需要迅速完成而验证可以相对延迟的应用场景(如离线电子货币系统).此外,基于辫群的密码系统的密钥长度较大...
  • 2. 应用场景 校验用户身份(使用私钥签名,公钥校验,只要用公钥能校验通过,则该信息一定是私钥持有者发布) 校验数据完整性(用解密后消息摘要跟原文消息摘要进行对比) 3. 签名过程 ...
  • 1. JWT 介绍 JSON Web Token(JWT)是...这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA公钥/私钥对对JWT进行签名。 虽然JWT可以加密以提供各方之间保密性,但我们将重点...
  • 现代密码学:数字签名

    千次阅读 2020-02-05 12:01:22
    数字签名的安全模型、性质3.RSA签名算法以及存在的安全问题4.ElGamal签名算法以及主要的问题5.特殊的签名算法以及适应的应用场景 数字签名 1.数字签名要解决的问题 A发送消息给B:A(不可抵赖)——————>B...
  • Android安全加密专题文章索引 Android安全加密:对称加密 ... 概述数字签名是非对称加密与数字摘要组合应用2. 应用场景 校验用户身份(使用私钥签名,公钥校验,只要用公钥能校验通过,则该信息一定
  • 欢迎关注公众号摘要:本篇文章介绍Schnorr两大应用场景,即从交互式零知识身份证明到非交互零知识身份证明、数字签名实现基本原理、菲亚特-沙米尔(Fiat-Shamir)变换。1. Schnorr简介Schno...
  • 分析了移动签名技术的安全性,包括数据隔离的安全性、算法安全性、密钥安全性和数字签名的有效性。同时针对用户身份鉴别、客户端变更两个应用场景,提出了方案实施的改进建议。最后,以智能电池管理系统用户登录场景...
  • Go语言代码实现数字签名过程

    千次阅读 2018-11-23 18:12:02
    直接使用百度百科中关于数字签名的应用例子,如下: 假如现在 Alice 向 Bob 传送数字信息,为了保证信息传送的保密性、真实性、完整性和不可否认性,需要对传送的信息进行数字加密和签名,其传送过程为: 1.Alice ...
  • 数字签名除了应用在火热区块链技术中之外,HTTPS中也有使用,数字签名类似于纸质合同,合同上必须有签名才认为是一份有效合同,否则它就是没有法律效力,因为别人可以对内容进行篡改。数字签名用于证实数据...
  • 之前个人维护一个数字证书模块,与密码学相关知识也紧密相关,同时数字证书在我们业务场景中,是作为指纹支付基础 iOS的签名机制。常常跟着网上教程一顿操作,然而却不知道原理是什么。个人觉得,知道原理...
  • 在文章非对称加密和签名认证中,我们介绍了双钥系统两种应用场景: 加密解密时,公钥用于加密,私钥用于解密 身份认证时,私钥用于签名,公钥用于验证 椭圆曲线密码学(ECC,Elliptic Curve Cryptogphay)是一种...
  • 在开始了解公钥和私钥之前,我们先来了解一下它们的应用场景: 1、一个在网络上公开的服务器要对外提供服务,它需要一种安全通信手段; 2、这个服务器需要对公众证明它是一台合法的服务器,而不是什么钓鱼服务器...
  • token令牌认证与数字签名认证区别

    千次阅读 2019-10-29 10:45:47
    token令牌认证 解决问题:免密登录。 应用场景:前后台分离项目场景。 ...作用:服务器端会将生成token...数字签名 解决问题:防止数据被篡改。 应用场景:服务期间数据传输保障数据不被篡改。 内容:密钥加密串...
  • http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html 原文 http://www.youdzone.com/signature.html   非常详尽描述了公钥私钥和证书关系以及应用场景。 ...
  • 在一些比较重要的应用场景中,通过网络传递数据需要进行加密以保证安全。本文将简单地介绍了加密解密的一些概念,以及相关的数字签名、证书。 加密和解密 说到加密,可能大家最熟悉的就是MD5了。MD5实际上只是一种...
  • 文章目录区块链起源、技术与应用区块链发展历史区块链密码学基础加密货币公共密码学数字签名区块链与加密货币技术原理什么是区块链区块链技术原理区块链结构区块生成挖矿与工作量证明区块广播矿工激励...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 245
精华内容 98
关键字:

数字签名的应用场景