數據加密算法詳解

作者簡介? 原創微信公眾號郭霖 WeChat ID: guolin_blog

大家早上好,轉眼假期就結束了,又到了跟你們見面的時候啦!

本篇是Chay_Chan第二篇 投稿,分享了如何在Android、Java以及Web端使用 RSA 與 AES 加密,希望對大家有所幫助。

Chay_Chan的博客地址:

http://blog.csdn.net/Chay_Chan

正文

數據傳輸加密

在開發應用過程中,客戶端與服務端經常需要進行數據傳輸,涉及到重要隱私信息時,開發者自然會想到對其進行加密,即使傳輸過程中被“有心人”截取,也不會將信息泄露。對于加密算法,相信不少開發者也有所耳聞,比如 MD5加密,Base64加密,DES加密,AES加密,RSA加密等等。在這里我主要向大家介紹一下我在開發過程中使用到的加密算法,RSA加密算法+AES加密算法。簡單地介紹一下這兩種算法吧。

RSA

之所以叫 RSA算法,是因為算法的三位發明者RSA是目前最有影響力的公鑰加密算法,它能夠抵抗到目前為止已知的絕大多數密碼攻擊,已被ISO推薦為公鑰數據加密標準,主要的算法原理就不多加介紹,如果對此感興趣的話,建議去百度一下RSA算法。需要了解的是RSA算法屬于非對稱加密算法,非對稱加密算法需要兩個密鑰:公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數據進行加密,那么只有用對應的公開密鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。簡單的說是“公鑰加密,私鑰解密;私鑰加密,公鑰解密”。

AES

高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高級加密標準由美國國家標準與技術研究院(NIST)于2001年11月26日發布于FIPS PUB 197,并在2002年5月26日成為有效的標準。2006年,高級加密標準已然成為對稱密鑰加密中最流行的算法之一。

為什么要結合使用這兩種算法

如果不清楚非對稱算法和對稱算法,也許你會問,為什么要結合使用這兩種算法,單純使用一種算法不行嗎?這就要結合不同的場景和需求了。

客戶端傳輸重要信息給服務端,服務端返回的信息不需加密的情況

客戶端傳輸重要信息給服務端,服務端返回的信息不需加密,例如綁定銀行卡的時候,需要傳遞用戶的銀行卡號,手機號等重要信息,客戶端這邊就需要對這些重要信息進行加密,使用RSA公鑰加密,服務端使用RSA解密,然后返回一些普通信息,比如狀態碼code,提示信息msg,提示操作是成功還是失敗。這種場景下,僅僅使用RSA加密是可以的。

客戶端傳輸重要信息給服務端,服務端返回的信息需加密的情況

客戶端傳輸重要信息給服務端,服務端返回的信息需加密,例如客戶端登錄的時候,傳遞用戶名和密碼等資料,需要進行加密,服務端驗證登錄信息后,返回令牌token需要進行加密,客戶端解密后保存。此時就需要結合這兩種算法了。至于整個流程是怎樣的,在下面會慢慢通過例子向你介紹,因為如果一開始就這么多文字類的操作,可能會讓讀者感到一頭霧水。

使用RSA加密和解密

產生公鑰和私鑰

產生RSA公鑰和密鑰的方法有很多,在這里我直接使用我封裝好的方法產生,都最后我會將兩個算法的工具類贈送給大家。

公鑰:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCRQZ5O/AOAjeYAaSFf6Rjhqovws78I716I9oGF7WxCIPmcaUa1YuyLOncCCuPsaw69+RMWjdbOBp8hd4PPM/d4mKTOVEYUE0SfxhhDTZaM5CzQEUXUyXy7icQTGR5wBjrbjU1yHCKOf5PJJZZQWB06husSFZ40TdL7FdlBpZ1u1QIDAQAB

