iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 5
0
Security

安全地寫 Java 的「基本功」系列 第 5

安全地寫 Java 的 「基本功」- Day 4

加解密簡論

我們在週末專案中,使用了所謂的 AES 加密機制,來加密一個簡單的檔案。然而因為時間有限,我們只能解釋到一個段落,必須把後半段留待下回說明。但是,如同前文所述,使用加解密機制,最大的問題便是金鑰管理。我們有必要在這一天,將加解密的基本概念與特性做個介紹。

同一把鑰匙

傳統加解密機制最大的特性,就是加密與解密必須使用同一把鑰匙。其實我們生活中所應用的,也大多是這樣的機制,例如你用 7zip 加密壓縮了一個檔案給同事,用公司電話當密碼,當然對方也要用公司電話來解開。

然而,這樣看似平常的一個動作,其實也有不少細節裡的魔鬼。

不同的結果

還記得我在初學加解密時,有一次寫了一個測試,要測試兩筆用同一個密碼加密出來的密文是相同的。結果竟然失敗了。我一直納悶著,為什麼密碼相同,又可以解密回原本相同的內容,但密文卻不相同。

但後來腦補了些課程,才知道原來這是加密機制一個很重要的特性。為了不會輕易地被破解,因此必須讓同樣的原始資料、同樣的金鑰能夠產生不同的結果。而要達到這一點,必須加入一個叫做初始向量(Initial Vector, iv)的參數。這個 iv 的參數可以大喇喇地放在密文裡,但是加了它,密文就會不一樣。

跟這個概念很像的,有另一個機制,稱為「加鹽」,就是在討厭的同事的咖啡裡加一大匙鹽給他喝。

不是的,「加鹽」的概念,就例如你把密碼用 SHA256 Hash 儲存在資料庫裡時,必須加上一些處理,好讓原本的密碼轉成 SHA256 時,不會是那個固定的值。

加密的強度

Java 的安全機制並不好,雖然是我的主觀想法,但是若稍有點涉獵在 Java 相關密碼學工具裡時,多少會有這種感覺。Java 在發行給全世界數十億主機執行時,在它裡頭,只提供到 AES 128 bit 的支援。在這類加密演算法裡,著名的有 DES、3DES、AES、Blowfish 等,而現在業界多半使用的,卻是 AES 256 bit 的強度。

換句話說,你若把我的 sample code 拿回去在你的電腦上執行,我敢保證一定會失敗。因為原本的 JDK 礙於美國加密演算法出口限制的關係,沒有提供更高的加解密強度支援。因此,你必須去這個頁面下載更新的 JAR 檔與授權才能使用更好的 AES 256 bit 加解密,目前這提供到 Java 8,使用 JDK 1.7 的人,只好冒險試試看了。

加密的實作

一般而言,我們只知道 AES、DES 等等這種名詞,就像社會大眾只知道 iPhone 6S、iPhone 7,但是玩家們,就會知道 iPhone 6S 的 CPU 是台積電還是三星做的。真正在實作加解密時,才會發現還有不同的實作機制。

當我們在 JCE 演算法清單 上找 AES 相關實作,會發現有這幾種:
* AES/CBC/NoPadding
* AES/CBC/PKCS5Padding
* AES/ECB/NoPadding
* AES/ECB/PKCS5Padding

Padding 的意思,類似打包裝箱時,你要塞一些填充的紙張或者泡綿,同樣的,padding 的處理,也就是將你要加密的內容進行處理過後,再進行加密。這樣會增加攻擊者暴力破解的難度。而 CBC 與 ECB,可以參考 維基百科 的說明。

然而,我們若研究其他相關的密碼學元件,會發現有其他選項,例如用 Bouncy Castle 可發現還有其他的實作選項。

小結

本日的內容,因為時間不足的緣故,無法補上程式的實作。程式部份,一樣實作在 GitHub 的 AdvancedAES 分支中。我會把握時間將實作部份完成。若明日有足夠篇幅與時間,會再解釋程式的設計原理。

明日,我們會討論,用不同的鑰匙來加解密的機制。


上一篇
安全地寫 Java 的 「基本功」- Day 3
下一篇
安全地寫 Java 的 「基本功」- Day 5
系列文
安全地寫 Java 的「基本功」14

尚未有邦友留言

立即登入留言