gRPC源碼分析1-SSL/TLS

来源:http://www.cnblogs.com/parse-code/archive/2016/12/18/6194934.html
-Advertisement-
Play Games

引子 前幾天看到微信後臺團隊分享了TLS相關文章,正好gRPC里TLS數據加密是很重要的一塊,於是整理出了這篇文章。 在gRPC里,如果僅僅是用來做後端微服務,可以考慮不加密。本文太長,先給個大綱。 1. HTTPS,HTTP/2介紹 2. TLS加密原理、實現庫 3. HTTP/2協議協商機制 4 ...


引子

前幾天看到微信後臺團隊分享了TLS相關文章,正好gRPC里TLS數據加密是很重要的一塊,於是整理出了這篇文章。

 

在gRPC里,如果僅僅是用來做後端微服務,可以考慮不加密。本文太長,先給個大綱。

1. HTTPS,HTTP/2介紹

2. TLS加密原理、實現庫

3. HTTP/2協議協商機制

4. 自建數字證書(CA)

5. gRPC使用TLS

 

1. HTTP/1.x

目前絕大多數網站和APP都是建立在HTTP之上的,所有的數據都是明文傳輸,沒有任何安全可言。

網圖 

2. HTTPS

HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)是以安全為目標的HTTP通道,即HTTP下加入SSL層,HTTPS的安全基礎是SSL。用來保護用戶隱私,防止流量劫持。


(網圖,懶得畫了) 

2.1 HTTPS的作用(來自百度)

  • 認證用戶和伺服器,確保數據發送到正確的客戶機和伺服器;(驗證證書)

  • 加密數據以防止數據中途被竊取;(加密)

  • 維護數據的完整性,確保數據在傳輸過程中不被改變。(摘要演算法)

 

HTTPS之所以安全,就是HTTP建立在SSL/TLS之上的。

(網圖)

 

SSL/TLS協議的基本思路是採用公鑰加密法,也就是說,客戶端先向伺服器端索要公鑰,然後用公鑰加密信息,伺服器收到密文後,用自己的私鑰解密。

 

(1)如何保證公鑰不被篡改?

將公鑰放在數字證書中。只要證書是可信的,公鑰就是可信的。

 

(2)公鑰加密計算量太大,如何減少耗用的時間?

每一次對話,客戶端和伺服器端都生成一個”對話密鑰”,用它來加密信息。由於”對話密鑰”是對稱加密,所以運算速度非常快,而伺服器公鑰只用於加密”對話密鑰”本身,這樣就減少了加密運算的消耗時間。

 

也就是說,對於HTTPS,由於成本問題

  • 握手階段(handshake)用的非對稱加密

  • 數據通信用的是對稱加密

 

2.2 加密演算法

我們大致的講一下加密相關術語。由於密碼學太過複雜,我們不去深究,也千萬別問我為什麼公鑰加密後,能夠用私鑰解密。

(主要是數學太難,門檻太高,我也不懂,逃。。。) 

對稱密鑰

又稱為共用密鑰加密,對稱密鑰在加密和解密的過程中使用的密鑰是相同的,常見的對稱加密演算法有DES、3DES、AES、RC5、RC6。對稱密鑰的優點是計算速度快,但是密鑰需要在通訊的兩端共用,讓彼此知道密鑰是什麼對方纔能正確解密,如果所有客戶端都共用同一個密鑰,那麼這個密鑰就像萬能鑰匙一樣,可以憑藉一個密鑰破解所有人的密文了。

非對稱密鑰

服務端會生成一對密鑰,一個私鑰保存在服務端,僅自己知道,另一個是公鑰,公鑰可以自由發佈供任何人使用。客戶端的明文通過公鑰加密後的密文需要用私鑰解密。非對稱密鑰在加密和解密的過程的使用的密鑰是不同的密鑰,加密和解密是不對稱的,所以稱之為非對稱加密。與對稱密鑰加密相比,非對稱加密無需在客戶端和服務端之間共用密鑰,只要私鑰不發給任何用戶,即使公鑰在網上被截獲,也無法被解密,僅有被竊取的公鑰是沒有任何用處的。常見的非對稱加密有RSA。

 

數字簽名

數字簽名就如同日常生活中的簽名一樣,這是任何人都沒法仿造的。在電腦中的數字簽名就是用於驗證傳輸的內容是不是真實伺服器發送的數據,發送的數據有沒有被篡改過。

 

數字證書

