鴻蒙NEXT如何保證應(yīng)用安全:詳解鴻蒙NEXT數(shù)字簽名和證書(shū)機(jī)制

本文由美團(tuán)技術(shù)團(tuán)隊(duì)張晨分享,原題“鴻蒙應(yīng)用簽名實(shí)操及機(jī)制探究”,下文進(jìn)行了排版優(yōu)化和內(nèi)容修訂。

1、引言

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

本文對(duì)鴻蒙NEXT公開(kāi)資料進(jìn)行了深入分析和解讀,梳理了鴻蒙單框架應(yīng)用的簽名機(jī)制,拆解每一步的實(shí)操過(guò)程和背后的實(shí)現(xiàn)原理,并對(duì)源碼分析整理簽名的校驗(yàn)機(jī)制。從中管中窺豹,探究鴻蒙系統(tǒng)的安全設(shè)計(jì)思路,給從事鴻蒙研發(fā)的同學(xué)提供一些借鑒。

成文過(guò)程中特別參考了OpenHarmony 5.0.0-Release版的文檔和源碼,詳見(jiàn):OpenHarmony 5.0.0 Release。

2、簽名機(jī)制

簽名相關(guān)的代碼在developtools_hapsigner源碼倉(cāng)庫(kù)里,簽名流程梳理如下:

簽名步驟可按如下分組:

1)生成開(kāi)發(fā)者簽名證書(shū),包括①、② 、③;

2)生成Profile文件,包括④ 、⑤ ;

3)生成簽名的App,包括⑥ 、⑦。

3、生成開(kāi)發(fā)者簽名證書(shū)

3.1 生成開(kāi)發(fā)者公私鑰

通過(guò)華為的DevEco-Studio工具可以直接生成包含開(kāi)發(fā)者公私鑰的p12文件,操作步驟:鴻蒙NEXT官方指南-生成密鑰和證書(shū)請(qǐng)求文件。

筆者示例生成的p12文件(保存為my.p12)是標(biāo)準(zhǔn)的PKCS#12格式(定義在RFC 7292),用來(lái)存儲(chǔ)一組或多組公鑰證書(shū)(里面包含公鑰)和其對(duì)應(yīng)的私鑰(用localKeyID字段進(jìn)行匹配公私鑰的匹配),使用ASN.1來(lái)定義其數(shù)據(jù)結(jié)構(gòu),并采用DER編碼規(guī)則將這些結(jié)構(gòu)編碼為二進(jìn)制形式。

可以通過(guò)openssl命令解析其結(jié)構(gòu),或者直接查看公鑰證書(shū)和私鑰信息:

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

openssl pkcs12 -info -in?my.p12?//查看公鑰證書(shū)和私鑰信息

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

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

MIIBqTCCAU+gAwIBAgIIKG2ih6j2GSswCgYIKoZIzj0EAwIwSTEJMAcGA1UEBhMA

MQkwBwYDVQQIEwAxCTAHBgNVBAcTADEJMAcGA1UEChMAMQkwBwYDVQQLEwAxEDAO

BgNVBAMTB3Rlc3RzY3IwHhcNMjQwOTIzMTI1NjM3WhcNNDkwOTE3MTI1NjM3WjBJ

MQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkwBwYDVQQKEwAxCTAH

BgNVBAsTADEQMA4GA1UEAxMHdGVzdHNjcjBZMBMGByqGSM49AgEGCCqGSM49AwEH

A0IABD28s78rF8+X1JWgkQcfHB2Gy20MCT51Oue6eG5ZbPsUKlZrPx0aRX0einL2

E5WsE3st0zI4yvj0KzhdEwksCWCjITAfMB0GA1UdDgQWBBRtCEWMjEr+bnXoAqSC

fjmk1btJQDAKBggqhkjOPQQDAgNIADBFAiAAiMtQXgCMUxrKtaPKvGqllswi1FRU

h1brCAbJ1t81FgIhAMXbzmeJlA7/zxZDULLRW0rCY6CU3KMDHr8N38EmuDug

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

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

PEM 文件的label用于指示文件的內(nèi)容類型。

以下是一些常見(jiàn)的 PEM header和footer(后面會(huì)陸續(xù)見(jiàn)到):

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

openssl x509 -in?my.pem -text -noout

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

Certificate:

????Data:

????????Version: 3 (0x2)?//證書(shū)的版本號(hào)

