密碼學基礎為數學與電腦科學,雖然有分為古典密碼學與現代密碼學兩種,因 web 身分驗證都跟現代密碼學息息相關,所以本主題提到的密碼學都是指現代密碼學。密碼學旨在討論資訊保密、資訊完整性、不可否認性以及資訊安全問題等。而除了身分驗證以外,這些特性也是其他某些技術的基礎,如區塊鏈。
以下會簡單介紹與密碼學相關的術語。
加密(encrypt)與解密(decrypt)是互為相反的操作,加密是將明文(plaintext)轉變成密文(cipher)的過程;解密則是將密文轉變成明文的過程。以時序圖來看如下:
@startuml
Alice -> Encrypter: Plaintext
Encrypter -> Decrypter: Cipher via internet
Decrypter -> Bob: Plaintext
@enduml
以上例來看,密文放上網路上之後,是沒人看得懂的。只有擁有解密器的 Bob 才能將此密文解回明文。
上述的加密解密流程是非常理想的。舉個例子,只要演算法流出的話(如電腦被偷),那任何人都能當攻擊者攻擊兩邊的系統。
這位 Kerckhoffs 在 19 世紀的時候提出一系列的設計加密系統的原則,而關鍵在於他提到了:即使演算法完全洩漏,只要金鑰沒有洩漏,密文就仍然是安全的,如 JWT 在 header 上就有明白跟大家說它是用什麼樣的演算法。當然這並不是說要叫大家公開演算法,而是說要確保公開了也不會有安全上的問題。
密碼學裡的雜湊(hash),具備以下理想的特性:
這些特性讓雜湊在身分驗證上有非常多種應用,最常聽到的就是作為保存密碼的方法,這樣即便雜湊外流了,理想上是無法從雜湊回推密碼。
Message authentication code,簡稱 MAC。它可以用特定演算法,從原本的資料來產生一小段資訊,只要原本的資料被偷改的話,產生的資訊就會不同,因此可以驗證資料完整性,從 Wiki 的範例圖可以非常清楚了解它的運作流程。
來源:Wiki
圖裡有兩個角色為 Sender 與 Receiver,整個流程要完整走完的條件是,兩個角色需要有共同的 Key(K)
。若 Key 只有你知我知的話,那就能使用 MAC 來確保訊息是由你傳給我,或是我傳給你的,因為那一小段的資訊只能靠擁有 Key 的人產生。這稱之為「可驗證性(authentication)」
簽合約通常能證明這份合約我已經讀過且認可了。而在上法院時,當時不在現場的法官看到有簽名,就會認為我已經看過合約。
數位簽章(digital signature)也是類似的概念,擁有私鑰(private key)可以對一個資料做簽章,擁有公鑰(public key)則能驗證簽章。若成功驗證簽章,代表此資料是完整的,且同時也能確認此資料是由擁有私鑰的人產生的。簽章的流程大致如下:
@startuml
Alice -> Signer: Private key + hash(data) = sign
Signer -> Bob: data & sign via Internet
Bob -> Verifier: hash(data) & sign
note right
Using Alice public key to verify
end note
@enduml
因為只有私鑰能簽章,而在使用上,私鑰通常都是保護的好好的,而公鑰通常是公開散布出去的,因此只要在路邊撿到一組 data + sign,然後隨便拿了 Alice 的公鑰一驗,居然通過了!那在理想上,我們可以確認這個 data 是 Alice 產生的。這稱之為「不可否認性(non-repudiation)」。
正如其名,亂數的目的是要產生隨機數,因此基本條件是要夠亂沒有規律,但在極大量樣本數的前提下,所有數字都要分布平均,也就是指「隨機性」。
有的亂數產生器是有辦法預測的,比方說以時間為亂數種子(seed)的亂數,產出來的亂數就是會著時間變化,這有可能會讓攻擊者趁虛而入,如在提 Cookie 的安全隱患時,有提到隨機產生 Session Prediction,這就是一種可能的攻擊手法。因此對做身分驗證來說,亂數是需要「不可預測性」的。
另外亂數產生時,有時候會產生出重複的數列,而有的演算法則不會,這個則是「不可重複性」。
而對身分驗證來說,「不可預測性」或「不可重複性」才是相較安全且必要的特性。
密碼學並不是筆者的專長,但今天還是把看到與知道的東西整理成一篇文章了,跪求高手指教!