數字證書簡稱CA,它由權威機構給某網站頒發的一種認可憑證,這個憑證是被大家(瀏覽器)所認可的。

 

3. HTTP/2

HTTP/2,主要是基於Google的SPDY協議,是自HTTP/1.1從1999年發佈16年後的首次更新。Servlet4.0將完全支持HTTP/2。

3.1 HTTP/1.1的問題

  • 假設一個網站需要載入幾十個資源(css、js、jpg、等等),等到html文件載入成功後,瀏覽器會一個一個請求這些資源,並等待伺服器按順序一個一個返回。

  • 一個請求,一個應答
  • http header

3.2 HTTP/2主要特性:

  • request/response多路復用(multiplexing)

  • 二進位幀傳輸(binary framing)

  • 數據流優先順序(stream prioritization)

  • 伺服器推送(server push)

  • 頭信息壓縮(header compression)

 

HTTP/2是站在HTTP/1.1肩膀上的一個改進而已,跟HTTP/1.1相比:

  • 相同的request/response模式

  • 沒有新的method

  • 沒有新的header

  • 在應用層沒有引入新的花樣

  • 沒有修改URL規範、沒有修改其他底層規範

 

HTTP/2僅是一個協議而已,它可以建立在TLS之上,也可以不。但是,根據 http://caniuse.com/,網站的統計,瀏覽器幾乎只支持安全的HTTP/2,也就是說如果是網站的話,想要升到HTTP/2就必須支持HTTPS。當然如gRPC這種內部的服務開發,可以不用支持TLS。

3.3 HTTP/2 的協議協商機制

一個網站支不支持HTTP/2,對於瀏覽器來說是不知道的,只能通過兩者的協商來確定是否使用HTTP/2協議,還是HTTP/1.1。我們分2種來講。

a. HTTP(without TLS)

為了更方便地部署新協議,HTTP/1.1 引入了 Upgrade 機制,它使得客戶端和服務端之間可以藉助已有的 HTTP 語法升級到其它協議。

 

如果大家之前使用過 WebSocket,應該已經對 HTTP Upgrade 機制有所瞭解。下麵是建立 WebSocket 連接的 HTTP 請求

GET ws://example.com/ HTTP/1.1

Connection: Upgrade

Upgrade: websocket

Origin: http://example.com

Sec-WebSocket-Version: 13

Sec-WebSocket-Key: d4egt7snxxxxxx2WcaMQlA==

Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

 

這是服務端同意升級的 HTTP 響應:

HTTP/1.1 101 Switching Protocols

Connection: Upgrade

Upgrade: websocket

Sec-WebSocket-Accept: gczJQPmQ4Ixxxxxx6pZO8U7UbZs=

 

在這之後,客戶端和服務端之間就可以使用 WebSocket 協議進行雙向數據通訊,跟 HTTP/1.1 沒關係了。可以看到,WebSocket 連接的建立就是典型的 HTTP Upgrade 機制。顯然,這個機制也可以用做 HTTP/1.1 到 HTTP/2 的協議升級。

 

b. HTTPS(with TLS)

多了 TLS 之後,雙方必須等到成功建立 TLS 連接之後才能發送應用數據。而要建立 TLS 連接,本來就要進行 CipherSuite 等參數的。引入 HTTP/2 之後,需要做的只是在原本的協商機制中把對 HTTP 協議的協商加進去。Google 在 SPDY 協議中開發了一個名為 NPN(Next Protocol Negotiation,下一代協議協商)的 TLS 擴展。隨著 SPDY 被 HTTP/2 取代,NPN 也被官方修訂為 ALPN(Application Layer Protocol Negotiation,應用層協議協商)。

 

下圖,是caniuse.com網站統計的支持HTTP/2的瀏覽器版本,以及支持的協商協議。可以看到chrome到41版本才支持,IE根本不支持。

 

4. SSL/TLS

互聯網加密通信協議的歷史,幾乎與互聯網一樣長。

 

  • 1994年,NetScape公司設計了SSL協議(Secure Sockets Layer)的1.0版,但是未發佈。

  • 1995年,NetScape公司發佈SSL 2.0版,很快發現有嚴重漏洞。

  • 1996年,SSL 3.0版問世,得到大規模應用。

  • 1999年,互聯網標準化組織ISOC接替NetScape公司,發佈了SSL的升級版TLS 1.0版。

  • 2006年和2008年,TLS進行了兩次升級,分別為TLS 1.1版和TLS 1.2版。最新的變動是2011年TLS 1.2的修訂版。

 