????????Serial Number: 2913163237517564203 (0x286da287a8f6192b)?//證書(shū)的序列號(hào),用于唯一標(biāo)識(shí)證書(shū)

????????Signature Algorithm: ecdsa-with-SHA256

????????Issuer: C = , ST = , L = , O = , OU = , CN = testscr?//證書(shū)頒發(fā)者的信息

????????Validity

公鑰信息(包括公鑰算法、公鑰位數(shù)、公鑰值等)屬于結(jié)構(gòu)化數(shù)據(jù)并且較長(zhǎng),不利于識(shí)別和比較,所以需要用一個(gè)簡(jiǎn)短的字符串來(lái)標(biāo)識(shí)公鑰唯一性。常用做法是使用公鑰指紋(Public Key Pin,也叫公鑰Pin),計(jì)算方式是對(duì)DER編碼的公鑰進(jìn)行SHA-256計(jì)算并進(jìn)行Base64編碼。

這里需要注意的是,在X509擴(kuò)展字段里包括了Subject Key Identifier(SKID)字段,也是證書(shū)持有者的標(biāo)識(shí)。那標(biāo)識(shí)公鑰的唯一性為什么不直接使用證書(shū)里自帶的SKID,還要自己算一遍呢,根據(jù)RFC 3280-4.2.1.2章節(jié)中對(duì)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的計(jì)算可以通過(guò)公鑰得到,但計(jì)算方式并不唯一,也可以通過(guò)任意的算法得到,只要保證唯一性就可以了。定義里推薦了兩種基于SHA-1的算法,openssl采用的算法(詳見(jiàn)v3_skid.c的ossl_x509_pubkey_hash函數(shù),是對(duì)DER編碼的公鑰進(jìn)行SHA-1計(jì)算。

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

另外,還有Authority Key Identifier(AKID)字段用于標(biāo)識(shí)證書(shū)的頒發(fā)者。當(dāng)驗(yàn)證一個(gè)證書(shū)鏈時(shí),驗(yàn)證程序會(huì)檢查每個(gè)證書(shū)的AKID和上一個(gè)證書(shū)的SKID是否匹配,確保它們形成一個(gè)連續(xù)的信任鏈。

使用如下命令可以從PEM協(xié)議的公鑰證書(shū)中提取PEM協(xié)議的公鑰:

openssl x509 -in?my.pem -pubkey -noout

輸出如下:

-----BEGIN PUBLIC KEY-----?//公鑰標(biāo)頭

MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE95zFs5cFHauzIYEuuw3g2R75a1ir

qEW0JWP9qAKkyVCizN0nnzcn/Fo5oeSZR1iPUnJvjlnpNvZL9BcQbLqa7g==

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

使用如下命令可以繼續(xù)轉(zhuǎn)換成DER編碼并計(jì)算SHA-256和Base64編碼:

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

所以結(jié)合使用如下命令可以直接從符合PEM協(xié)議的公鑰證書(shū)文件中得到對(duì)應(yīng)的公鑰指紋:

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

最終筆者示例的公鑰證書(shū)計(jì)算得到的公鑰指紋為:

fzyRjPvTPElBAj0VlYlVA74M3RMtUh5ljKbOYf1NDA0=

3.2 生成證書(shū)簽名請(qǐng)求

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

得到的CSR內(nèi)容示例如下:

-----BEGIN NEW CERTIFICATE REQUEST-----?//CSR標(biāo)頭

MIIBMzCB2wIBADBJMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkw

BwYDVQQKEwAxCTAHBgNVBAsTADEQMA4GA1UEAxMHdGVzdHNjcjBZMBMGByqGSM49

AgEGCCqGSM49AwEHA0IABD28s78rF8+X1JWgkQcfHB2Gy20MCT51Oue6eG5ZbPsU

KlZrPx0aRX0einL2E5WsE3st0zI4yvj0KzhdEwksCWCgMDAuBgkqhkiG9w0BCQ4x

ITAfMB0GA1UdDgQWBBRtCEWMjEr+bnXoAqSCfjmk1btJQDAKBggqhkjOPQQDAgNH

ADBEAiAlzkRf0AHKh59/deFGo/4JHQRSbw6P+Q7qsiiMMWHT7wIgGugWrCm7tFLh

mRjEEyJNOpen9kfhyOanSRrwtBlEFc0=

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

生成的CSR文件是標(biāo)準(zhǔn)的PKCS#10格式(定義在RFC 2986),用于向證書(shū)頒發(fā)機(jī)構(gòu)(CA)請(qǐng)求簽發(fā)數(shù)字證書(shū)的文件,包含申請(qǐng)者的公鑰和一些身份信息,這些信息將包含在頒發(fā)的證書(shū)中。

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

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

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

Certificate request self-signature verify OK?//表明CSR的自簽名已成功驗(yàn)證

Certificate Request:

????Data:

????????Version: 1 (0x0)

????????Subject: C = , ST = , L = , O = , OU = , CN = testscr?//證書(shū)申請(qǐng)者的信息

????????Subject Public Key Info:

????????????Public Key Algorithm:?id-ecPublicKey

????????????????Public-Key: (256 bit)

????????????????pub:?//證書(shū)申請(qǐng)者的公鑰值,和上面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:?//證書(shū)申請(qǐng)者的標(biāo)識(shí)

????????????????????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

注意到其中證書(shū)申請(qǐng)者的公鑰值和上面p12文件中的公鑰值是一樣的,說(shuō)明CSR中包含了我們的公鑰信息。

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

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

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

fzyRjPvTPElBAj0VlYlVA74M3RMtUh5ljKbOYf1NDA0=

和通過(guò)公鑰證書(shū)計(jì)算得到的公鑰指紋相同。

3.3 生成開(kāi)發(fā)者簽名葉子證書(shū)

證書(shū)的作用可以抽象概括為:

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

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

分別是:

1)葉子證書(shū)由中間證書(shū)頒發(fā)(即葉子證書(shū)的Issuer+AKID和中間證書(shū)的Subject+SKID相同);

