首页 » 智能 » 关于SSL PINNING的一切_证书_摘要

关于SSL PINNING的一切_证书_摘要

雨夜梧桐 2024-11-13 08:38:53 0

扫一扫用手机浏览

文章目录 [+]

-----BEGIN CERTIFICATE-----MIIFQDCCBCigAwIBAgIGAXSrxEHXMA0GCSqGSIb3DQEBCwUAMIGkMTUwMwYDVQQDDCxDaGFybGVzIFByb3h5IENBICgyMCBTZXAgMjAyMCwgQzAyRDM3RUhNRDZSKTElMCMGA1UECwwcaHR0cHM6Ly9jaGFybGVzcHJveHkuY29tL3NzbDERMA8GA1UECgwIWEs3MiBMdGQxETAPBgNVBAcMCEF1Y2tsYW5kMREwDwYDVQQIDAhBdWNrbGFuZDELMAkGA1UEBhMCTlowHhcNMDAwMTAxMDAwMDAwWhcNNDkxMTE3MTM0NjM5WjCBpDE1MDMGA1UEAwwsQ2hhcmxlcyBQcm94eSBDQSAoMjAgU2VwIDIwMjAsIEMwMkQzN0VITUQ2UikxJTAjBgNVBAsMHGh0dHBzOi8vY2hhcmxlc3Byb3h5LmNvbS9zc2wxETAPBgNVBAoMCFhLNzIgTHRkMREwDwYDVQQHDAhBdWNrbGFuZDERMA8GA1UECAwIQXVja2xhbmQxCzAJBgNVBAYTAk5aMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoMCTz31wG8zGwexoelqWd+q9WzQHtkFCReKjw0qRZ/8gjmUuj6pdmEg6FQFrf9gnIiyPeME+J1gOfIp3z9i860VjviQGUwuPCBuU8G0eXBYZOE2kJvKx1G5QeI/chnGi3a3Sk5bGBUV1mMbS35OUkFVgvBygVyEjOF1SKDM/IT9jh5QV8uzhObDk+0F6mjZ+uug2CDdQLNd4VqMClXrDaFk2gVpcnDatNI0p6doBlsxMedIFw0wPJaXfdl1MCkPOwqgDpgh4J/3roGwJ5ky9zbE7l552jm/UjTRt5X7608IO5G0Kd5OutvxyqmZUmYLDS0wcS+vZrPA6WwPUgT+TeQIDAQABo4IBdDCCAXAwDwYDVR0TAQH/BAUwAwEB/zCCASwGCWCGSAGG+EIBDQSCAR0TggEZVGhpcyBSb290IGNlcnRpZmljYXRlIHdhcyBnZW5lcmF0ZWQgYnkgQ2hhcmxlcyBQcm94eSBmb3IgU1NMIFByb3h5aW5nLiBJZiB0aGlzIGNlcnRpZmljYXRlIGlzIHBhcnQgb2YgYSBjZXJ0aWZpY2F0ZSBjaGFpbiwgdGhpcyBtZWFucyB0aGF0IHlvdSdyZSBicm93c2luZyB0aHJvdWdoIENoYXJsZXMgUHJveHkgd2l0aCBTU0wgUHJveHlpbmcgZW5hYmxlZCBmb3IgdGhpcyB3ZWJzaXRlLiBQbGVhc2Ugc2VlIGh0dHA6Ly9jaGFybGVzcHJveHkuY29tL3NzbCBmb3IgbW9yZSBpbmZvcm1hdGlvbi4wDgYDVR0PAQH/BAQDAgIEMB0GA1UdDgQWBBTtSzIKBzFSToLLgoAPM4tSPWqDEDANBgkqhkiG9w0BAQsFAAOCAQEAnB+8XuuZAtE3WE03xIu3rHw+sYdrSvV0es/xt1L2/gnnll/W7PvK4prG62sagblbbnLECLy8AKfN/gh9aY9i6EXxee+vVy8GC8Cmo4TIv0asmPqUXBv+ggZCRNvnT1mtCvpkjgeEwGTXjqk6Caq1X61WDzTg/EBPpqhSX10BTFRXLufVMfC/Qy5EdpgwCOm8SZnEwqgAW62GM81Lngl+WIM+NLX5sdtSmkuhfikNR5rRvFPIjBU1t9qP77l/24Ov5BsGjcMfk3Pjzdqy8V17WhQGRhb/k6nzlxrxWmQ4rdNVtKLWHD9ubozsX23z6B8l1GMDzYr3VbxdMpGPV5eiGA==-----END CERTIFICATE-----

用openssl解析证书:

openssl x509 -text -in ~/Downloads/charles-ssl-proxying-certificate.pem

得到如下输出:

关于SSL PINNING的一切_证书_摘要 智能