目前常用的 HTTP 協議是 HTTP1.1,常用的 TLS 協議版本有如下幾個:TLS1.2, TLS1.1, TLS1.0 和 SSL3.0。

  • 其中 SSL3.0 由於 POODLE 攻擊已經被證明不安全

  • TLS1.0 也存在部分安全漏洞,比如 RC4 和 BEAST 攻擊

  • TLS1.2 和 TLS1.1 暫時沒有已知的安全漏洞,比較安全,同時有大量擴展提升速度和性能,推薦

 

那麼如何建立TLS鏈接的呢?大概步驟如下:

(網圖)

  1. 客戶端將自己支持的一套加密演算法、HASH演算法發送給服務端

  2. 服務端從中選出一組加密演算法與HASH演算法,並將自己的身份信息以證書的形式發回給客戶端。證書裡面包含了服務端的地址(功能變數名稱),加密公鑰,以及證書的頒發機構等信息

  3. 客戶端獲得證書之後,開始驗證證書的合法性,如果證書信任,則生成一串隨機數字作為通訊過程中對稱加密的秘鑰。然後取出證書中的公鑰,將這串數字以及HASH的結果進行加密,然後發給服務端

  4. 服務端接收客戶端發來的數據之後,通過私鑰進行解密,然後HASH校驗,如果一致,則使用客戶端發來的數字串加密一段握手消息發給客戶端

  5. 客戶端解密,並HASH校驗,沒有問題,則握手結束。接下來的傳輸過程將由之前客戶端生成的隨機密碼並利用對稱加密演算法進行加密通信

 

4.1 實現庫

TLS協議的設計目標是構建一個安全傳輸層(Transport Layer Security ),在基於連接的傳輸層(如tcp)之上提供。

 

TLS是用來做加密數據傳輸的,因此它的主體當然是一個對稱加密傳輸組件。為了給這個組件生成雙方共用的密鑰,因此就需要先搞一個認證密鑰協商組件,TLS協議自然分為:

  1. 做對稱加密傳輸的record協議 ,the record protocol

  2. 做認證密鑰協商的handshake協議,the handshake protocol

還有3個很簡單的輔助協議:

  1. changecipher spec 協議,the changecipher spec protocol, 用來通知對端從handshake切換到record協議(有點冗餘,在TLS1.3裡面已經被刪掉了)

  2. alert協議,the alert protocol, 用來通知各種返回碼,

  3. application data協議, The application data protocol,就是把http,smtp等的數據流傳入record層做處理並傳輸。

(網圖)

 

如上看到,要實現TLS協議是很複雜的,目前他的實現也已經有很多了,當然最著名的當屬 openssl 。在wikipedia里已經列的很詳細了。gRPC里由於是基於netty的,netty里的TLS實現庫主要是BoringSSL、OpenSSL

大家可以參考

https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations

 

5. CA(證書)

它的作用就是提供證書(即伺服器證書,由功能變數名稱、公司信息、序列號和簽名信息組成)加強服務端和客戶端之間信息交互的安全性,以及證書運維相關服務。任何個體/組織都可以扮演 CA 的角色,只不過難以得到客戶端的信任,能夠受瀏覽器預設信任的 CA 大廠商有很多,其中 TOP5 是 Symantec、Comodo、Godaddy、GolbalSign 和 Digicert。

 

證書也挺貴的,對於個人來說,還是算了。就是我們偉大的12306用的也是自建證書。

5.1 證書標準

X.509 - 這是一種證書標準,主要定義了證書中應該包含哪些內容.其詳情可以參考RFC5280,SSL使用的就是這種證書標準.

5.2 編碼格式

同樣的X.509證書,可能有不同的編碼格式

  • PEM - Privacy Enhanced Mail,打開看文本格式,以"-----BEGIN..."開頭, "-----END..."結尾,內容是BASE64編碼.
    查看PEM格式證書的信息:openssl x509 -in certificate.pem -text -noout
    Apache和*NIX伺服器偏向於使用這種編碼格式.

  • DER - Distinguished Encoding Rules,打開看是二進位格式,不可讀.
    查看DER格式證書的信息:openssl x509 -in certificate.der -inform der -text -noout
    Java和Windows伺服器偏向於使用這種編碼格式.

5.3 相關的文件擴展名