2)中間證書(shū)由根證書(shū)頒發(fā)(即中間證書(shū)的Issuer+AKID和根證書(shū)的Subject+SKID相同);

3)根證書(shū)由自己頒發(fā)(也就是自簽名,根證書(shū)的Issuer和Subject相同)。

我們需要的是用于給我們App簽名的開(kāi)發(fā)者簽名葉子證書(shū),這需要華為的開(kāi)發(fā)者簽名中間證書(shū)來(lái)幫我們頒發(fā)。

葉子證書(shū)分為調(diào)試證書(shū)和發(fā)布證書(shū),我們以發(fā)布證書(shū)為例操作步驟

需要上傳我們的CSR文件,得到的證書(shū)文件內(nèi)容示例如下:

-----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-----

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

根證書(shū):

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

中間證書(shū):

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

葉子證書(shū):

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

注意到:頒發(fā)下來(lái)的葉子證書(shū)里Subject和我們申請(qǐng)時(shí)所使用的CSR里的Subject不同,

葉子證書(shū)里是:

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

說(shuō)明華為在頒發(fā)葉子證書(shū)的時(shí)候,并沒(méi)有使用我們CSR里的Subject,而是根據(jù)我們?cè)陂_(kāi)發(fā)者平臺(tái)網(wǎng)站上登陸的賬號(hào)信息,對(duì)Subject進(jìn)行了填充。其中OU字段跟賬號(hào)信息有關(guān)(類似iOS的Team ID,但在華為開(kāi)發(fā)者網(wǎng)站上沒(méi)有找到直接查看的地方)。葉子證書(shū)里的公鑰信息還是和CSR保持一致,計(jì)算得到的公鑰指紋也一樣。

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

4、生成Profile文件

4.1 登記App信息

這里主要是在華為開(kāi)發(fā)者平臺(tái)上登記一下App的各項(xiàng)信息(操作步驟)。

需要注意的是:包名填寫(xiě)的時(shí)候,平臺(tái)會(huì)在線檢查一下是否和已經(jīng)存在的包名有重復(fù)(包括其他人申請(qǐng)的包名)。

申請(qǐng)成功以后,會(huì)分配一個(gè)唯一的APP ID:

這個(gè)APP ID用來(lái)在網(wǎng)站上標(biāo)識(shí)APP的唯一性。后面文章中會(huì)出現(xiàn)類似的名稱,為了消除歧義,相似的字段用括號(hào)內(nèi)容區(qū)分,這里稱為APP ID(網(wǎng)站)。

4.2 生成Profile文件

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

跟著操作步驟,選擇之前的APP ID(網(wǎng)站)和證書(shū),可以得到對(duì)應(yīng)的Profile文件:

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

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

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

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

openssl pkcs7 -in?my.p7b -print_certs? -inform DER?//查看證書(shū)信息

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

{

????"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"

}

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

官方文檔:app-provision-structure.md

源碼定義:provision_verify.cpp

