Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 494, comments - 13, trackbacks - 0, articles - 1

          本文由美團技術團隊張晨分享,原題“鴻蒙應用簽名實操及機制探究”,下文進行了排版優化和內容修訂。

          1、引言

          華為鴻蒙單框架操作系統HarmonyOS NEXT已于2024年10月23日正式發布Release版。HarmonyOS NEXT僅支持鴻蒙原生應用,不再兼容安卓。

          本文對鴻蒙NEXT公開資料進行了深入分析和解讀,梳理了鴻蒙單框架應用的簽名機制,拆解每一步的實操過程和背后的實現原理,并對源碼分析整理簽名的校驗機制。從中管中窺豹,探究鴻蒙系統的安全設計思路,給從事鴻蒙研發的同學提供一些借鑒。

          成文過程中特別參考了OpenHarmony 5.0.0-Release版的文檔和源碼,詳見:OpenHarmony 5.0.0 Release

           
           

          2、簽名機制

          簽名相關的代碼在developtools_hapsigner源碼倉庫里,簽名流程梳理如下:

          簽名步驟可按如下分組:

          • 1)生成開發者簽名證書,包括①、② 、③;
          • 2)生成Profile文件,包括④ 、⑤ ;
          • 3)生成簽名的App,包括⑥ 、⑦。

          3、生成開發者簽名證書

          3.1 生成開發者公私鑰

          通過華為的DevEco-Studio工具可以直接生成包含開發者公私鑰的p12文件,操作步驟:鴻蒙NEXT官方指南-生成密鑰和證書請求文件

          筆者示例生成的p12文件(保存為my.p12)是標準的PKCS#12格式(定義在RFC 7292),用來存儲一組或多組公鑰證書(里面包含公鑰)和其對應的私鑰(用localKeyID字段進行匹配公私鑰的匹配),使用ASN.1來定義其數據結構,并采用DER編碼規則將這些結構編碼為二進制形式。

          可以通過openssl命令解析其結構,或者直接查看公鑰證書和私鑰信息:

          openssl asn1parse -in my.p12 -inform DER //解碼DER和解析ASN.1

          openssl pkcs12 -info -in my.p12 //查看公鑰證書和私鑰信息

          筆者用于示例生成的p12文件里包含的公鑰證書如下:

          -----BEGIN CERTIFICATE-----

          MIIBqTCCAU+gAwIBAgIIKG2ih6j2GSswCgYIKoZIzj0EAwIwSTEJMAcGA1UEBhMA

          MQkwBwYDVQQIEwAxCTAHBgNVBAcTADEJMAcGA1UEChMAMQkwBwYDVQQLEwAxEDAO

          BgNVBAMTB3Rlc3RzY3IwHhcNMjQwOTIzMTI1NjM3WhcNNDkwOTE3MTI1NjM3WjBJ

          MQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkwBwYDVQQKEwAxCTAH

          BgNVBAsTADEQMA4GA1UEAxMHdGVzdHNjcjBZMBMGByqGSM49AgEGCCqGSM49AwEH

          A0IABD28s78rF8+X1JWgkQcfHB2Gy20MCT51Oue6eG5ZbPsUKlZrPx0aRX0einL2

          E5WsE3st0zI4yvj0KzhdEwksCWCjITAfMB0GA1UdDgQWBBRtCEWMjEr+bnXoAqSC

          fjmk1btJQDAKBggqhkjOPQQDAgNIADBFAiAAiMtQXgCMUxrKtaPKvGqllswi1FRU

          h1brCAbJ1t81FgIhAMXbzmeJlA7/zxZDULLRW0rCY6CU3KMDHr8N38EmuDug

          -----END CERTIFICATE-----

          公鑰證書的表示是遵循Privacy Enhanced Mail(PEM)協議(定義在RFC 7468)的文本文件,其格式如下:

          PEM 文件的label用于指示文件的內容類型。

          以下是一些常見的 PEM header和footer(后面會陸續見到):

          解析具體公鑰證書信息可以采用如下命令(將公鑰證書以文本的形式保存為my.pem文件):

          openssl x509 -in my.pem -text -noout

          解析得到如下輸出(重要部分加了注釋):

          Certificate:

              Data:

                  Version: 3 (0x2) //證書的版本號

                  Serial Number: 2913163237517564203 (0x286da287a8f6192b) //證書的序列號,用于唯一標識證書

                  Signature Algorithm: ecdsa-with-SHA256

                  Issuer: C = , ST = , L = , O = , OU = , CN = testscr //證書頒發者的信息

                  Validity

          公鑰信息(包括公鑰算法、公鑰位數、公鑰值等)屬于結構化數據并且較長,不利于識別和比較,所以需要用一個簡短的字符串來標識公鑰唯一性。常用做法是使用公鑰指紋(Public Key Pin,也叫公鑰Pin),計算方式是對DER編碼的公鑰進行SHA-256計算并進行Base64編碼。

          這里需要注意的是,在X509擴展字段里包括了Subject Key Identifier(SKID)字段,也是證書持有者的標識。那標識公鑰的唯一性為什么不直接使用證書里自帶的SKID,還要自己算一遍呢,根據RFC 3280-4.2.1.2章節中對SKID的定義:

          For CA certificates, subject key identifiers SHOULD be derived from the public key or a method that generates unique values.

          Two common methods for generating key identifiers from the public key are:

          (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bits).

          (2) The keyIdentifier is composed of a four bit type field with the value 0100 followed by the least significant 60 bits of the SHA-1 hash of the value of the BIT STRING subjectPublicKey (excluding the tag, length, and number of unused bit string bits).

          SKID的計算可以通過公鑰得到,但計算方式并不唯一,也可以通過任意的算法得到,只要保證唯一性就可以了。定義里推薦了兩種基于SHA-1的算法,openssl采用的算法(詳見v3_skid.c的ossl_x509_pubkey_hash函數,是對DER編碼的公鑰進行SHA-1計算。

          如果采用SKID來進行公鑰的唯一性校驗,那么攻擊者可以偽造一個證書,里面的SKID和你的一樣(SHA-1碰撞,或者直接照抄一下也行),這樣的證書也是合法的,就可以輕易繞過對公鑰的校驗。所以SKID一般只用于在證書鏈中尋找父子關系,并不用于公鑰的唯一性標識。

          另外,還有Authority Key Identifier(AKID)字段用于標識證書的頒發者。當驗證一個證書鏈時,驗證程序會檢查每個證書的AKID和上一個證書的SKID是否匹配,確保它們形成一個連續的信任鏈。

          使用如下命令可以從PEM協議的公鑰證書中提取PEM協議的公鑰:

          openssl x509 -in my.pem -pubkey -noout

          輸出如下:

          -----BEGIN PUBLIC KEY----- //公鑰標頭

          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE95zFs5cFHauzIYEuuw3g2R75a1ir

          qEW0JWP9qAKkyVCizN0nnzcn/Fo5oeSZR1iPUnJvjlnpNvZL9BcQbLqa7g==

          -----END PUBLIC KEY-----

          使用如下命令可以繼續轉換成DER編碼并計算SHA-256和Base64編碼:

          openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

          所以結合使用如下命令可以直接從符合PEM協議的公鑰證書文件中得到對應的公鑰指紋:

          openssl x509 -in my.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

          最終筆者示例的公鑰證書計算得到的公鑰指紋為:

          fzyRjPvTPElBAj0VlYlVA74M3RMtUh5ljKbOYf1NDA0=

          3.2 生成證書簽名請求

          同樣通過DevEco-Studio可以直接生成證書簽名請求Certificate Signing Request(CSR)文件(操作步驟)。

          得到的CSR內容示例如下:

          -----BEGIN NEW CERTIFICATE REQUEST----- //CSR標頭

          MIIBMzCB2wIBADBJMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkw

          BwYDVQQKEwAxCTAHBgNVBAsTADEQMA4GA1UEAxMHdGVzdHNjcjBZMBMGByqGSM49

          AgEGCCqGSM49AwEHA0IABD28s78rF8+X1JWgkQcfHB2Gy20MCT51Oue6eG5ZbPsU

          KlZrPx0aRX0einL2E5WsE3st0zI4yvj0KzhdEwksCWCgMDAuBgkqhkiG9w0BCQ4x

          ITAfMB0GA1UdDgQWBBRtCEWMjEr+bnXoAqSCfjmk1btJQDAKBggqhkjOPQQDAgNH

          ADBEAiAlzkRf0AHKh59/deFGo/4JHQRSbw6P+Q7qsiiMMWHT7wIgGugWrCm7tFLh

          mRjEEyJNOpen9kfhyOanSRrwtBlEFc0=

          -----END NEW CERTIFICATE REQUEST-----

          生成的CSR文件是標準的PKCS#10格式(定義在RFC 2986),用于向證書頒發機構(CA)請求簽發數字證書的文件,包含申請者的公鑰和一些身份信息,這些信息將包含在頒發的證書中。

          可以看到CSR文件也是遵循PEM協議的,可以如下命令解析CSR文件的內容(保存為my.csr文件):

          openssl req -text -noout -verify -in my.csr

          輸出示例(重要部分加了注釋):

          Certificate request self-signature verify OK //表明CSR的自簽名已成功驗證

          Certificate Request:

              Data:

                  Version: 1 (0x0)

                  Subject: C = , ST = , L = , O = , OU = , CN = testscr //證書申請者的信息

                  Subject Public Key Info:

                      Public Key Algorithm: id-ecPublicKey

                          Public-Key: (256 bit)

                          pub: //證書申請者的公鑰值,和上面my.pem里的公鑰值相同

                              04:3d:bc:b3:bf:2b:17:cf:97:d4:95:a0:91:07:1f:

                              1c:1d:86:cb:6d:0c:09:3e:75:3a:e7:ba:78:6e:59:

                              6c:fb:14:2a:56:6b:3f:1d:1a:45:7d:1e:8a:72:f6:

                              13:95:ac:13:7b:2d:d3:32:38:ca:f8:f4:2b:38:5d:

                              13:09:2c:09:60

                          ASN1 OID: prime256v1

                          NIST CURVE: P-256

                  Attributes:

                      Requested Extensions:

                          X509v3 Subject Key Identifier: //證書申請者的標識

                              6D:08:45:8C:8C:4A:FE:6E:75:E8:02:A4:82:7E:39:A4:D5:BB:49:40

              Signature Algorithm: ecdsa-with-SHA256

              Signature Value:

                  30:44:02:20:25:ce:44:5f:d0:01:ca:87:9f:7f:75:e1:46:a3:

                  fe:09:1d:04:52:6f:0e:8f:f9:0e:ea:b2:28:8c:31:61:d3:ef:

                  02:20:1a:e8:16:ac:29:bb:b4:52:e1:99:18:c4:13:22:4d:3a:

                  97:a7:f6:47:e1:c8:e6:a7:49:1a:f0:b4:19:44:15:cd

          注意到其中證書申請者的公鑰值和上面p12文件中的公鑰值是一樣的,說明CSR中包含了我們的公鑰信息。

          使用如下命令也可以直接從CSR文件中得到公鑰指紋:

          openssl req -in my.csr -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

          示例生成的CSR計算得到的公鑰指紋為:

          fzyRjPvTPElBAj0VlYlVA74M3RMtUh5ljKbOYf1NDA0=

          和通過公鑰證書計算得到的公鑰指紋相同。

          3.3 生成開發者簽名葉子證書

          證書的作用可以抽象概括為:

          頒發者(Issuer)說:持有者(Subject)的公鑰是某某某。

          證書一般分為三級:根證書(Root Certificate)、中間證書(Intermediate Certificate)、葉子證書(Leaf Certificate)。

          分別是:

          • 1)葉子證書由中間證書頒發(即葉子證書的Issuer+AKID和中間證書的Subject+SKID相同);
          • 2)中間證書由根證書頒發(即中間證書的Issuer+AKID和根證書的Subject+SKID相同);
          • 3)根證書由自己頒發(也就是自簽名,根證書的Issuer和Subject相同)。

          我們需要的是用于給我們App簽名的開發者簽名葉子證書,這需要華為的開發者簽名中間證書來幫我們頒發。

          葉子證書分為調試證書和發布證書,我們以發布證書為例操作步驟):

          需要上傳我們的CSR文件,得到的證書文件內容示例如下:

          -----BEGIN CERTIFICATE-----

          MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE

          AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx

          NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE

          CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw

          EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs

          GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB

          wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T

          AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI

          zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn

          BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h

          FTjgDHctXJlC5L7+ZDY=

          -----END CERTIFICATE-----

          -----BEGIN CERTIFICATE-----

          MIIDATCCAoigAwIBAgIIXmuDXbWpOB8wCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE

          AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDcwOTAyMDQyNFoXDTMwMDcw

          NzAyMDQyNFowYjELMAkGA1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE

          CwwKSHVhd2VpIENCRzEtMCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVs

          YXRpb25zIENBIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE65LdoIZh1hlpZ2gP

          bJ6gPhHsvYSRe22KETgdqeVeYnrbRHI9wsPT6RGYS+pU4mPl6wxzgDMqN6SY/BoZ

          luhkE1PzaHoPoNIWIq0O33hpyKyyYwAacIUEjYurkw1E9r9no4IBGDCCARQwHwYD

          VR0jBBgwFoAUo45a9Vq8cYwqaiVyfkiS4pLcIAAwHQYDVR0OBBYEFNtek7Ij6NDk

          /nF6Zumkc0dbf/NeMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEGCCsGAQUFBwIBFiVo

          dHRwOi8vY3BraS1jYXdlYi5odWF3ZWkuY29tL2Nwa2kvY3BzMBIGA1UdEwEB/wQI

          MAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMGYGA1UdHwRfMF0wW6BZoFeGVWh0dHA6

          Ly9jcGtpLWNhd2ViLmh1YXdlaS5jb20vY3BraS9zZXJ2bGV0L2NybEZpbGVEb3du

          LmNybD9jZXJ0eXBlPTEwJi9yb290X2cyX2NybC5jcmwwCgYIKoZIzj0EAwMDZwAw

          ZAIwWO1X5q2MdfpR1Q237GpUHGbL1C13rGyFg2p3AYo44FpZ2/A9ss0wOHKM4KDl

          ZPqdAjBLkf8NPZy7KVog98+iCTLq35DJ2ZVxkCxknA9YhiHVyXf4HPm4JlT7rW7o

          Q+FzM3c=

          -----END CERTIFICATE-----

          -----BEGIN CERTIFICATE-----

          MIICujCCAkGgAwIBAgIOY8ui/vvwxqFf+kFokYUwCgYIKoZIzj0EAwMwYjELMAkG

          A1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEt

          MCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVsYXRpb25zIENBIEcyMB4X

          DTI0MDkyMzEyNTgwNFoXDTI3MDkyMzEyNTgwNFowazELMAkGA1UEBhMCQ04xDzAN

          BgNVBAoMBuW8oOaZqDEcMBoGA1UECwwTMTI4OTY3Njc4NjA2NTQ5NDk3NzEtMCsG

          A1UEAwwk5byg5pmoKDEyODk2NzY3ODYwNjU0OTQ5NzcpXCxSZWxlYXNlMFkwEwYH

          KoZIzj0CAQYIKoZIzj0DAQcDQgAEPbyzvysXz5fUlaCRBx8cHYbLbQwJPnU657p4

          blls+xQqVms/HRpFfR6KcvYTlawTey3TMjjK+PQrOF0TCSwJYKOB0TCBzjAMBgNV

          HRMBAf8EAjAAMFkGA1UdHwRSMFAwTqBMoEqGSGh0dHA6Ly9oNWhvc3RpbmctZHJj

          bi5kYmFua2Nkbi5jbi9jY2g1L2NybC9oZHJjYWcyL0h1YXdlaUNCR0hEUkcyY3Js

          LmNybDAfBgNVHSMEGDAWgBTbXpOyI+jQ5P5xembppHNHW3/zXjAdBgNVHQ4EFgQU

          bQhFjIxK/m516AKkgn45pNW7SUAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG

          CCsGAQUFBwMDMAoGCCqGSM49BAMDA2cAMGQCMFzNlsafNs7ad5xelZOzCebdRofE

          VaQZJW0o5QAdTX0t9Ij1o/zUm0bXIf8ZZTJLYgIwKuuZu+LeLCLZJFEM7tYKDhIK

          TegCiesP1THuMgiZhZYOYl1kIZBPVrEB8O1wtxEm

          -----END CERTIFICATE-----

          可以看到葉子證書文件里也包括了中間證書和根證書,分別解析證書信息如下。

          根證書:

          Certificate:

              Data:

                  Version: 3 (0x2)

                  Serial Number: 5339133492510690512 (0x4a18699f9d7d8cd0)

                  Signature Algorithm: ecdsa-with-SHA384

                  Issuer: C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Root CA G2

                  Validity

                      Not Before: Mar 16 03:04:39 2020 GMT

                      Not After : Mar 16 03:04:39 2049 GMT

                  Subject: C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Root CA G2

                  Subject Public Key Info:

                      Public Key Algorithm: id-ecPublicKey

                          Public-Key: (384 bit)

                          pub:

                              04:5a:27:64:1a:70:d2:3b:0d:ff:1c:4d:b2:d8:61:

                              e5:f9:fa:56:04:86:b9:4b:e2:25:9c:da:ec:19:4b:

                              f0:0b:52:36:41:6b:ed:a8:21:d6:9b:01:65:14:af:

                              79:cc:a5:e2:33:cb:3d:c9:5d:d5:55:78:7b:8a:f3:

                              7c:64:93:b7:48:2e:4d:d5:30:ab:bc:1d:a5:a4:73:

                              01:c1:cc:f8:0c:0d:24:80:70:8c:9b:fc:03:79:ce:

                              a4:38:7c:75:c6:f0:91

                          ASN1 OID: secp384r1

                          NIST CURVE: P-384

                  X509v3 extensions:

                      X509v3 Key Usage: critical

                          Certificate Sign, CRL Sign

                      X509v3 Basic Constraints: critical

                          CA:TRUE

                      X509v3 Subject Key Identifier:

                          A3:8E:5A:F5:5A:BC:71:8C:2A:6A:25:72:7E:48:92:E2:92:DC:20:00

              Signature Algorithm: ecdsa-with-SHA384

              Signature Value:

                  30:64:02:30:33:2a:5e:07:b3:f4:21:b6:3b:73:a8:29:59:c0:

                  a5:85:1c:e7:38:91:63:f2:e6:af:ac:db:b6:3c:8a:33:f4:a2:

                  2a:af:78:e7:06:50:47:26:cd:26:c8:8e:e7:b5:8a:44:02:30:

                  5b:9b:c7:83:31:96:39:ce:ae:62:31:95:02:e8:7e:d4:cd:84:

                  a2:c7:85:32:d5:89:6c:2d:55:7b:df:c3:ed:28:ff:61:15:38:

                  e0:0c:77:2d:5c:99:42:e4:be:fe:64:36

          中間證書:

          Certificate:

              Data:

                  Version: 3 (0x2)

                  Serial Number: 6803676100576229407 (0x5e6b835db5a9381f)

                  Signature Algorithm: ecdsa-with-SHA384

                  Issuer: C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Root CA G2

                  Validity

                      Not Before: Jul  9 02:04:24 2020 GMT

                      Not After : Jul  7 02:04:24 2030 GMT

                  Subject: C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Developer Relations CA G2

                  Subject Public Key Info:

                      Public Key Algorithm: id-ecPublicKey

                          Public-Key: (384 bit)

                          pub:

                              04:eb:92:dd:a0:86:61:d6:19:69:67:68:0f:6c:9e:

                              a0:3e:11:ec:bd:84:91:7b:6d:8a:11:38:1d:a9:e5:

                              5e:62:7a:db:44:72:3d:c2:c3:d3:e9:11:98:4b:ea:

                              54:e2:63:e5:eb:0c:73:80:33:2a:37:a4:98:fc:1a:

                              19:96:e8:64:13:53:f3:68:7a:0f:a0:d2:16:22:ad:

                              0e:df:78:69:c8:ac:b2:63:00:1a:70:85:04:8d:8b:

                              ab:93:0d:44:f6:bf:67

                          ASN1 OID: secp384r1

                          NIST CURVE: P-384

                  X509v3 extensions:

                      X509v3 Authority Key Identifier:

                          A3:8E:5A:F5:5A:BC:71:8C:2A:6A:25:72:7E:48:92:E2:92:DC:20:00

                      X509v3 Subject Key Identifier:

                          DB:5E:93:B2:23:E8:D0:E4:FE:71:7A:66:E9:A4:73:47:5B:7F:F3:5E

                      X509v3 Certificate Policies:

                          Policy: X509v3 Any Policy

                            CPS: [url=http://cpki-caweb.huawei.com/cpki/cps]http://cpki-caweb.huawei.com/cpki/cps[/url]

                      X509v3 Basic Constraints: critical

                          CA:TRUE, pathlen:0

                      X509v3 Key Usage: critical

                          Certificate Sign, CRL Sign

                      X509v3 CRL Distribution Points:

                          Full Name:

                            URI:[url=http://cpki-caweb.huawei.com/cpki/servlet/crlFileDown.crl?certype=10&/root_g2_crl.crl]http://cpki-caweb.huawei.com/cpk ... 10&/root_g2_crl.crl[/url]

              Signature Algorithm: ecdsa-with-SHA384

              Signature Value:

                  30:64:02:30:58:ed:57:e6:ad:8c:75:fa:51:d5:0d:b7:ec:6a:

                  54:1c:66:cb:d4:2d:77:ac:6c:85:83:6a:77:01:8a:38:e0:5a:

                  59:db:f0:3d:b2:cd:30:38:72:8c:e0:a0:e5:64:fa:9d:02:30:

                  4b:91:ff:0d:3d:9c:bb:29:5a:20:f7:cf:a2:09:32:ea:df:90:

                  c9:d9:95:71:90:2c:64:9c:0f:58:86:21:d5:c9:77:f8:1c:f9:

                  b8:26:54:fb:ad:6e:e8:43:e1:73:33:77

          葉子證書:

          Certificate:

              Data:

                  Version: 3 (0x2)

                  Serial Number:

                      63:cb:a2:fe:fb:f0:c6:a1:5f:fa:41:68:91:85

                  Signature Algorithm: ecdsa-with-SHA384

                  Issuer: C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Developer Relations CA G2

                  Validity

                      Not Before: Sep 23 12:58:04 2024 GMT

                      Not After : Sep 23 12:58:04 2027 GMT

                  Subject: C = CN, O = \E5\BC\A0\E6\99\A8, OU = 1289676786065494977, CN = "\E5\BC\A0\E6\99\A8(1289676786065494977)\\,Release"

                  Subject Public Key Info:

                      Public Key Algorithm: id-ecPublicKey

                          Public-Key: (256 bit)

                          pub:

                              04:3d:bc:b3:bf:2b:17:cf:97:d4:95:a0:91:07:1f:

                              1c:1d:86:cb:6d:0c:09:3e:75:3a:e7:ba:78:6e:59:

                              6c:fb:14:2a:56:6b:3f:1d:1a:45:7d:1e:8a:72:f6:

                              13:95:ac:13:7b:2d:d3:32:38:ca:f8:f4:2b:38:5d:

                              13:09:2c:09:60

                          ASN1 OID: prime256v1

                          NIST CURVE: P-256

                  X509v3 extensions:

                      X509v3 Basic Constraints: critical

                          CA:FALSE

                      X509v3 CRL Distribution Points:

                          Full Name:

                            URI:[url=http://h5hosting-drcn.dbankcdn.cn/cch5/crl/hdrcag2/HuaweiCBGHDRG2crl.crl]http://h5hosting-drcn.dbankcdn.c ... aweiCBGHDRG2crl.crl[/url]

                      X509v3 Authority Key Identifier:

                          DB:5E:93:B2:23:E8:D0:E4:FE:71:7A:66:E9:A4:73:47:5B:7F:F3:5E

                      X509v3 Subject Key Identifier:

                          6D:08:45:8C:8C:4A:FE:6E:75:E8:02:A4:82:7E:39:A4:D5:BB:49:40

                      X509v3 Key Usage: critical

                          Digital Signature

                      X509v3 Extended Key Usage:

                          Code Signing

              Signature Algorithm: ecdsa-with-SHA384

              Signature Value:

                  30:64:02:30:5c:cd:96:c6:9f:36:ce:da:77:9c:5e:95:93:b3:

                  09:e6:dd:46:87:c4:55:a4:19:25:6d:28:e5:00:1d:4d:7d:2d:

                  f4:88:f5:a3:fc:d4:9b:46:d7:21:ff:19:65:32:4b:62:02:30:

                  2a:eb:99:bb:e2:de:2c:22:d9:24:51:0c:ee:d6:0a:0e:12:0a:

                  4d:e8:02:89:eb:0f:d5:31:ee:32:08:99:85:96:0e:62:5d:64:

                  21:90:4f:56:b1:01:f0:ed:70:b7:11:26

          注意到:頒發下來的葉子證書里Subject和我們申請時所使用的CSR里的Subject不同,

          葉子證書里是:

          Subject: C = CN, O = \E5\BC\A0\E6\99\A8, OU = 1289676786065494977, CN = "\E5\BC\A0\E6\99\A8(1289676786065494977)\\,Release"

          CSR里是:

          Subject: C = , ST = , L = , O = , OU = , CN = testscr

          說明華為在頒發葉子證書的時候,并沒有使用我們CSR里的Subject,而是根據我們在開發者平臺網站上登陸的賬號信息,對Subject進行了填充。其中OU字段跟賬號信息有關(類似iOS的Team ID,但在華為開發者網站上沒有找到直接查看的地方)。葉子證書里的公鑰信息還是和CSR保持一致,計算得到的公鑰指紋也一樣。

          另外,華為目前給葉子證書的有效期是3年,3年以后需要續期成新證書。當然,如果續期新證書的時候使用的CSR不變,那么新證書的公鑰指紋也依然會保持不變。

          4、生成Profile文件

          4.1 登記App信息

          這里主要是在華為開發者平臺上登記一下App的各項信息(操作步驟)。

          需要注意的是:包名填寫的時候,平臺會在線檢查一下是否和已經存在的包名有重復(包括其他人申請的包名)。

          申請成功以后,會分配一個唯一的APP ID:

          這個APP ID用來在網站上標識APP的唯一性。后面文章中會出現類似的名稱,為了消除歧義,相似的字段用括號內容區分,這里稱為APP ID(網站)。

          4.2 生成Profile文件

          Profile文件是描述App的包名、簽名、申請的權限列表、安裝包類型、可安裝設備等信息的文件(類似iOS的Provisioning Profile),簽名后保存為Cryptographic Message Syntax格式(CMS,擴展的PKCS#7/格式,CMS定義在RFC 5652,PKCS#7定義在RFC 2315)。

          跟著操作步驟,選擇之前的APP ID(網站)和證書,可以得到對應的Profile文件:

          Profile也分為發布和調試兩種,發布只能選擇發布證書,調試只能選擇調試證書。這里繼續以發布類型為例,生成的Profile文件(保存為my.p7b)被華為簽名后, 通過如下命令可以查看里面的所有信息:

          openssl pkcs7 -in my.p7b -print -inform DER

          主要包括配置信息和簽名信息兩部分,也可以通過如下命令分別查看配置信息和簽名信息:

          openssl smime -verify -in my.p7b -inform DER -noverify //查看配置信息

          openssl pkcs7 -in my.p7b -print_certs  -inform DER //查看證書信息

          得到的示例配置信息如下(*為手動打碼):

          {

              "version-name": "2.0.0",

              "version-code": 2,

              "app-distribution-type": "app_gallery",

              "uuid": "234e1d73-****-****-****-f81e2598d0ff",

              "validity": {

                  "not-before": 1727096284,

                  "not-after": 1821704284

              },

              "type": "release",

              "bundle-info": {

                  "developer-id": "300**********7916",

                  "distribution-certificate": "-----BEGIN CERTIFICATE-----\nMIICujCCAkGgAwIBAgIOY8ui/vvwxqFf+kFokYUwCgYIKoZIzj0EAwMwYjELMAkG\nA1UEBgwCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEt\nMCsGA1UEAwwkSHVhd2VpIENCRyBEZXZlbG9wZXIgUmVsYXRpb25zIENBIEcyMB4X\nDTI0MDkyMzEyNTgwNFoXDTI3MDkyMzEyNTgwNFowazELMAkGA1UEBhMCQ04xDzAN\nBgNVBAoMBuW8oOaZqDEcMBoGA1UECwwTMTI4OTY3Njc4NjA2NTQ5NDk3NzEtMCsG\nA1UEAwwk5byg5pmoKDEyODk2NzY3ODYwNjU0OTQ5NzcpXCxSZWxlYXNlMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAEPbyzvysXz5fUlaCRBx8cHYbLbQwJPnU657p4\nblls+xQqVms/HRpFfR6KcvYTlawTey3TMjjK+PQrOF0TCSwJYKOB0TCBzjAMBgNV\nHRMBAf8EAjAAMFkGA1UdHwRSMFAwTqBMoEqGSGh0dHA6Ly9oNWhvc3RpbmctZHJj\nbi5kYmFua2Nkbi5jbi9jY2g1L2NybC9oZHJjYWcyL0h1YXdlaUNCR0hEUkcyY3Js\nLmNybDAfBgNVHSMEGDAWgBTbXpOyI+jQ5P5xembppHNHW3/zXjAdBgNVHQ4EFgQU\nbQhFjIxK/m516AKkgn45pNW7SUAwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG\nCCsGAQUFBwMDMAoGCCqGSM49BAMDA2cAMGQCMFzNlsafNs7ad5xelZOzCebdRofE\nVaQZJW0o5QAdTX0t9Ij1o/zUm0bXIf8ZZTJLYgIwKuuZu+LeLCLZJFEM7tYKDhIK\nTegCiesP1THuMgiZhZYOYl1kIZBPVrEB8O1wtxEm\n-----END CERTIFICATE-----\n",

                  "bundle-name": "com.***.test",

                  "apl": "normal",

                  "app-feature": "hos_normal_app",

                  "app-identifier": "576************2509"

              },

              "baseapp-info": {},

              "permissions": {},

              "acls": {},

              "issuer": "app_gallery"

          }

          具體每個字段的含義可以參考官方文檔和源碼中的定義:

          其中重點字段解析如下:

          得到的示例證書內容如下:

          subject=C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Root CA G2

          issuer=C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Root CA G2

          -----BEGIN CERTIFICATE-----

          MIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE

          AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx

          NjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE

          CwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw

          EAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs

          GUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB

          wcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T

          AQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI

          zj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn

          BlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h

          FTjgDHctXJlC5L7+ZDY=

          -----END CERTIFICATE-----

           

          subject=C = CN, O = Huawei, OU = HOS AppGallery, CN = HOS Profile Management

          issuer=C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Software Signing Service CA

          -----BEGIN CERTIFICATE-----

          MIIC7TCCAnOgAwIBAgIIV5nKqt2oGmwwCgYIKoZIzj0EAwMwZDELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEvMC0GA1UE

          AwwmSHVhd2VpIENCRyBTb2Z0d2FyZSBTaWduaW5nIFNlcnZpY2UgQ0EwHhcNMjMw

          NDI0MDYyNjMxWhcNMjgwNDI0MDYyNjMxWjBYMQswCQYDVQQGDAJDTjEPMA0GA1UE

          CgwGSHVhd2VpMRcwFQYDVQQLDA5IT1MgQXBwR2FsbGVyeTEfMB0GA1UEAwwWSE9T

          IFByb2ZpbGUgTWFuYWdlbWVudDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDdY

          3RoPqb6WD8UpXJiavZLN48iamektKUKZHFl9xwr1Siu77z3lI86cREa3Flw50uKc

          xkMNKM4FWBRMd3CDhI+jggEZMIIBFTAfBgNVHSMEGDAWgBT69fe+IFZdXdTabfEU

          FTwdCduyNDAdBgNVHQ4EFgQU0a99kztpYeCetotz0YIduJ2I2VcwRgYDVR0gBD8w

          PTA7BgRVHSAAMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly9wa2kuY29uc3VtZXIuaHVh

          d2VpLmNvbS9jYS9jcHMwDgYDVR0PAQH/BAQDAgeAMEwGA1UdHwRFMEMwQaA/oD2G

          O2h0dHA6Ly9wa2kuY29uc3VtZXIuaHVhd2VpLmNvbS9jYS9jcmwvc29mdF9zaWdu

          X3Nydl9jcmwuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBgGDCsGAQQBj1sCgngB

          AwQIMAYCAQEKAQEwCgYIKoZIzj0EAwMDaAAwZQIwRYOlQ6Qq2SF8LHQ78xpNYh47

          zMemerx5oG4F6Uq/3ARPfowvdrEu5Ss+njPMG0FFAjEA0s7YhO7Ktm60mkuHuxQS

          46fqIHh/PAPJ2ozg1yDSD771bAGn7mDeGjaAFXEtKzU5

          -----END CERTIFICATE-----

           

          subject=C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Software Signing Service CA

          issuer=C = CN, O = Huawei, OU = Huawei CBG, CN = Huawei CBG Root CA G2

          -----BEGIN CERTIFICATE-----

          MIIDADCCAoegAwIBAgIIJGDixWQS3MkwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE

          AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjEyMzIzOVoXDTQwMDMx

          NjEyMzIzOVowZDELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE

          CwwKSHVhd2VpIENCRzEvMC0GA1UEAwwmSHVhd2VpIENCRyBTb2Z0d2FyZSBTaWdu

          aW5nIFNlcnZpY2UgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASsEz7cwYkzFh9b

          xIwKfXx5qHGjl5WITy0teGnNWqv+jYCceeixHqErvK7YRn2hVPIqhRqKWeANHZUK

          G0qxi+NIpmSmQS8/63CLz1QAcxfv2Xl3/V82dF0v9lm16ehMsN+jggEVMIIBETAf

          BgNVHSMEGDAWgBSjjlr1WrxxjCpqJXJ+SJLiktwgADAdBgNVHQ4EFgQU+vX3viBW

          XV3U2m3xFBU8HQnbsjQwDwYDVR0TAQH/BAUwAwEB/zBGBgNVHSAEPzA9MDsGBFUd

          IAAwMzAxBggrBgEFBQcCARYlaHR0cDovL2Nwa2ktY2F3ZWIuaHVhd2VpLmNvbS9j

          cGtpL2NwczAOBgNVHQ8BAf8EBAMCAQYwZgYDVR0fBF8wXTBboFmgV4ZVaHR0cDov

          L2Nwa2ktY2F3ZWIuaHVhd2VpLmNvbS9jcGtpL3NlcnZsZXQvY3JsRmlsZURvd24u

          Y3JsP2NlcnR5cGU9MTAmL3Jvb3RfZzJfY3JsLmNybDAKBggqhkjOPQQDAwNnADBk

          AjBrAQQxUlNgqhYkcEm5eksnPxDkPJSY/qNd2BDgbvEydiLwPSvB7Z9lipxz8ikZ

          EeUCMGppWcaV//SIG1y5tEwthLwWeEaF613vUILWQLir8+CA3RZGsRBqtE8xSqfz

          yafLYQ==

          -----END CERTIFICATE-----

          這里依然是完整的三級證書鏈,注意,根證書和之前申請到的開發者簽名證書的根證書一樣,但中間證書和葉子證書均不一樣,比較如下(紅色底色表示內容相同):

          5、生成簽名的APP

          5.1 得到簽名的APP包

          將生成的Profile文件、葉子證書文件等配置到項目的signingConfigs里,使用華為的IDE可以直接得到簽名后的App包。如下圖所示。

          或者參考命令手動給未簽名的App包進行簽名。

          得到的簽名的App包只是用于提供給華為商店進行審核和后續的拆包,并不能直接安裝到手機上運行。App包實際上就是標準的ZIP格式,可以修改后綴為.zip進行解壓(如下圖所示)。

          可以看到里面包括了.hap包和描述App一些信息的pack.info文件。

          那么對App包進行簽名的內容以及Profile文件在哪里呢?根據對源碼里VerifyHap.java類的verifyHap函數進行分析,發現鴻蒙上的簽名機制類似Android V3,簽名信息和Profile文件存儲在自定義的HapSigningBlock區,放到了ZIP格式Central Directory區的前面。

          其結構如下:

          HapSigningBlock區的魔數(轉成string也就是<hap sign block>):

          /**

           * The value of lower 8 bytes of magic word

           */

          public static final long HAP_SIG_BLOCK_MAGIC_LO_V3 = 0x676973207061683cL;

           

          /**

           * The value of higher 8 bytes of magic word

           */

          public static final long HAP_SIG_BLOCK_MAGIC_HI_V3 = 0x3e6b636f6c62206eL;

           

          /**

           * Size of hap signature block header

           */

          public static final int HAP_SIG_BLOCK_HEADER_SIZE = 32;

          通過hex工具直接打開App包也可以在Central Directory區前面找到:

          其中SignatureSchemeBlock區存放了CMS格式的Hap包簽名信息,而Profile文件就存儲在SigningBlock區,Type是0x20000002:

          /**

           * ID of profile block

           */

          public static final int HAP_PROFILE_BLOCK_ID = 0x20000002;

          通過如下hap-sign-tool.jar的命令可以導出存儲在App包或Hap包里的簽名證書和Profile文件:

          1java -jar hap-sign-tool.jar verify-app -inFile my-signed.app -outCertChain

          5.2 簽名校驗、拆包、重簽名

          提供給華為應用市場審核的App包在經過簽名校驗,確認是開發者的應用以及應用的完整性以后,華為會取出App包SigningBlock區的Profile文件,解壓出Hap包,把Profile文件或Profile文件內的配置(下一章節展開描述區別)重新放到Hap包的SigningBlock區里,并用Hap的簽名葉子證書對Hap包進行重新簽名,簽名方式和給App包簽名一樣。最終真正通過應用市場下發到手機上的是經過重簽名的Hap包(類似iOS的雙層簽名機制)。

          解析出簽名證書如下:

          CN=HOS AppGallery Application Release, OU=HOS AppGallery, O=Huawei, C=CN

          -----BEGIN CERTIFICATE-----

          MIIC+TCCAn+gAwIBAgIIWXsBFAJOQzIwCgYIKoZIzj0EAwMwZDELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEvMC0GA1UE

          AwwmSHVhd2VpIENCRyBTb2Z0d2FyZSBTaWduaW5nIFNlcnZpY2UgQ0EwHhcNMjMw

          NDI0MDYyMjA1WhcNMjgwNDI0MDYyMjA1WjBkMQswCQYDVQQGDAJDTjEPMA0GA1UE

          CgwGSHVhd2VpMRcwFQYDVQQLDA5IT1MgQXBwR2FsbGVyeTErMCkGA1UEAwwiSE9T

          IEFwcEdhbGxlcnkgQXBwbGljYXRpb24gUmVsZWFzZTBZMBMGByqGSM49AgEGCCqG

          SM49AwEHA0IABIokjn9tVRpgEC6b1AR9chiiejUGBiF83Lzm1giyZX9XKVzTPkHq

          RRuML+zhRtT1JESEMOUggPyJbe9+rt3k9CijggEZMIIBFTAfBgNVHSMEGDAWgBT6

          9fe+IFZdXdTabfEUFTwdCduyNDAdBgNVHQ4EFgQUFzRtDLYZ7zX/idRsHYmJZ734

          vwgwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly9wa2ku

          Y29uc3VtZXIuaHVhd2VpLmNvbS9jYS9jcHMwDgYDVR0PAQH/BAQDAgeAMEwGA1Ud

          HwRFMEMwQaA/oD2GO2h0dHA6Ly9wa2kuY29uc3VtZXIuaHVhd2VpLmNvbS9jYS9j

          cmwvc29mdF9zaWduX3Nydl9jcmwuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBgG

          DCsGAQQBj1sCgngBAwQIMAYCAQEKAQAwCgYIKoZIzj0EAwMDaAAwZQIxAJofyGQW

          4ZVDW64qTeiVQVn5w7iRhejP6YFqYX9h/5mNXKMQ8ZuQCFT7EaqhVblWlQIwWIPB

          xC+YhPz6JmDMSZDynZINnXi0T3k9UvbcCybbd2k2PWHYvYqQdKAuYGcNc2Ho

          -----END CERTIFICATE-----

          CN=Huawei CBG Software Signing Service CA, OU=Huawei CBG, O=Huawei, C=CN

          -----BEGIN CERTIFICATE-----

          MIIDADCCAoegAwIBAgIIJGDixWQS3MkwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC

          Q04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE

          AwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjEyMzIzOVoXDTQwMDMx

          NjEyMzIzOVowZDELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE

          CwwKSHVhd2VpIENCRzEvMC0GA1UEAwwmSHVhd2VpIENCRyBTb2Z0d2FyZSBTaWdu

          aW5nIFNlcnZpY2UgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASsEz7cwYkzFh9b

          xIwKfXx5qHGjl5WITy0teGnNWqv+jYCceeixHqErvK7YRn2hVPIqhRqKWeANHZUK

          G0qxi+NIpmSmQS8/63CLz1QAcxfv2Xl3/V82dF0v9lm16ehMsN+jggEVMIIBETAf

          BgNVHSMEGDAWgBSjjlr1WrxxjCpqJXJ+SJLiktwgADAdBgNVHQ4EFgQU+vX3viBW

          XV3U2m3xFBU8HQnbsjQwDwYDVR0TAQH/BAUwAwEB/zBGBgNVHSAEPzA9MDsGBFUd

          IAAwMzAxBggrBgEFBQcCARYlaHR0cDovL2Nwa2ktY2F3ZWIuaHVhd2VpLmNvbS9j

          cGtpL2NwczAOBgNVHQ8BAf8EBAMCAQYwZgYDVR0fBF8wXTBboFmgV4ZVaHR0cDov

          L2Nwa2ktY2F3ZWIuaHVhd2VpLmNvbS9jcGtpL3NlcnZsZXQvY3JsRmlsZURvd24u

          Y3JsP2NlcnR5cGU9MTAmL3Jvb3RfZzJfY3JsLmNybDAKBggqhkjOPQQDAwNnADBk

          AjBrAQQxUlNgqhYkcEm5eksnPxDkPJSY/qNd2BDgbvEydiLwPSvB7Z9lipxz8ikZ

          EeUCMGppWcaV//SIG1y5tEwthLwWeEaF613vUILWQLir8+CA3RZGsRBqtE8xSqfz

          yafLYQ==

          -----END CERTIFICATE-----

          注意這里給Hap的簽名證書和我們之前申請的開發者簽名證書不一樣,Hap簽名證書和對應的私鑰都是華為的,跟我們的應用沒有關系,而且簽名證書鏈里不包含根證書的信息。

          這里再和之前的證書對比一下(紅色和黃色底色表示內容分別相同):

          三者的根證書都一樣,Profile簽名證書和Hap簽名證書的中間證書一樣,三者的葉子證書均不一樣。

          另外,如果在上架應用市場的時候,勾選了加密:

          根據《鴻蒙生態應用安全技術白皮書》描述,只是對Hap包里的代碼做加密,然后重新簽名,所以證書和Profile文件的解析均不受影響。

          6、校驗機制

          簽名相關的代碼在security_appverify源碼倉庫里,簽名校驗流程梳理如下(圖上所有判斷條件在失敗情況下均會導致簽名校驗失敗,為了直觀不畫出此流程):

          簽名校驗步驟可以分成三組,分別是:

          • 1)SignatureSchemeBlock區校驗;
          • 2)Profile校驗和解析;
          • 3)Hap包完整性校驗。

          7、SignatureSchemeBlock區校驗

          校驗Hap包時首先在ZIP的Central Directory區前32個字節尋找是否有HapSigningBlock區的Header,找到以后定位到SignatureSchemeBlock區,解析其CMS格式,并校驗SignatureSchemeBlock區證書鏈的完整性。

          證書鏈完整性校驗流程如下:

          校驗葉子證書時,需要按證書指定算法重新計算證書的hash,并使用上一級證書(中間證書)的公鑰對葉子證書里的證書簽名進行解密,與重新計算的hash比對是否相同,相同則認為證書可信。中間證書繼續通過根證書的公鑰校驗自己的證書簽名。根證書用自己的公鑰校驗自己。

          上一章說到,SignatureSchemeBlock區的證書鏈不包括根證書,所以這一步需要使用到根證書其實是內置在鴻蒙系統里的,存放地址是:

          /system/etc/security/trusted_root_ca.json

          具體內容如下:

          {

              "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Root CA G2":"-----BEGIN CERTIFICATE-----\nMIICGjCCAaGgAwIBAgIIShhpn519jNAwCgYIKoZIzj0EAwMwUzELMAkGA1UEBhMC\nQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEeMBwGA1UE\nAwwVSHVhd2VpIENCRyBSb290IENBIEcyMB4XDTIwMDMxNjAzMDQzOVoXDTQ5MDMx\nNjAzMDQzOVowUzELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UE\nCwwKSHVhd2VpIENCRzEeMBwGA1UEAwwVSHVhd2VpIENCRyBSb290IENBIEcyMHYw\nEAYHKoZIzj0CAQYFK4EEACIDYgAEWidkGnDSOw3/HE2y2GHl+fpWBIa5S+IlnNrs\nGUvwC1I2QWvtqCHWmwFlFK95zKXiM8s9yV3VVXh7ivN8ZJO3SC5N1TCrvB2lpHMB\nwcz4DA0kgHCMm/wDec6kOHx1xvCRo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T\nAQH/BAUwAwEB/zAdBgNVHQ4EFgQUo45a9Vq8cYwqaiVyfkiS4pLcIAAwCgYIKoZI\nzj0EAwMDZwAwZAIwMypeB7P0IbY7c6gpWcClhRznOJFj8uavrNu2PIoz9KIqr3jn\nBlBHJs0myI7ntYpEAjBbm8eDMZY5zq5iMZUC6H7UzYSix4Uy1YlsLVV738PtKP9h\nFTjgDHctXJlC5L7+ZDY=\n-----END CERTIFICATE-----\n"

          }

          可以看到這個根證書就是上一章解析出來的根證書,所以這里可以校驗通過。

          在確認證書鏈可信以后,根據葉子證書的Subject判斷Hap包的安裝來源,具體代碼在trusted_source_manager.cpp的MatchTrustedSource函數里,也就是和內置的Hap簽名證書列表進行比較,看匹配到哪一個。

          內置的Hap簽名證書列表存放地址是:

          /system/etc/security/trusted_apps_sources.json

          具體內容如下:

          {

              "version": "1.0.1",

              "release-time":"2021-06-03 10:06:00",

              "trust-app-source":[

                  {

                      "name":"huawei app gallery",

                      "app-signing-cert":"C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS AppGallery Application Release",

                      "profile-signing-certificate":"C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS Profile Management",

                      "profile-debug-signing-certificate":"C=CN, O=Huawei, OU=HOS AppGallery, CN=HOS Profile Management Debug",

                      "issuer-ca":"C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA",

                      "root-ca": "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Root CA G2",

                      "max-certs-path":3,

                      "critialcal-cert-extension":["keyusage","huawei-signing-capability"]

                  },

                  {

                      "name":"huawei system apps",

                      "app-signing-cert":"C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Release",

                      "profile-signing-certificate":"C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Profile Release",

                      "profile-debug-signing-certificate":"C=CN, O=Huawei CBG, OU=HOS Development Team, CN=HOS Application Provision Profile Release_Debug",

                      "issuer-ca":"C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA",

                      "root-ca": "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Root CA G2",

                      "max-certs-path":3,

                      "critialcal-cert-extension":["keyusage","huawei-signing-capability"]

                  },

                  {

                      "name":"third_party app preload",

                      "app-signing-cert":"C=CN, O=Huawei, OU=HOS Open Platform, CN=HOS Preload Service",

                      "profile-signing-certificate":"",

                      "profile-debug-signing-certificate":"",

                      "issuer-ca":"C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Software Signing Service CA",

                      "root-ca": "C=CN, O=Huawei, OU=Huawei CBG, CN=Huawei CBG Root CA G2",

                      "max-certs-path":3,

                      "critialcal-cert-extension":["keyusage","huawei-signing-capability"]

                  }

             ]

          }

          這里有“huawei app gallery(應用市場)”、“huawei system apps(系統應用)”、“third_party app preload(三方預裝)”三組。每一組包括對應的Hap簽名證書Subject、Profile簽名證書Subject等信息。

          我們走應用市場分發的Hap包會匹配到“huawei app gallery”這個證書。

          8、Profile解析和校驗

          接下來在SigningBlock區尋找Profile,這里注意到不同Hap包簽名方式會影響Profile的存儲格式。對于走應用市場分發的Hap包,Profile是直接把其配置以字符串的格式保存,而對于其他情況,則是用CMS的格式保存。那么應用市場分發的Hap包也就不需要Profile的文件簽名校驗了。

          對于其他情況,首先會使用Profile里保存的葉子證書公鑰校驗Profile的文件簽名,然后會校驗葉子證書Subject是否和匹配的同組內Profile簽名證書Subject相同。

          校驗通過后解析Profile里的配置信息,根據type不同走不同的校驗邏輯:

          • 1)發布,會校驗是否為允許的安裝來源,根據hap_verify_v2.cpp的IsAppDistributedTypeAllowInstall函數,允許的來源包括企業簽名、MDM、眾包測試等分發場景;
          • 2)調試,會校驗待安裝的設備UDID是否在Profile的device-ids列表中。

          都校驗通過后,再繼續看Profile文件簽名證書和Hap的簽名正式是否相同,并繼續對Profile配置的字段規則合法性進行檢測。走完這一步,就可以認為Profile是可信的。

          隨后會生成App ID(公鑰)和Fingerprint兩個新的字段和驗證結果一并返回。其中APP ID(公鑰)是根據Profile配置里開發者簽名證書公鑰生成的(詳見GenerateAppId函數),fingerprint是根據Profile配置里開發者簽名證書直接計算整個證書的指紋(注意不是上一章的公鑰指紋,詳見GenerateFingerprint函數)。至此完成Profile的解析和校驗。

          另外,在鴻蒙SignatureInfo API中,會返回三個參數:

          其中API返回的appId為了消除歧義,這里稱為APP ID(接口)。

          根據包管理子系統bundle_install_checker.cpp的ParseHapFiles函數、inner_bundle_info.h的SetProvisionId函數和這個PR來看:

          // bundle_install_checker.cpp

              newInfo.SetProvisionId(provisionInfo.appId);

           

          // inner_bundle_info.h

              void SetProvisionId(const std::string &provisionId)

          {

                  baseBundleInfo_->appId = baseBundleInfo_->name + Constants::FILE_UNDERLINE + provisionId;

              }

          APP ID(接口)的值實際上是APP ID(公鑰)加上了{bundleName}_的前綴。

          9、Hap包完整性校驗

          這一步的過程和Hap包簽名類似,將ZIP包中數據和HapSigningBlock區里非SignatureSchemeBlock的部分拼接,重新計算hash,與使用Hap簽名葉子證書公鑰解密SignatureSchemeBlock區簽名后的hash比較,相同則認為Hap包未被篡改。具體可以參考hap_signing_block_utils.cpp的VerifyHapIntegrity函數,這里就不展開了。

          10、本文小結

          從鴻蒙單框架應用的簽名和校驗機制的種種細節中可以看出,HarmonyOS NEXT的安全設計非常務實,融合了Anroid和iOS雙端的特性,有借鑒Android成熟的部分(簽名格式),但更多的是參考了iOS的設計思路(雙層簽名機制),甚至更加嚴格。期待HarmonyOS NEXT給我們帶來一個新的未來。

          感謝華為同學對本文的大力支持。

          11、相關資料

          [1] 即時通訊安全篇(三):常用加解密算法與通訊安全講解

          [2] 即時通訊安全篇(六):非對稱加密技術的原理與應用實踐

          [3] 一篇讀懂HTTPS:加密原理、安全邏輯、數字證書等

          [4] 即時通訊初學者必知必會的20個網絡編程和通信安全知識點

          [5] 微信新一代通信安全解決方案:基于TLS1.3的MMTLS詳解

          [6] 微信技術分享:揭秘微信后臺安全特征數據倉庫的架構設計

          [7] 來自阿里OpenIM:打造安全可靠即時通訊服務的技術實踐分享


          (本文已同步發布于:http://www.52im.net/thread-4801-1-1.html)



          作者:Jack Jiang (點擊作者姓名進入Github)
          出處:http://www.52im.net/space-uid-1.html
          交流:歡迎加入即時通訊開發交流群 215891622
          討論:http://www.52im.net/
          Jack Jiang同時是【原創Java Swing外觀工程BeautyEye】【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
          本博文 歡迎轉載,轉載請注明出處(也可前往 我的52im.net 找到我)。


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 尼勒克县| 建瓯市| 沙洋县| 木里| 石台县| 开原市| 巩义市| 乌恰县| 乐平市| 浏阳市| 连平县| 宕昌县| 平遥县| 北京市| 大宁县| 木里| 西乡县| 黔西县| 梅州市| 信宜市| 周口市| 苍梧县| 南昌县| 鸡泽县| 凌云县| 南丰县| 定兴县| 永胜县| 青冈县| 汉阴县| 新沂市| 万山特区| 大丰市| 宽城| 汾西县| 晋江市| 汝南县| 永德县| 平利县| 焉耆| 盱眙县|