雖然我們已經知道有PEM和DER這兩種編碼格式,但文件擴展名並不一定就叫"PEM"或者"DER",常見的擴展名除了PEM和DER還有以下這些,它們除了編碼格式可能不同之外,內容也有差別,但大多數都能相互轉換編碼格式.

  • CRT - CRT應該是certificate的三個字母,其實還是證書的意思,常見於*NIX系統,有可能是PEM編碼,也有可能是DER編碼,大多數應該是PEM編碼,相信你已經知道怎麼辨別.

  • CER - 還是certificate,還是證書,常見於Windows系統,同樣的,可能是PEM編碼,也可能是DER編碼,大多數應該是DER編碼.

  • KEY - 通常用來存放一個公鑰或者私鑰,並非X.509證書,編碼同樣的,可能是PEM,也可能是DER.
    查看KEY的辦法:openssl rsa -in mykey.key -text -noout
    如果是DER格式的話,同理應該這樣了:openssl rsa -in mykey.key -text -noout -inform der

  • CSR - Certificate Signing Request,即證書簽名請求,這個並不是證書,而是向權威證書頒發機構獲得簽名證書的申請,其核心內容是一個公鑰(當然還附帶了一些別的信息),在生成這個申請的時候,同時也會生成一個私鑰,私鑰要自己保管好。
    查看的辦法:openssl req -noout -text -in my.csr

  • PFX/P12 - predecessor of PKCS#12,對*nix伺服器來說,一般CRT和KEY是分開存放在不同文件中的,但Windows的IIS則將它們存在一個PFX文件中,(因此這個文件包含了證書及私鑰),PFX通常會有一個"提取密碼",你想把裡面的東西讀取出來的話,它就要求你提供提取密碼,PFX使用的時DER編碼,如何把PFX轉換為PEM編碼?
    openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
    這個時候會提示你輸入提取代碼. for-iis.pem就是可讀的文本.
    生成pfx的命令類似這樣:openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt其中CACert.crt是CA(權威證書頒發機構)的根證書,有的話也通過-certfile參數一起帶進去.這麼看來,PFX其實是個證書密鑰庫.

  • JKS - 即Java Key Storage,這是Java的專利,跟OpenSSL關係不大,利用Java的一個叫"keytool"的工具,可以將PFX轉為JKS

5.4 證書編碼的轉換

  • PEM轉為DER openssl x509 -in cert.crt -outform der -out cert.der

  • DER轉為PEM openssl x509 -in cert.crt -inform der -outform pem -out cert.pem

 

6. 自建證書

OpenSSL 是一個免費開源的庫,它提供了構建數字證書的命令行工具。一般都是三級證書,為了簡單我就只做2級了,大家可以自己簽發三級。

6.1 創建 Root CA

a) 生成根證書私鑰

$ openssl genrsa -aes256 -out cakey.pem 2048 (生成私鑰)

$ openssl pkcs8 -topk8 -in cakey.pem -out ca.key -nocrypt (grpc格式

 

b)生成根證書簽發申請文件

$openssl req -new -key ca.key -out ca.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=wwc" (/CN代表的就是功能變數名稱)

 

c)自簽髮根證書(cer文件)

$ openssl x509 -req -days 365 -sha1 -extensions v3_ca -signkey ca.key -in ca.csr -out ca.cer

 

6.2 簽發自建證書

a) 生成證書私鑰

$ openssl genrsa -aes256 -out server.pem 2048 (生成私鑰)

$ openssl pkcs8 -topk8 -in server.pem -out server.key -nocrypt

 

b)生成證書簽發申請文件

$openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=myprovince/L=mycity/O=myorganization/OU=mygroup/CN=wancai"

 

c)使用根證書簽發服務端證書

$ openssl x509 -req -days 365 -sha1 -extensions v3_req -CA ca.cer -CAkey ca.key -CAserial ca.srl -CAcreateserial -in server.csr -out server.cer

 

7. gRPC使用自建證書

將server.cer(證書)和server.key(私鑰)拷貝到工作目錄

 

gRPC的通信組件是netty、okhttp,netty帶了ssl實現,有動態和靜態兩種方式來提供TLS的實現庫,為了開發方便,我這裡使用了boringssl實現庫。okhttp也實現了TLS,但okhttp使用在移動端,故在此不表。

<dependency>

    <groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>${grpc.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>1.1.33.Fork23</version>
</dependency>

 

gRPC Server端

使用TLS,添加證書和私鑰

/* The port on which the server should run */
int port = 8443;
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.useTransportSecurity(loadCert("server.cer"),loadCert("server.key"))
.build()
.start();
logger.info("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
 public void run() {
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
   System.err.println("*** shutting down gRPC server since JVM is shutting down");
HelloWorldServer.this.stop();
System.err.println("*** server shut down");
}
});

 

 

