客戶端與服務端資料加密傳輸方案

2021-09-11 18:03:45 字數 4544 閱讀 6057

總結從前一篇網路安全基礎要點知識介紹中可以知道,在網路通訊中,通訊傳輸資料容易被擷取或篡改,如果在傳輸使用者隱私資料過程中,被不法分子擷取或篡改,就可能導致使用者受到傷害,比如被詐騙,所以對客戶端與服務端的傳輸資料加密,是網路通訊中必不可少的。

首先,客戶端與服務端商量好資料加密協議,對傳輸資料做到安全保護。

安全保護至少需要有下面兩點:

採用https協議

採用公鑰密碼體制rsa演算法對資料加密

現在安全是保證了,但還要考慮到效能問題,由於rsa演算法對資料加密時運算速度慢,所以直接把所有傳輸資料都用rsa加密,會導致網路通訊慢,這對使用者將是不好的體驗。由於對稱金鑰密碼體制中的aes運算速度快且安全性高,所以結合aes對傳輸資料加密是非常好的方案。

下面是對客戶端與服務端通訊資料加密比較通用的方案:

客戶端生成aes金鑰,並儲存aes金鑰

客戶端用aes金鑰對請求傳輸資料進行加密

客戶端使用rsa公鑰對aes金鑰加密,然後把值放到自定義的乙個請求頭中

客戶端向服務端發起請求

服務端拿到自定義的請求頭值,然後使用rsa私鑰解密,拿到aes金鑰

服務端使用aes金鑰對請求資料解密

服務端對響應資料使用aes金鑰加密

服務端向客戶端發出響應

客戶端拿到服務端加密資料,並使用之前儲存的aes金鑰解密

注意:傳輸資料使用aes金鑰加密,rsa公鑰對aes金鑰加密。rsa公鑰和私鑰由服務端生成,公鑰放在客戶端,私鑰放在服務端。公鑰私鑰要私密保護,不能隨便給人。

上面網路通訊過程是安全的,可以保證通訊資料即使被擷取了,也無法獲得任何有效資訊;即使被篡改了,也無法被客戶端和服務端驗證通過。

生成aes金鑰和使用aes金鑰加密、解密,有下面重要的幾點:

1.金鑰長度的選擇:aes能支援的金鑰長度可以為128,192,256位(也即16,24,32個位元組),這裡選擇128位。

2.演算法/模式/填充的選擇:

演算法/模式/填充

位元組加密後資料長度

不滿16位元組加密後長度

aes/cbc/nopadding

16 不支援

aes/cbc/pkcs5padding

3216

aes/cbc/iso10126paddind

3216

aes/cfb/nopadding

16原始資料長度

aes/cfb/pkcs5padding

3216

aes/cfb/iso10126padding

3216

aes/ecb/nopadding

16不支援

aes/ecb/pkcs5padding

3216

aes/ecb/iso10126padding

3216

aes/ecb/iso10126padding

3216

aes/ofb/nopadding

16原始資料長度

aes/ofb/pkcs5padding

3216

aes/ofb/iso10126padding

3216

aes/pcbc/nopadding

16不支援

aes/pcbc/pkcs5padding

3216

aes/pcbc/iso10126padding

3216

這裡選擇aes/cbc/pkcs5padding。

3.新增向量 ivparameterspec:增強演算法強度。

4.編碼格式選擇:utf-8。

下面為具體**實現:

private final int aes_key_length = 16;//金鑰長度16位元組,128位

private final string aes_algorithm = "aes";//演算法名字

private final string aes_transformation = "aes/cbc/pkcs5padding";//演算法/模式/填充

private final string aes_iv = "0112030445060709";//使用cbc模式,需要乙個向量iv,可增加加密演算法的強度

private final string aes_string = "abcdefghijklmnopqrstuvwxyzabcdefghigklop";

private final charset utf_8 = charset.forname("utf-8");//編碼格式