Certificate: Data: Version: 3 (0x2) Serial Number: 04:00:00:00:00:01:0f:86:26:e6:0d Signature Algorithm: sha1WithRSAEncryption Issuer: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign Validity Not Before: Dec 15 08:00:00 2006 GMT Not After : Dec 15 08:00:00 2021 GMT Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:a6:cf:24:0e:be:2e:6f:28:99:45:42:c4:ab:3e: 21:54:9b:0b:d3:7f:84:70:fa:12:b3:cb:bf:87:5f: c6:7f:86:d3:b2:30:5c:d6:fd:ad:f1:7b:dc:e5:f8: 60:96:09:92:10:f5:d0:53:de:fb:7b:7e:73:88:ac: 52:88:7b:4a:a6:ca:49:a6:5e:a8:a7:8c:5a:11:bc: 7a:82:eb:be:8c:e9:b3:ac:96:25:07:97:4a:99:2a: 07:2f:b4:1e:77:bf:8a:0f:b5:02:7c:1b:96:b8:c5: b9:3a:2c:bc:d6:12:b9:eb:59:7d:e2:d0:06:86:5f: 5e:49:6a:b5:39:5e:88:34:ec:bc:78:0c:08:98:84: 6c:a8:cd:4b:b4:a0:7d:0c:79:4d:f0:b8:2d:cb:21: ca:d5:6c:5b:7d:e1:a0:29:84:a1:f9:d3:94:49:cb: 24:62:91:20:bc:dd:0b:d5:d9:cc:f9:ea:27:0a:2b: 73:91:c6:9d:1b:ac:c8:cb:e8:e0:a0:f4:2f:90:8b: 4d:fb:b0:36:1b:f6:19:7a:85:e0:6d:f2:61:13:88: 5c:9f:e0:93:0a:51:97:8a:5a:ce:af:ab:d5:f7:aa: 09:aa:60:bd:dc:d9:5f:df:72:a9:60:13:5e:00:01: c9:4a:fa:3f:a4:ea:07:03:21:02:8e:82:ca:03:c2: 9b:8f Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Key Identifier: 9B:E2:07:57:67:1C:1E:C0:6A:06:DE:59:B4:9A:2D:DF:DC:19:86:2E X509v3 CRL Distribution Points: Full Name: URI:http://crl.globalsign.net/root-r2.crl X509v3 Authority Key Identifier: keyid:9B:E2:07:57:67:1C:1E:C0:6A:06:DE:59:B4:9A:2D:DF:DC:19:86:2E Signature Algorithm: sha1WithRSAEncryption 99:81:53:87:1c:68:97:86:91:ec:e0:4a:b8:44:0b:ab:81:ac: 27:4f:d6:c1:b8:1c:43:78:b3:0c:9a:fc:ea:2c:3c:6e:61:1b: 4d:4b:29:f5:9f:05:1d:26:c1:b8:e9:83:00:62:45:b6:a9:08: 93:b9:a9:33:4b:18:9a:c2:f8:87:88:4e:db:dd:71:34:1a:c1: 54:da:46:3f:e0:d3:2a:ab:6d:54:22:f5:3a:62:cd:20:6f:ba: 29:89:d7:dd:91:ee:d3:5c:a2:3e:a1:5b:41:f5:df:e5:64:43: 2d:e9:d5:39:ab:d2:a2:df:b7:8b:d0:c0:80:19:1c:45:c0:2d: 8c:e8:f8:2d:a4:74:56:49:c5:05:b5:4f:15:de:6e:44:78:39: 87:a8:7e:bb:f3:79:18:91:bb:f4:6f:9d:c1:f0:8c:35:8c:5d: 01:fb:c3:6d:b9:ef:44:6d:79:46:31:7e:0a:fe:a9:82:c1:ff: ef:ab:6e:20:c4:50:c9:5f:9d:4d:9b:17:8c:0c:e5:01:c9:a0: 41:6a:73:53:fa:a5:50:b4:6e:25:0f:fb:4c:18:f4:fd:52:d9: 8e:69:b1:e8:11:0f:de:88:d8:fb:1d:49:f7:aa:de:95:cf:20: 78:c2:60:12:db:25:40:8c:6a:fc:7e:42:38:40:64:12:f7:9e: 81:e1:93:2e

输出中是没有X509v3 Authority Key Identifier的字段的,根据RFC3280的定义,只有根证书许可省略这个字段:

The keyIdentifier field of the authorityKeyIdentifier extension MUSTbe included in all certificates generated by conforming CAs tofacilitate certification path construction. There is one exception;where a CA distributes its public key in the form of a "self-signed"certificate, the authority key identifier MAY be omitted.

以是这是一个自署名的根证书。
当系统信赖了根证书,那么根证书链下的所有子证书都会被认为合法,证书链的观点下面细说。
Charles的抓包功能是通过中间人攻击来完成的,根证书被信赖,那么Charles只要用一个子证书来欺骗被抓包的客户端,就能绕过TLS对中间人攻击的防护。
在Android 6.0之前,用户信赖的CA证书会被认为是合法的,安装一个根证书就能解密所有App的HTTPS流量,6.0之后加了个限定,只有系统内置的CA证书被信赖,开拓中的运用须要手动信赖用户添加的CA证书才行,这样就只有手动信赖了证书的运用流量能被解密:

<?xml version="1.0" encoding="utf-8"?><network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <trust-anchors> <certificates src="@raw/my_ca"/> </trust-anchors> </domain-config></network-security-config>