其中重點(diǎn)字段解析如下:

得到的示例證書(shū)內(nèi)容如下:

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-----

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

5、生成簽名的APP

5.1 得到簽名的APP包

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

或者參考命令手動(dòng)給未簽名的App包進(jìn)行簽名。

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

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

那么對(duì)App包進(jìn)行簽名的內(nèi)容以及Profile文件在哪里呢?根據(jù)對(duì)源碼里VerifyHap.java類的verifyHap函數(shù)進(jìn)行分析,發(fā)現(xiàn)鴻蒙上的簽名機(jī)制類似Android V3,簽名信息和Profile文件存儲(chǔ)在自定義的HapSigningBlock區(qū),放到了ZIP格式Central Directory區(qū)的前面。

其結(jié)構(gòu)如下:

HapSigningBlock區(qū)的魔數(shù)(轉(zhuǎn)成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;

通過(guò)hex工具直接打開(kāi)App包也可以在Central Directory區(qū)前面找到:

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

/**

?* ID of profile block

?*/

public static final int HAP_PROFILE_BLOCK_ID = 0x20000002;

通過(guò)如下hap-sign-tool.jar的命令可以導(dǎo)出存儲(chǔ)在App包或Hap包里的簽名證書(shū)和Profile文件:

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

5.2 簽名校驗(yàn)、拆包、重簽名

提供給華為應(yīng)用市場(chǎng)審核的App包在經(jīng)過(guò)簽名校驗(yàn),確認(rèn)是開(kāi)發(fā)者的應(yīng)用以及應(yīng)用的完整性以后,華為會(huì)取出App包SigningBlock區(qū)的Profile文件,解壓出Hap包,把Profile文件或Profile文件內(nèi)的配置(下一章節(jié)展開(kāi)描述區(qū)別)重新放到Hap包的SigningBlock區(qū)里,并用Hap的簽名葉子證書(shū)對(duì)Hap包進(jìn)行重新簽名,簽名方式和給App包簽名一樣。最終真正通過(guò)應(yīng)用市場(chǎng)下發(fā)到手機(jī)上的是經(jīng)過(guò)重簽名的Hap包(類似iOS的雙層簽名機(jī)制)。

解析出簽名證書(shū)如下:

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的簽名證書(shū)和我們之前申請(qǐng)的開(kāi)發(fā)者簽名證書(shū)不一樣,Hap簽名證書(shū)和對(duì)應(yīng)的私鑰都是華為的,跟我們的應(yīng)用沒(méi)有關(guān)系,而且簽名證書(shū)鏈里不包含根證書(shū)的信息。

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

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

另外,如果在上架應(yīng)用市場(chǎng)的時(shí)候,勾選了加密:

根據(jù)《鴻蒙生態(tài)應(yīng)用安全技術(shù)白皮書(shū)》描述,只是對(duì)Hap包里的代碼做加密,然后重新簽名,所以證書(shū)和Profile文件的解析均不受影響。

6、校驗(yàn)機(jī)制

簽名相關(guān)的代碼在security_appverify源碼倉(cāng)庫(kù)里,簽名校驗(yàn)流程梳理如下(圖上所有判斷條件在失敗情況下均會(huì)導(dǎo)致簽名校驗(yàn)失敗,為了直觀不畫(huà)出此流程):

簽名校驗(yàn)步驟可以分成三組,分別是:

1)SignatureSchemeBlock區(qū)校驗(yàn);

2)Profile校驗(yàn)和解析;

3)Hap包完整性校驗(yàn)。

7、SignatureSchemeBlock區(qū)校驗(yàn)

校驗(yàn)Hap包時(shí)首先在ZIP的Central Directory區(qū)前32個(gè)字節(jié)尋找是否有HapSigningBlock區(qū)的Header,找到以后定位到SignatureSchemeBlock區(qū),解析其CMS格式,并校驗(yàn)SignatureSchemeBlock區(qū)證書(shū)鏈的完整性。

證書(shū)鏈完整性校驗(yàn)流程如下:

校驗(yàn)葉子證書(shū)時(shí),需要按證書(shū)指定算法重新計(jì)算證書(shū)的hash,并使用上一級(jí)證書(shū)(中間證書(shū))的公鑰對(duì)葉子證書(shū)里的證書(shū)簽名進(jìn)行解密,與重新計(jì)算的hash比對(duì)是否相同,相同則認(rèn)為證書(shū)可信。中間證書(shū)繼續(xù)通過(guò)根證書(shū)的公鑰校驗(yàn)自己的證書(shū)簽名。根證書(shū)用自己的公鑰校驗(yàn)自己。