gRPC Client端

添加信任的證書,同時註意剛纔我們建立證書的時候,功能變數名稱是wancai,所以在這裡需要添加功能變數名稱,否則鏈接失敗。

SslContext sslContext = null;
try {
sslContext = GrpcSslContexts.forClient().trustManager(
loadCert("server.cer")).build();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
InetAddress address;
try {
address = InetAddress.getByName(host);
address = InetAddress.getByAddress("wancai", address.getAddress());
} catch (UnknownHostException ex) {
throw new RuntimeException(ex);
}
channel = NettyChannelBuilder.forAddress(new InetSocketAddress(address, port))
.flowControlWindow(65 * 1024)
.negotiationType(NegotiationType.TLS)
.sslContext(sslContext)
.build();
blockingStub = GreeterGrpc.newBlockingStub(channel);

 

最後,我們通過 wireshark,抓包看看使用TLS加密和不加密通信的信息。

當沒有加密時,通信如下

 

參考資料

  1. https://blog.helong.info/blog/2015/09/07/tls-protocol-analysis-and-crypto-protocol-design/

  2. http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html

  3. http://www.barretlee.com/blog/2016/04/24/detail-about-ca-and-certs/

  4. http://www.cnblogs.com/guogangj/p/4118605.html

  5. https://my.oschina.net/itblog/blog/651434

  6. http://blog.csdn.net/clementad/article/details/50620067

  7. https://imququ.com/post/protocol-negotiation-in-http2.html

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介:學習完了php和jQuery之後,對函數的記憶不到位,導致很多函數沒記住,所以為了促進自己的記憶,每天花一點時間來寫這個博客。 時間:2016-12-18 地點:太原 天氣:晴 一.php函數(數組相關的函數) 1.array_change_key_case 作用:返回字元串鍵名為全大寫或者全 ...
  • 1.class是struct的擴展,它包括數據成員和成員函數。 2.在C++中,有三種訪問許可權: (1)private:預設,只供類內部的函數使用。 (2)public:類外的程式可以使用。 (3)proteted 註意: C++的規範,類名稱的首字母應該大寫。 eg: 出現錯誤: 3.通過函數來訪 ...
  • 上一篇文章網站實現微信登錄之嵌入二維碼中描述瞭如何在自己的登錄頁面內嵌入登錄二維碼,今天的這篇文章主要是描述下在掃碼成功之後微信重定向回網站後登錄邏輯的處理,其實也就是驗證身份信息,授權用戶登錄的邏輯。這裡說句題外話,寫博客複習已經做過的項目真的有助於自己對已經寫過代碼和業務邏輯的理解,說不定還有意 ...
  • 1.node-formidable 對文件上傳提供幫助的組件 2.app.js ...
  • <filter>: 過濾器,執行一個過濾器會有返回個枚舉值,即DENY,NEUTRAL,ACCEPT其中之一。返回DENY,日誌將立即被拋棄不再經過其他過濾器;返回NEUTRAL,有序列表裡的下個過濾器過接著處理日誌;返回ACCEPT,日誌會被立即處理,不再經過剩餘過濾器。 過濾器被添加到<Appe ...
  • 1.假設我們要輸出張三,李四兩個人的基本信息,包括姓名,年齡,可以用以下的C程式實現: eg: 2.假設要輸出很多人的信息,那麼用上面這樣的程式思路實現起來很不方便,可以用數組來實現: eg: 3.假設基本信息的屬性有很多個,還有工作,婚姻狀況等等的屬性,按上面的程式思想,我們就得增加很多用於保存屬 ...
  • 微盤系統,微盤搭建,微盤源碼,微交易系統搭建,微交易源碼,微交易系統, 本公司微交易系統,是基於微信端開發的交易平臺。平臺適用於貴金屬、外匯、原油、期貨…等多個交易品種的投資者,並對接多個移動支付介面,輕鬆解決出入金問題。程式說明:2017新版微交易系統建設,採用新浪數據介面,非常穩定,直接運營版本 ...
  • 閱讀目錄 架構的定義 如何開始設計一個架構 一個好架構的特點 做架構中的誤區 結語 一、架構的定義 所謂一千個架構師中有一千種“最好的架構”模式。 “架構”是我們這行業種一個很常見的詞,表明其必然也是經歷了很長的歲月打磨所形成的一個詞。架構的這個詞出現的意義是什麼?為瞭解決什麼問題?只有把這2個問題 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...