那么有没有在高版本Android上全局抓包的方法呢?还真有,对付ROOT过的手机,我们可以导出.0格式的证书,放到系统的/etc/security/cacerts/目录下,这样就会被认为是系统内置CA证书,从而达到抓取所有运用HTTPS流量的目的。

TLS与证书

在讲本文的主题SSL Pinning之前,须要先容一些背景知识,下面几节阐明了TLS握手过程,以及证书的校验过程。

TLS握手

这里又要拿出Cloudflare的经典图了:

这里描述的是TLS1.3之前的情形,细节不再赘述,可以看我之前的文章:TLS握手过程,我们只须要把稳个中一个重点:做事端会把自己的证书发送给客户端,而证书中包含了公钥信息。

证书校验

那么客户端得到证书是如何校验这个证书是合法的呢?这里就要引入证书链的观点,以Google为例:

可以看到,这里一共是有三级证书的,自底向上分别被称为终极实体证书,中间证书和根证书。
把三个证书拖出来,分别存成文件:

证书都是cer后缀,我们考试测验用DER解码,先看看终极实体证书:

openssl x509 -text -inform der -in ~/Downloads/\.google.com.cer

输出如下信息:

Certificate: Data: Version: 3 (0x2) Serial Number: 31:79:87:25:0f:c0:be:e8:08:00:00:00:00:56:05:ed Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, O=Google Trust Services, CN=GTS CA 1O1 Validity Not Before: Aug 26 08:08:49 2020 GMT Not After : Nov 18 08:08:49 2020 GMT Subject: C=US, ST=California, L=Mountain View, O=Google LLC, CN=.google.com Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:8e:14:e9:f8:bb:ae:1f:c4:64:53:b7:d6:7a:76: 50:8b:ab:05:c6:2e:71:32:e0:3e:db:ef:1e:5a:34: 43:a4:74:6a:2b:52:38:75:03:f0:2d:fa:e6:da:82: 10:92:53:9b:a0:0e:28:ea:61:68:2b:0c:6d:df:22: da:5f:14:1b:90 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Basic Constraints: critical CA:FALSE X509v3 Subject Key Identifier: 96:65:7B:C2:08:15:03:E1:C3:F8:50:DD:8F:B6:73:65:43:DF:8C:80 X509v3 Authority Key Identifier: keyid:98:D1:F8:6E:10:EB:CF:9B:EC:60:9F:18:90:1B:A0:EB:7D:09:FD:2B Authority Information Access: OCSP - URI:http://ocsp.pki.goog/gts1o1core CA Issuers - URI:http://pki.goog/gsr2/GTS1O1.crt X509v3 Subject Alternative Name: DNS:.google.com, DNS:.android.com, DNS:.appengine.google.com, DNS:.bdn.dev, DNS:.cloud.google.com, DNS:.crowdsource.google.com, DNS:.datacompute.google.com, DNS:.g.co, DNS:.gcp.gvt2.com, DNS:.gcpcdn.gvt1.com, DNS:.ggpht.cn, DNS:.gkecnapps.cn, DNS:.google-analytics.com, DNS:.google.ca, DNS:.google.cl, DNS:.google.co.in, DNS:.google.co.jp, DNS:.google.co.uk, DNS:.google.com.ar, DNS:.google.com.au, DNS:.google.com.br, DNS:.google.com.co, DNS:.google.com.mx, DNS:.google.com.tr, DNS:.google.com.vn, DNS:.google.de, DNS:.google.es, DNS:.google.fr, DNS:.google.hu, DNS:.google.it, DNS:.google.nl, DNS:.google.pl, DNS:.google.pt, DNS:.googleadapis.com, DNS:.googleapis.cn, DNS:.googlecnapps.cn, DNS:.googlecommerce.com, DNS:.googlevideo.com, DNS:.gstatic.cn, DNS:.gstatic.com, DNS:.gstaticcnapps.cn, DNS:.gvt1.com, DNS:.gvt2.com, DNS:.metric.gstatic.com, DNS:.urchin.com, DNS:.url.google.com, DNS:.wear.gkecnapps.cn, DNS:.youtube-nocookie.com, DNS:.youtube.com, DNS:.youtubeeducation.com, DNS:.youtubekids.com, DNS:.yt.be, DNS:.ytimg.com, DNS:android.clients.google.com, DNS:android.com, DNS:developer.android.google.cn, DNS:developers.android.google.cn, DNS:g.co, DNS:ggpht.cn, DNS:gkecnapps.cn, DNS:goo.gl, DNS:google-analytics.com, DNS:google.com, DNS:googlecnapps.cn, DNS:googlecommerce.com, DNS:source.android.google.cn, DNS:urchin.com, DNS:www.goo.gl, DNS:youtu.be, DNS:youtube.com, DNS:youtubeeducation.com, DNS:youtubekids.com, DNS:yt.be X509v3 Certificate Policies: Policy: 2.23.140.1.2.2 Policy: 1.3.6.1.4.1.11129.2.5.3 X509v3 CRL Distribution Points: Full Name: URI:http://crl.pki.goog/GTS1O1core.crl 1.3.6.1.4.1.11129.2.4.2:.v.....7~.b....a...{7.V..&[...K.ATn...t........G0E. .i...V.i.U....g..}"..d.6.../R.V+.!..X..#.....S.}..7../.l.V=G....d....GF0M..j-u....~f.HZ Signature Algorithm: sha256WithRSAEncryption 2f:de:47:43:cd:2d:0a:ed:6f:6d:3c:4b:39:0e:e6:05:17:74: 58:a7:33:f0:a1:10:0a:52:94:55:80:52:8a:5c:a0:88:73:35: 55:cd:d9:51:72:de:c2:96:5c:52:83:f2:ca:05:a1:72:60:06: 8e:da:4d:80:05:6a:60:fe:60:ab:cc:dc:02:67:84:41:47:cd: eb:af:80:6b:ec:d5:0d:6e:56:5a:bd:00:47:d8:62:2f:4c:01: 93:76:10:bb:16:15:ca:d4:d9:b2:92:0e:5d:96:56:06:95:c3: a6:d6:77:fb:97:b6:2f:66:06:7c:0c:21:91:ac:8c:84:16:61: 40:02:a9:f1:ca:62:e3:e0:72:da:7b:ab:3f:64:27:bb:d0:ff: de:a0:c4:6d:a3:72:1d:bc:0e:1d:a7:6a:07:15:69:70:aa:63: d2:68:ed:50:d2:44:c4:21:ca:b4:ec:73:0b:0c:b2:86:17:fa: cd:4a:ca:57:2c:56:9d:17:10:0e:68:ce:6d:e1:00:d4:65:f1: 11:63:9f:e4:07:d9:fb:eb:36:7e:77:bc:94:a3:c5:04:8c:ca: fa:ec:7a:a3:33:fb:b1:65:82:d0:2b:e7:02:29:f9:c4:91:da: 3e:62:3e:8a:da:29:c2:91:bb:60:cf:d6:d2:f4:5b:a5:19:37: b1:ae:b8:7e