私鑰:

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJFBnk78A4CN5gBpIV/pGOGqi/CzvwjvXoj2gYXtbEIg+ZxpRrVi7Is6dwIK4+xrDr35ExaN1s4GnyF3g88z93iYpM5URhQTRJ/GGENNlozkLNARRdTJfLuJxBMZHnAGOtuNTXIcIo5/k8klllBYHTqG6xIVnjRN0vsV2UGlnW7VAgMBAAECgYBMoT9xD8aRNUrXgJ7YyFIWCzEUZN8tSYqn2tPt4ZkxMdA9UdS5sFx1/vv1meUwPjJiylnlliJyQlAFCdYBo7qzmib8+3Q8EU3MDP9bNlpxxC1go57/q/TbaymWyOk3pK2VXaX+8vQmllgRZMQRi2JFBHVoep1f1x7lSsf2TpipgQJBANJlO+UDmync9X/1YdrVaDOi4o7g3w9u1eVq9B01+WklAP3bvxIoBRI97HlDPKHx+CZXeODx1xj0xPOK3HUz5FECQQCwvdagPPtWHhHx0boPF/s4ZrTUIH04afuePUuwKTQQRijnl0eb2idBe0z2VAH1utPps/p4SpuT3HI3PJJ8MlVFAkAFypuXdj3zLQ3k89A5wd4Ybcdmv3HkbtyccBFALJgs+MPKOR5NVaSuF95GiD9HBe4awBWnu4B8Q2CYg54F6+PBAkBKNgvukGyARnQGc6eKOumTTxzSjSnHDElIsjgbqdFgm/UE+TJqMHmXNyyjqbaA9YeRc67R35HfzgpvQxHG8GN5AkEAxSKOlfACUCQ/CZJovETMmaUDas463hbrUznp71uRMk8RP7DY/lBnGGMeUeeZLIVK5X2Ngcp9nJQSKWCGtpnfLQ==

很明顯,公鑰字符串長度比較短,私鑰的比較長。生成完密鑰后,公鑰可以存放在客戶端,即使被別人知道公鑰,也是沒有問題的;私鑰則一定要保存在服務端。如果到時公司面臨人事變動,避免私鑰被離職人員泄露,可以重新生成公鑰和密鑰。

使用公鑰加密,私鑰解密

這里在客戶端模擬加密的情況,對字符串”Beyond黃家駒”使用RSA加密,調用 RSAUtils 的 encryptByPublicKey()方法,輸出結果為:

密文:BRFjf3tUqRqlwuP5JtzxZinf7lp+AHuHM9JSabM5BNFDxuUe9+uuO6RpCHVH5PibifqQHzGNsyZn1G9QcIENT9Tbm+PZwAbNUlMPZRDBU1FSnOtY8dBdeW/lJdnY9sJVwNvIBnOLQk66hxRh6R2149dwlgdsGUpWMOMBzcP3vsU=

在服務端,可以使用 RSAUtils 的 decryptByPrivateKey() 方法進行解密,現在模擬服務端解密:

在這里雖然沒有完全模擬數據傳輸過程,比如說客戶端發起一個網絡請求,傳遞參數給服務端,服務端接收參數并進行處理,也是為了讓大家可以更加容易明白,所以這里只是進行簡單的模擬。可以看到Android客戶端端和Java服務端的RSA加密解密算法是可以互通的,原因是他們所使用到的base64加密類是一致的,所以才可以實現加密和解密的算法互通。

使用到的jar包都是javabase64-1.3.1.jar,相信不少人都知道,java中有自帶的Base64算法類,但是安卓中卻沒有,之前出現的情況是,使用的Base64類不統一,比如在安卓客戶端開發使用的Base64算法是使用第三方提供的jar包,而java服務端中使用的是JDK自帶的Base64,導致從客戶端傳過來的密文,服務端解析出錯。

上面的例子展示了客戶端使用公鑰加密,服務端使用私鑰解密的過程。也許你會這么想,既然可以如此,那服務端那邊信息也可以通過RSA加密后,傳遞加密信息過來,客戶端進行解密。但是,這樣做,顯示是不安全的。原因是,由于客戶端并沒有保存私鑰,只有公鑰,只可以服務端進行私鑰加密,客戶端進行公鑰解密,但由于公鑰是公開,別人也可以獲取到公鑰,如果信息被他們截取,他們同樣可以通過公鑰進行解密,那么這樣子加密,就毫無意義了,所以這個時候,就要結合對稱算法,實現客戶端與服務端之前的安全通信了。

使用AES加密解密

加密

模擬客戶端進行AES加密,我們通過調用 AESUtils 中的 generateKey() 方法,隨機產生一個密鑰,用于對數據進行加密。輸出的結果為:

密鑰:6446c69c0f914a57密文:GECDQOsc22yV48hdJENTMg==

解密

模擬服務端進行AES解密,由于AES屬于對稱算法,加密和解密需要使用同一把密鑰,所以,服務端要解密傳遞過來的內容,就需要密鑰 + 密文。這里模擬一下服務端解密。

