說(shuō)點(diǎn)廢話,我一直覺(jué)得APPLE是個(gè)非常激進(jìn)的公司蛀缝, 從早些的Flash顷链,到現(xiàn)在的http,又比如新的Mac連USB口都不給屈梁。公司大到這個(gè)量級(jí)嗤练,已經(jīng)可以憑一己之力促進(jìn)先進(jìn)技術(shù)的普及了。
本文內(nèi)容分為以下三部分
- HTTPS協(xié)議
- 使用Let's Encrypt在后端部署https服務(wù)
- https在iOS上的正確使用姿勢(shì)
Part1 HTTPS協(xié)議
普通的HTTP請(qǐng)求在讶,在通信雙方建立了TCP連接之后煞抬,就可以進(jìn)行了。而HTTPS則不同构哺,在建立TCP連接之后革答,需要先進(jìn)行SSL協(xié)議的握手過(guò)程,然后才是HTTP的通信曙强。
SSL的握手過(guò)程如下圖所示
alice想要與bob進(jìn)行https的通信残拐,需要以下幾步
- alice給出協(xié)議版本號(hào)、一個(gè)客戶端生成的隨機(jī)數(shù)(Client random)旗扑,以及客戶端支持的加密方法蹦骑。
- bob確認(rèn)雙方使用的加密方法,并給出數(shù)字證書(shū)(包含bob的公鑰)臀防、以及一個(gè)服務(wù)器生成的隨機(jī)數(shù)(Server random)眠菇。
- alice 確認(rèn)數(shù)字證書(shū)(向CA確認(rèn))有效,然后生成一個(gè)新的隨機(jī)數(shù)(Premaster secret)袱衷,并使用數(shù)字證書(shū)中的公鑰捎废,加密這個(gè)隨機(jī)數(shù),發(fā)給鮑勃致燥。
- bob使用自己的私鑰登疗,獲取愛(ài)麗絲發(fā)來(lái)的隨機(jī)數(shù)(即Premaster secret)。
- alice和bob根據(jù)約定的加密方法,使用前面的三個(gè)隨機(jī)數(shù)辐益,生成"對(duì)話密鑰"(session key)断傲,用來(lái)加密接下來(lái)的整個(gè)對(duì)話過(guò)程。
上述步驟的最終目的智政,是為了生成”對(duì)話密鑰“认罩,以后的通信都使用這個(gè)密鑰進(jìn)行對(duì)稱加密(一般對(duì)稱加解密的速度是比較快的)
那么看到這里,就又一個(gè)問(wèn)題出現(xiàn)了续捂。握手階段的信息安全如何保障垦垂?
答案是無(wú)法保障。整個(gè)握手階段牙瓢,都是明文的劫拗。因此如果有第三方竊聽(tīng)了通信,他可以獲得Client random矾克、Server random以及加密后的Premaster secret页慷。只要第三方無(wú)法破解Premaster secret的內(nèi)容,那么通信就是安全的聂渊。
Part2 使用Let's Encrypt在后端部署https服務(wù)
可以參考這篇文章
How To Secure Nginx with Let's Encrypt on Ubuntu 16.04
大致步驟
- 安裝certbot客戶端
- 配置服務(wù)器允許方案 /.well-known文件夾
- sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com 這個(gè)命令會(huì)生成你需要的證書(shū)等文件
- 配置Nginx ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
如果速度很慢多半是python的源被墻了差购,需要改一下pip配置。
Let's Encrypt大法好汉嗽,退沃通保平安欲逃!
Part3 在iOS上使用自己頒發(fā)的HTTPS證書(shū)的正確姿勢(shì)
在開(kāi)發(fā)環(huán)境,也需要進(jìn)行HTTPS的話饼暑,需要對(duì)AFN進(jìn)行兩個(gè)設(shè)置:允許不合法的證書(shū)和不驗(yàn)證域名
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:[self host]]];
manager.securityPolicy.allowInvalidCertificates = YES;
manager.securityPolicy.validatesDomainName = NO;