信息量非常大,我们关注几个关键字段:Signature Algorithm: sha256WithRSAEncryption表示证书的署名是先利用SHA256做择要,再对择要做RSA加密天生的。
Public Key Algorithm: id-ecPublicKey,表示公钥的算法是ECDSA,这是一个ECC证书,比较RSA算法,ECDSA的证书更小,运算也更快。
X509v3 Authority Key Identifier,不须要关心内容,有这个字段表示这不是自署名的根证书。
X509v3 Subject Alternative Name,这里包含了证书适用的域名。
末了还有一段Signature Algorithm,这便是证书的署名,合营前面的证书署名算法可以完成证书链的校验。
中间证书的构造大同小异,这里列出用于校验的关键信息:

Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:d0:18:cf:45:d4:8b:cd:d3:9c:e4:40:ef:7e:b4: dd:69:21:1b:c9:cf:3c:8e:4c:75:b9:0f:31:19:84: 3d:9e:3c:29:ef:50:0d:10:93:6f:05:80:80:9f:2a: a0:bd:12:4b:02:e1:3d:9f:58:16:24:fe:30:9f:0b: 74:77:55:93:1d:4b:f7:4d:e1:92:82:10:f6:51:ac: 0c:c3:b2:22:94:0f:34:6b:98:10:49:e7:0b:9d:83: 39:dd:20:c6:1c:2d:ef:d1:18:61:65:e7:23:83:20: a8:23:12:ff:d2:24:7f:d4:2f:e7:44:6a:5b:4d:d7: 50:66:b0:af:9e:42:63:05:fb:e0:1c:c4:63:61:af: 9f:6a:33:ff:62:97:bd:48:d9:d3:7c:14:67:dc:75: dc:2e:69:e8:f8:6d:78:69:d0:b7:10:05:b8:f1:31: c2:3b:24:fd:1a:33:74:f8:23:e0:ec:6b:19:8a:16: c6:e3:cd:a4:cd:0b:db:b3:a4:59:60:38:88:3b:ad: 1d:b9:c6:8c:a7:53:1b:fc:bc:d9:a4:ab:bc:dd:3c: 61:d7:93:15:98:ee:81:bd:8f:e2:64:47:20:40:06: 4e:d7:ac:97:e8:b9:c0:59:12:a1:49:25:23:e4:ed: 70:34:2c:a5:b4:63:7c:f9:a3:3d:83:d1:cd:6d:24: ac:07 Exponent: 65537 (0x10001)

这一段给出了中间证书的公钥,由于是RSA算法,以是这里有一个Modulus和一个Exponent。
终极实体证书的署名是用中间证书的私钥对终极实体证书的择要加密得到,以是对应的解密过程是用中间证书的公钥解密终极实体证书的署名,能得出终极实体证书的择要,如果能解密成功,就能确认终极实体证书确实是由中间证书署名的,再对终极实体证书做一次择要,和解密出得择要比对,如果同等即可确认证书没用被修改过。
我们手动实现一下这个过程:已知指数,模和密文,我们须要还原出原文,根据RSA算法,打算原文的算法如下,个中m是明文,c是密文,e是指数,n是模:

m = c ^ e (mod n)

代入上面证书里的值:

>>> n = 0x00d018cf45d48bcdd39ce440ef7eb4dd69211bc9cf3c8e4c75b90f3119843d9e3c29ef500d10936f0580809f2aa0bd124b02e13d9f581624fe309f0b747755931d4bf74de1928210f651ac0cc3b222940f346b981049e70b9d8339dd20c61c2defd1186165e7238320a82312ffd2247fd42fe7446a5b4dd75066b0af9e426305fbe01cc46361af9f6a33ff6297bd48d9d37c1467dc75dc2e69e8f86d7869d0b71005b8f131c23b24fd1a3374f823e0ec6b198a16c6e3cda4cd0bdbb3a4596038883bad1db9c68ca7531bfcbcd9a4abbcdd3c61d7931598ee81bd8fe264472040064ed7ac97e8b9c05912a1492523e4ed70342ca5b4637cf9a33d83d1cd6d24ac07>>> e = 65537>>> c = 0x2fde4743cd2d0aed6f6d3c4b390ee605177458a733f0a1100a52945580528a5ca088733555cdd95172dec2965c5283f2ca05a17260068eda4d80056a60fe60abccdc0267844147cdebaf806becd50d6e565abd0047d8622f4c01937610bb1615cad4d9b2920e5d96560695c3a6d677fb97b62f66067c0c2191ac8c8416614002a9f1ca62e3e072da7bab3f6427bbd0ffdea0c46da3721dbc0e1da76a07156970aa63d268ed50d244c421cab4ec730b0cb28617facd4aca572c569d17100e68ce6de100d465f111639fe407d9fbeb367e77bc94a3c5048ccafaec7aa333fbb16582d02be70229f9c491da3e623e8ada29c291bb60cfd6d2f45ba51937b1aeb87e>>> pow(c, e, n)986236757547332986472011617696226561292849812918563355472727826767720188564083584387121625107510786855734801053524719833194566624465665316622563244215340671405971599343902468620306327831715457360719532421388780770165778156818229863337344187575566725786793391480600129482653072861971002459947277805295727097226389568776499707662505334062639449916265137796823793276300221537201727072401742985542559596685092673521228140822200236743113743661549252453726123450722876929538747702356573783116197523966334991563351853851212597377279504828784763247643211048750059383511539240076118611220389103205312907651075225923933445>>> print('0x%x' % pow(c, e, n))0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420cd55ba8e69bcc9a1c2aaba552982abd5519051f5708cb6f9885cd3a7d28cd505

末了这一段密文便是终极实体证书的择要,我们再用openssl手动算一次择要,看是否同等。
先把证书转换成ANS.1格式,这是一种和protobuffer很相似的描述,都是tag, length, value的形式。

openssl asn1parse -inform der -in ~/Downloads/\.google.com.cer

输出如下:

0:d=0 hl=4 l=2416 cons: SEQUENCE 4:d=1 hl=4 l=2136 cons: SEQUENCE 8:d=2 hl=2 l= 3 cons: cont [ 0 ] 10:d=3 hl=2 l= 1 prim: INTEGER :02 13:d=2 hl=2 l= 16 prim: INTEGER :317987250FC0BEE808000000005605ED 31:d=2 hl=2 l= 13 cons: SEQUENCE 33:d=3 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption 44:d=3 hl=2 l= 0 prim: NULL 46:d=2 hl=2 l= 66 cons: SEQUENCE 48:d=3 hl=2 l= 11 cons: SET 50:d=4 hl=2 l= 9 cons: SEQUENCE 52:d=5 hl=2 l= 3 prim: OBJECT :countryName 57:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US 61:d=3 hl=2 l= 30 cons: SET 63:d=4 hl=2 l= 28 cons: SEQUENCE 65:d=5 hl=2 l= 3 prim: OBJECT :organizationName 70:d=5 hl=2 l= 21 prim: PRINTABLESTRING :Google Trust Services 93:d=3 hl=2 l= 19 cons: SET 95:d=4 hl=2 l= 17 cons: SEQUENCE 97:d=5 hl=2 l= 3 prim: OBJECT :commonName 102:d=5 hl=2 l= 10 prim: PRINTABLESTRING :GTS CA 1O1 114:d=2 hl=2 l= 30 cons: SEQUENCE 116:d=3 hl=2 l= 13 prim: UTCTIME :200826080849Z 131:d=3 hl=2 l= 13 prim: UTCTIME :201118080849Z 146:d=2 hl=2 l= 102 cons: SEQUENCE 148:d=3 hl=2 l= 11 cons: SET 150:d=4 hl=2 l= 9 cons: SEQUENCE 152:d=5 hl=2 l= 3 prim: OBJECT :countryName 157:d=5 hl=2 l= 2 prim: PRINTABLESTRING :US 161:d=3 hl=2 l= 19 cons: SET 163:d=4 hl=2 l= 17 cons: SEQUENCE 165:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName 170:d=5 hl=2 l= 10 prim: PRINTABLESTRING :California 182:d=3 hl=2 l= 22 cons: SET 184:d=4 hl=2 l= 20 cons: SEQUENCE 186:d=5 hl=2 l= 3 prim: OBJECT :localityName 191:d=5 hl=2 l= 13 prim: PRINTABLESTRING :Mountain View 206:d=3 hl=2 l= 19 cons: SET 208:d=4 hl=2 l= 17 cons: SEQUENCE 210:d=5 hl=2 l= 3 prim: OBJECT :organizationName 215:d=5 hl=2 l= 10 prim: PRINTABLESTRING :Google LLC 227:d=3 hl=2 l= 21 cons: SET 229:d=4 hl=2 l= 19 cons: SEQUENCE 231:d=5 hl=2 l= 3 prim: OBJECT :commonName 236:d=5 hl=2 l= 12 prim: UTF8STRING :.google.com 250:d=2 hl=2 l= 89 cons: SEQUENCE 252:d=3 hl=2 l= 19 cons: SEQUENCE 254:d=4 hl=2 l= 7 prim: OBJECT :id-ecPublicKey 263:d=4 hl=2 l= 8 prim: OBJECT :prime256v1 273:d=3 hl=2 l= 66 prim: BIT STRING 341:d=2 hl=4 l=1799 cons: cont [ 3 ] 345:d=3 hl=4 l=1795 cons: SEQUENCE 349:d=4 hl=2 l= 14 cons: SEQUENCE 351:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage 356:d=5 hl=2 l= 1 prim: BOOLEAN :255 359:d=5 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:03020780 365:d=4 hl=2 l= 19 cons: SEQUENCE 367:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Extended Key Usage 372:d=5 hl=2 l= 12 prim: OCTET STRING [HEX DUMP]:300A06082B06010505070301 386:d=4 hl=2 l= 12 cons: SEQUENCE 388:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints 393:d=5 hl=2 l= 1 prim: BOOLEAN :255 396:d=5 hl=2 l= 2 prim: OCTET STRING [HEX DUMP]:3000 400:d=4 hl=2 l= 29 cons: SEQUENCE 402:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Key Identifier 407:d=5 hl=2 l= 22 prim: OCTET STRING [HEX DUMP]:041496657BC2081503E1C3F850DD8FB6736543DF8C80 431:d=4 hl=2 l= 31 cons: SEQUENCE 433:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Authority Key Identifier 438:d=5 hl=2 l= 24 prim: OCTET STRING [HEX DUMP]:3016801498D1F86E10EBCF9BEC609F18901BA0EB7D09FD2B 464:d=4 hl=2 l= 104 cons: SEQUENCE 466:d=5 hl=2 l= 8 prim: OBJECT :Authority Information Access 476:d=5 hl=2 l= 92 prim: OCTET STRING [HEX DUMP]:305A302B06082B06010505073001861F687474703A2F2F6F6373702E706B692E676F6F672F677473316F31636F7265302B06082B06010505073002861F687474703A2F2F706B692E676F6F672F677372322F475453314F312E637274 570:d=4 hl=4 l=1218 cons: SEQUENCE 574:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Alternative Name 579:d=5 hl=4 l=1209 prim: OCTET STRING [HEX DUMP]:308204B5820C2A2E676F6F676C652E636F6D820D2A2E616E64726F69642E636F6D82162A2E617070656E67696E652E676F6F676C652E636F6D82092A2E62646E2E64657682122A2E636C6F75642E676F6F676C652E636F6D82182A2E63726F7764736F757263652E676F6F676C652E636F6D82182A2E64617461636F6D707574652E676F6F676C652E636F6D82062A2E672E636F820E2A2E6763702E677674322E636F6D82112A2E67637063646E2E677674312E636F6D820A2A2E67677068742E636E820E2A2E676B65636E617070732E636E82162A2E676F6F676C652D616E616C79746963732E636F6D820B2A2E676F6F676C652E6361820B2A2E676F6F676C652E636C820E2A2E676F6F676C652E636F2E696E820E2A2E676F6F676C652E636F2E6A70820E2A2E676F6F676C652E636F2E756B820F2A2E676F6F676C652E636F6D2E6172820F2A2E676F6F676C652E636F6D2E6175820F2A2E676F6F676C652E636F6D2E6272820F2A2E676F6F676C652E636F6D2E636F820F2A2E676F6F676C652E636F6D2E6D78820F2A2E676F6F676C652E636F6D2E7472820F2A2E676F6F676C652E636F6D2E766E820B2A2E676F6F676C652E6465820B2A2E676F6F676C652E6573820B2A2E676F6F676C652E6672820B2A2E676F6F676C652E6875820B2A2E676F6F676C652E6974820B2A2E676F6F676C652E6E6C820B2A2E676F6F676C652E706C820B2A2E676F6F676C652E707482122A2E676F6F676C656164617069732E636F6D820F2A2E676F6F676C65617069732E636E82112A2E676F6F676C65636E617070732E636E82142A2E676F6F676C65636F6D6D657263652E636F6D82112A2E676F6F676C65766964656F2E636F6D820C2A2E677374617469632E636E820D2A2E677374617469632E636F6D82122A2E67737461746963636E617070732E636E820A2A2E677674312E636F6D820A2A2E677674322E636F6D82142A2E6D65747269632E677374617469632E636F6D820C2A2E75726368696E2E636F6D82102A2E75726C2E676F6F676C652E636F6D82132A2E776561722E676B65636E617070732E636E82162A2E796F75747562652D6E6F636F6F6B69652E636F6D820D2A2E796F75747562652E636F6D82162A2E796F7574756265656475636174696F6E2E636F6D82112A2E796F75747562656B6964732E636F6D82072A2E79742E6265820B2A2E7974696D672E636F6D821A616E64726F69642E636C69656E74732E676F6F676C652E636F6D820B616E64726F69642E636F6D821B646576656C6F7065722E616E64726F69642E676F6F676C652E636E821C646576656C6F706572732E616E64726F69642E676F6F676C652E636E8204672E636F820867677068742E636E820C676B65636E617070732E636E8206676F6F2E676C8214676F6F676C652D616E616C79746963732E636F6D820A676F6F676C652E636F6D820F676F6F676C65636E617070732E636E8212676F6F676C65636F6D6D657263652E636F6D8218736F757263652E616E64726F69642E676F6F676C652E636E820A75726368696E2E636F6D820A7777772E676F6F2E676C8208796F7574752E6265820B796F75747562652E636F6D8214796F7574756265656475636174696F6E2E636F6D820F796F75747562656B6964732E636F6D820579742E6265 1792:d=4 hl=2 l= 33 cons: SEQUENCE 1794:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Certificate Policies 1799:d=5 hl=2 l= 26 prim: OCTET STRING [HEX DUMP]:30183008060667810C010202300C060A2B06010401D679020503 1827:d=4 hl=2 l= 51 cons: SEQUENCE 1829:d=5 hl=2 l= 3 prim: OBJECT :X509v3 CRL Distribution Points 1834:d=5 hl=2 l= 44 prim: OCTET STRING [HEX DUMP]:302A3028A026A0248622687474703A2F2F63726C2E706B692E676F6F672F475453314F31636F72652E63726C 1880:d=4 hl=4 l= 260 cons: SEQUENCE 1884:d=5 hl=2 l= 10 prim: OBJECT :1.3.6.1.4.1.11129.2.4.2 1896:d=5 hl=3 l= 245 prim: OCTET STRING [HEX DUMP]:0481F200F0007600B21E05CC8BA2CD8A204E8766F92BB98A2520676BDAFA70E7B249532DEF8B905E000001742A06F9BD000004030047304502205BB262C173701DC2F4D182C34760FA693875B409B650DA2DBE966D80CB6EE9C8022100CFD52D39644158ED44F23ABE9B4746304D8CAB6A2D75DA92F0187E6688485A0D007600E712F2B0377E1A62FB8EC90C6184F1EA7B37CB561D11265BF3E0F34BF241546E000001742A06F9D2000004030047304502200B69DB8E9756FB698955FA04BF8467C80E7D22C2F364CD36DACDD72F52D1562B022100925882AA2314AAB3009F53A47D93CE377FCB2FCA6C1E563D4716ACEBF264E087 2144:d=1 hl=2 l= 13 cons: SEQUENCE 2146:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption 2157:d=2 hl=2 l= 0 prim: NULL 2159:d=1 hl=4 l= 257 prim: BIT STRING