到這里也許你會問,客戶端使用AES進行加密,服務端要進行解密的話,需要用到產生的密鑰,那密鑰必須從客戶端傳輸到服務端,如果不對密鑰進行加密,那加密就沒有意義了。所以這里終于談到了重點,RSA算法+AES算法結合使用。

RSA算法+AES算法的使用

舉一個簡單的例子來說明一下吧,例如實名認證功能,需要傳遞用戶真實姓名和身份證號,對于這種重要信息,需要進行加密處理。

客戶端使用RSA + AES對重要信息進行加密

客戶端加密過程主要分為以下三個步驟:

1.客戶端隨機產生AES的密鑰;

2.對身份證信息(重要信息)進行AES加密;

3.通過使用RSA對AES密鑰進行公鑰加密。

這樣在傳輸的過程中,即時加密后的AES密鑰被別人截取,對其也無濟于事,因為他并不知道RSA的私鑰,無法解密得到原本的AES密鑰,就無法解密用AES加密后的重要信息。

服務端使用RSA + AES對重要信息進行解密

服務端解密過程主要分為以下兩個步驟:

1.對加密后的AES密鑰進行RSA私鑰解密,拿到密鑰原文;

2.對加密后的重要信息進行AES解密,拿到原始內容。

現實開發中,服務端有時也需要向客戶端傳遞重要信息,比如登錄的時候,返回 token 給客戶端,作為令牌,這個令牌就需要進行加密,原理也是差不多的,比上面多一個步驟而已,就是將解密后的AES密鑰,對將要傳遞給客戶端的數據 token 進行AES加密,返回給客戶端,由于客戶端和服務端都已經拿到同一把AES鑰匙,所以客戶端可以解密服務端返回的加密后的數據。如果客戶端想要將令牌進行保存,則需要使用自己定義的默認的AES密鑰進行加密后保存,需要使用的時候傳入默認密鑰和密文,解密后得到 原token。

上面提及到客戶端加密,服務端返回數據不加密的情況,上面說到僅僅使用RSA是可以,但是還是建議同時使用這兩種算法,即產生一個AES密鑰,使用RSA對該密鑰進行公鑰加密,對重要信息進行AES加密,服務端通過RSA私鑰解密拿到AES密鑰,再對加密后的重要信息進行解密。如果僅僅使用RSA,服務端只通過RSA解密,這樣會對于性能會有所影響,原因是RSA的解密速度約等于AES解密數據的100倍,所以如果每個重要信息都只通過RSA加密和解密,則會影響服務端系統的性能,所以建議兩種算法一起使用。

同時還有相應的JS版RSA和AES算法,使用方式也差不多,在這里簡單演示一下:

下面是一個html頁面的代碼,引入了 rsa.js 和 aes.js:

打開頁面后,查看控制臺輸出:

同時,模擬服務端解密,運行結果如下:

需要注意的是:

1. RSAUtils中配置公鑰和密鑰,可以使用getKeys()方法產生。如果是客戶端,則無須配置私鑰,把沒有私鑰的RSAUtils放到客戶端,因為僅需要用到公鑰加密的方法。

2. AESUtils中配置偏移量IV_STRING;

3. rsa.js中最底部配置公鑰,須和上面RSAUtils配置的公鑰一致;

4. aes.js中的底部var iv = CryptoJS.enc.Utf8.parse(“16-Bytes–String”); //加密向量中,替換里面的字符串,加密向量須和上面的AESUtils中的偏移量一致。

在這里將我自己封裝的RSAUtils、AESUtils以及使用第三方jar包的Base64Utils還有JS版的RSAHE AES分享給大家,希望可以幫助到大家。

http://download.csdn.net/detail/chay_chan/9766486

為了完成這篇博客,花費了接近半天的時間,相當于總結自己在數據傳輸這一方面的經驗,希望可以幫助到更多的開發者,一起交流學習,互相提升和進步。


文章原創作者GuoLin 書籍推薦

郭林大神原創android 書籍:《第一行代碼 android》

淘寶鏈接:

https://s.click.taobao.com/t?e=m%3D2%26s%3DgKUfuKdAZKocQipKwQzePOeEDrYVVa64K7Vc7tFgwiHjf2vlNIV67p2n%2BQBNMyE6Rku8%2Bpj6eJall3bs%2B3NRhNHnsKI%2BqxhyM0iVZhTFBom4YIorMPnmg8G0g2OJi%2FzmXHfenomYtn5EW9vzeG8LzfPUwktUBEmkxg5p7bh%2BFbQ%3D&pvid=10_106.6.161.154_3367_1490163222155

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容