上一章說(shuō)到,SignatureSchemeBlock區(qū)的證書(shū)鏈不包括根證書(shū),所以這一步需要使用到根證書(shū)其實(shí)是內(nèi)置在鴻蒙系統(tǒng)里的,存放地址是:

/system/etc/security/trusted_root_ca.json

具體內(nèi)容如下:

{

????"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"

}

可以看到這個(gè)根證書(shū)就是上一章解析出來(lái)的根證書(shū),所以這里可以校驗(yàn)通過(guò)。

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

內(nèi)置的Hap簽名證書(shū)列表存放地址是:

/system/etc/security/trusted_apps_sources.json

具體內(nèi)容如下:

{

????"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(應(yīng)用市場(chǎng))”、“huawei system apps(系統(tǒng)應(yīng)用)”、“third_party app preload(三方預(yù)裝)”三組。每一組包括對(duì)應(yīng)的Hap簽名證書(shū)Subject、Profile簽名證書(shū)Subject等信息。

我們走應(yīng)用市場(chǎng)分發(fā)的Hap包會(huì)匹配到“huawei app gallery”這個(gè)證書(shū)。

8、Profile解析和校驗(yàn)

接下來(lái)在SigningBlock區(qū)尋找Profile,這里注意到不同Hap包簽名方式會(huì)影響Profile的存儲(chǔ)格式。對(duì)于走應(yīng)用市場(chǎng)分發(fā)的Hap包,Profile是直接把其配置以字符串的格式保存,而對(duì)于其他情況,則是用CMS的格式保存。那么應(yīng)用市場(chǎng)分發(fā)的Hap包也就不需要Profile的文件簽名校驗(yàn)了。

對(duì)于其他情況,首先會(huì)使用Profile里保存的葉子證書(shū)公鑰校驗(yàn)Profile的文件簽名,然后會(huì)校驗(yàn)葉子證書(shū)Subject是否和匹配的同組內(nèi)Profile簽名證書(shū)Subject相同。

校驗(yàn)通過(guò)后解析Profile里的配置信息,根據(jù)type不同走不同的校驗(yàn)邏輯:

1)發(fā)布,會(huì)校驗(yàn)是否為允許的安裝來(lái)源,根據(jù)hap_verify_v2.cpp的IsAppDistributedTypeAllowInstall函數(shù),允許的來(lái)源包括企業(yè)簽名、MDM、眾包測(cè)試等分發(fā)場(chǎng)景;

2)調(diào)試,會(huì)校驗(yàn)待安裝的設(shè)備UDID是否在Profile的device-ids列表中。

都校驗(yàn)通過(guò)后,再繼續(xù)看Profile文件簽名證書(shū)和Hap的簽名正式是否相同,并繼續(xù)對(duì)Profile配置的字段規(guī)則合法性進(jìn)行檢測(cè)。走完這一步,就可以認(rèn)為Profile是可信的。

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

另外,在鴻蒙SignatureInfo API中,會(huì)返回三個(gè)參數(shù):

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

根據(jù)包管理子系統(tǒng)bundle_install_checker.cpp的ParseHapFiles函數(shù)、inner_bundle_info.h的SetProvisionId函數(shù)和這個(gè)PR來(lái)看:

//?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(接口)的值實(shí)際上是APP ID(公鑰)加上了{(lán)bundleName}_的前綴。

9、Hap包完整性校驗(yàn)

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

10、本文小結(jié)

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

感謝華為同學(xué)對(duì)本文的大力支持。

11、相關(guān)資料

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

[2]?即時(shí)通訊安全篇(六):非對(duì)稱加密技術(shù)的原理與應(yīng)用實(shí)踐

[3]?一篇讀懂HTTPS:加密原理、安全邏輯、數(shù)字證書(shū)等

[4]?即時(shí)通訊初學(xué)者必知必會(huì)的20個(gè)網(wǎng)絡(luò)編程和通信安全知識(shí)點(diǎn)

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

[6]?微信技術(shù)分享:揭秘微信后臺(tái)安全特征數(shù)據(jù)倉(cāng)庫(kù)的架構(gòu)設(shè)計(jì)

[7]?來(lái)自阿里OpenIM:打造安全可靠即時(shí)通訊服務(wù)的技術(shù)實(shí)踐分享

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容