再看看RFC5280的定义:

Certificate ::= SEQUENCE { tbsCertificate TBSCertificate, signatureAlgorithm AlgorithmIdentifier, signatureValue BIT STRING } TBSCertificate ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, serialNumber CertificateSerialNumber, signature AlgorithmIdentifier, issuer Name, validity Validity, subject Name, subjectPublicKeyInfo SubjectPublicKeyInfo, issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version MUST be v2 or v3

第二行便是TBSCertificate的位置和长度,真正用来打算择要的部分,偏移是4,hl=4表示header长度是4,l=2136表示内容长度是2136,总长度是2140,我们用dd提取出这部分,并对输出结果做SHA256择要:

dd if=/Users/shunix/Downloads/\.google.com.cer of=/Users/shunix/tmp/tbs skip=4 bs=1 count=2140openssl dgst -sha256 ~/tmp/tbs

输出如下:

SHA256(/Users/shunix/tmp/tbs)= cd55ba8e69bcc9a1c2aaba552982abd5519051f5708cb6f9885cd3a7d28cd505

而上面我们用公钥解出来的择要去掉前面的

0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003031300d060960864801650304020105000420

末了结果也是cd55ba8e69bcc9a1c2aaba552982abd5519051f5708cb6f9885cd3a7d28cd505,二者完备同等,解释终极实体证书没有被修改过。
而中间证书和根证书的校验也是同样的过程,这里就不赘述。
根证书是自署名的,乃至都可以不用署名,由于根证书是内置到系统里的。
CA之以是不直接从根证书发布终极实体证书是由于这样风险太大,一旦涌现缺点发布随意马虎导致根证书不受信赖,以是CA会从根证书发布中间证书,再从中间证书发布终极实体证书,完成自我隔离。
当然,根证书也是有不被信赖的先例的,比如Firefox和Chrome在2015年移除了对CNNIC根证书的信赖,详细缘故原由就不细讲了。