/*** 使用aes加密

** @param aeskey aes key

* @param data 被加密的資料

* @return aes加密後的資料

*/private byte encodeaes(byte aeskey, string data)

secretkeyspec keyspec = new secretkeyspec(aeskey, aes_algorithm);

try catch (exception e)

return null;

}/**

* 使用aes解密

** @param aeskey aes key

* @param data 被解密的資料

* @return aes解密後的資料

*/private string decodeaes(byte aeskey, byte data)

secretkeyspec keyspec = new secretkeyspec(aeskey, aes_algorithm);

try catch (exception e)

return null;

}private int getrandom(int count)

/*** 生成aes key

** @return aes key

*/private string initaeskey()

return sb.tostring();

}

現在aes金鑰和aes加密、解密都有了,在通常情況下,還會對加密、解密過程進行base64 編碼、解碼。

base64編碼,選擇 url_safe 標識,也就是 「-」 和 「_」 會被替換為 「+」 和 「/」,:

/**

* 對資料進行base64編碼,使用的是,而且flags需要使用 。

** @param input **資料

* @return base64編碼的資料

*/private string encodebase64(byte input)

base64解碼,和編碼對應:

/**

* 對資料進行base64解碼,使用的是,而且flags需要使用 ,主要是為了和base64加密對應。

** @param str 需要解碼的資料

* @return base64解碼後的資料

*/private byte decodebase64(string str)

rsa公鑰是從服務端拿到的,這個公鑰不能被洩漏,必須做到安全保護。

使用rsa公鑰加密,也有幾個重要點:

1.拿到的公鑰是base64 編碼後的,所以首先需要對公鑰base64解碼。

2.演算法/模式/填充的選擇:rsa/ecb/pkcs1padding

3.編碼格式選擇:utf-8。

注意:使用rsa公鑰加密的流程對應的就是服務端使用rsa私鑰解密的流程,所以需要和服務端溝通商量好。

具體**實現:

private final string rsa_pub_key = "服務端給的公鑰";

private final string rsa_transformation = "rsa/ecb/pkcs1padding";

/*** 公鑰加密

** @param data 要加密的資料

* @param key 公鑰

* @param transformation 演算法/模式/填充

* @return 加密後的資料

*/public byte encryptbypublickey(byte data, string key, string transformation)

throws generalsecurityexception

1.為了保證網路通訊中的通訊資料安全,首先採用https協議和公鑰金鑰體制中的rsa加密。

2.因為是rsa運算速度慢,所以採用運算速度快且安全性高的對稱金鑰密碼體制中的aes對所

有傳輸資料進行加密,然後再用rsa對aes金鑰加密,這樣既能保證安全又能保證效能。

3.rsa公鑰和私鑰由服務端生成,公鑰放在客戶端,私鑰放在服務端。

4.資料加密後採用base64編碼,資料解密前採用base64解碼。

5.編碼格式同一採用utf-8。

服務端向客戶端傳輸檔案

23.1 閱讀須知 所以如果不符合你的需求就不用往下了。這是用socket傳輸檔案的服務端 include sockaddr in include socket include socket include printf include exit include bzero define serve...

TCP 服務端 客戶端 傳輸資料結構

編寫4個檔案 server.c client.c sum.h makefile 主要是客戶端 與服務端在傳輸資料的時候,不是直接傳遞字串,而是傳遞自定義的資料結構 注意 tcp傳送的資訊是以位元組為單位保證順序的.當兩台機器都同時小端機或大端機時,傳輸是正常的。否則,可能會出現異常情況。server...

C 服務端與客戶端

c 服務端與客戶端連線實現的由來 那麼既然乙個伺服器端口可以應對多個客戶端連線,那麼接下來我們就看一下,如何讓多個客戶端與服務端連線。如同我們上面所說的,乙個tcpclient就是乙個socket,所以我們只要建立多個tcpclient,然後再呼叫connect 方法就可以了 c 服務端與客戶端連線...