SSL PINNING

综上所述,有几种情形SSL是无法担保安全的:

某些wifi或者网站哀求装个根证书才能连续利用,比如某订票网站被信赖的CA随意发布证书,比如赛门铁克,17年居然发布了example.com的证书,挺缺德的

以是客户端供应了一种额外的机制来担保HTTPS通信的安全,SSL Pinning,SSL Pinning又可以细分为Certificate Pinning和Public Key Pinning。

CERTIFICATE PINNING

Certificate Pinning也便是证书锁定,大略来说便是把证书文件打包进安装包,通过加载本地证书自定义TrustManager,进而创建自定义的SSLSocketFactory来完成的,这里贴一些关键代码:

fun loadCertificate(): Certificate { // 假设证书放在assets下 return BaseApplication.instance.assets .open("shunix.cert").use { input -> CertificateFactory.getInstance("X.509").generateCertificate(input) }}fun getTrustManager(): TrustManager { val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply { setCertificateEntry("shunix", loadCertificate()) } return TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).run { init(keyStore) trustManagers[0] }}fun getSSLSocketFactory(): SSLSocketFactory { val sslContext = SSLContext.getInstance("TLS").apply { init(null, arrayOf(getTrustManager()), null) } return sslContext.socketFactory}FALLBACK策略

内置证书的方案存在一个问题,证书是会过期的,一样平常终极实体证书也便是一年的有效期,而中间证书和根证书有效期都是10年旁边,超过绝大多数运用的生命周期了,以是一个比较大略的做法是同时内置中间证书或者根证书作为子证书过期的应对方案。
中间证书和根证书一样平常都是同一个机构的,以是选哪一个并没有实质的差异,但是这样在安全性上会有一定的妥协,可以参考前面提到的赛门铁克和CNNIC证书,当根证书不被信赖,一样会出问题,还有便是如果改换证书的CA也是做不到的,局限性很大。

那么能不能只内置终极实体证书,同时能办理有效期的问题呢?很自然地会想到动态更新本地证书,那就带来了另一个问题,如何担保本地证书更新的安全性呢?这是一个鸡生蛋蛋生鸡的问题,实在不讲究点,更新证书的要求可以直接走没有证书锁定的HTTPS完成,由于HTTPS被挟制本身便是小概率情形。
如果追求完美的话,有一个比较麻烦的办理方案,便是再打包一个自署名的证书到安装包,锁定这个自署名的证书来更新终极实体证书,自署名证书有效期可以自定义,定的足够长就好,当然做事端也须要做相应改造,是否须要这么严格的安全策略就看业务场景了。

PUBLIC KEY PINNING

Certificate Pinning实现过于繁琐,同时局限性比较大,以是就有了锁定Subject Public Key Info的实现。
申请过证书的都知道,须要供应算法和公钥,纵然改换新证书,这两个东西也是可以保持不变的,Android 7.0以上供应了非常方便的实现,只须要在res/xml/network_security_config.xml里加如下配置:

<?xml version="1.0" encoding="utf-8"?><network-security-config> <domain-config> <domain includeSubdomains="true">example.com</domain> <pin-set expiration="2018-01-01"> <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin> <!-- backup pin --> <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin> </pin-set> </domain-config></network-security-config>

可以参考Android官方文档:https://developer.android.com/training/articles/security-config#CertificatePinning这里pin的是Base64编码后的Subject Public Key Info(SPKI)的哈希,详细天生方法可以参考Mozilla的文档:https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning#Extracting_the_Base64_encoded_public_key_information

FALLBACK策略

虽然基于公钥的锁定不存在证书过期的问题,但依然须要fallback策略,由于可能存在私钥泄露的情形下,这种情形下须要重新发布证书,公钥私钥都会改变。
Android许可pin多个SPKI,只要符合一个就能正常通信,以是这里可以pin几个CA的根证书或者中间证书的SPKI,会丢失一点安全性,但是为私钥泄露的情形留下了操作空间。

结语

纵然做了SSL Pinning,依然有HTTPS被挟制,内容被修改的可能,比如对付证书锁定的办法,可以直接更换掉apk里的证书,再做重打包,对付公钥锁定的办法,可以通过hook RootTrustManager的办法直接绕过验证。
做事端须要在业务上对客户端要求做验证,只依赖机制上的安全是不足的,道高一尺魔高一丈,客户端和做事端该当互不信赖,对付输入须要做足够的校验,这并不是一种overhead。

作者:SHUNIX

出处:https://shunix.com/ssl-pinning/

相关文章

FPGA实验-串口通信之战_模块_数据

UART串行接口简称串口,是我们各种芯片最常用的一种异步通信接口,通过这样的串口我们就可以建立起打算机和我们实验板之间的通信和掌握...

智能 2025-01-21 阅读2 评论0