將公開金鑰加密用於驗證
驗證是確認識別身分的程序,讓一個實體可以確定另一個實體的識別身分。在下列範例中,A 使用者和 B 使用者會使用公開金鑰加密來確認 B 使用者的識別身分。下面的標記表示某個項目已經使用金鑰加密進行加密或解密
{something}key
其中 something 是已加密或解密的項目描述,而 key 是用來加密或解密該項目的金鑰。
在下列範例中,A 使用者想要驗證 B 使用者。B 使用者有一組金鑰,其中包含一個公開金鑰和一個私密金鑰。B 使用者會向 A 使用者揭露公開金鑰 (在本文件的<提供公開金鑰>一節將詳細說明)。
A 使用者會產生隨機訊息,並傳送給 B 使用者,如下所示:
A->B random_message
B 使用者使用私密金鑰來加密隨機訊息,然後將加密的版本傳回給 A 使用者:
B->A {random_message}User_B's_private_key
A 使用者收到這個訊息之後,會使用 B 使用者先前公佈的公開金鑰來解密訊息。A 使用者會將解密的訊息與 A 使用者原先傳給使用者的訊息做比較。如果訊息相符,A 使用者便知道後面的訊息來自於 B 使用者,因為詐欺者不太可能會知道 B 使用者的私密金鑰,所以也無法正確地加密要傳送給 A 使用者的隨機訊息。
因此,在這個範例中,與其加密 A 使用者所傳送的原始訊息,B 使用者改為建構訊息摘要,然後加密該訊息摘要。訊息摘要是衍生自原始的隨機訊息,並且具有下列有用的特性:
•摘要很難還原。他人若嘗試模擬 B 使用者,將無法從摘要判斷原始的訊息。
•模擬者很難找到計算出相同摘要值的不同訊息。
使用摘要可保護 B 使用者。B 使用者會計算 A 使用者所傳送隨機訊息的摘要,然後加密結果。B 使用者將加密的摘要傳回給 A 使用者。A 使用者可以解密 B 使用者的訊息並比較值,藉以計算出相同的摘要並驗證 B 使用者。
建立資料以進行驗證
本文<其他注意事項>一節中所述的技術稱為數位簽章。這項技術需要 B 使用者簽署 A 使用者產生的訊息;這對於 B 使用者而言,就和加密 A 使用者產生的隨機值一樣的危險。因此,這個範例中的驗證通訊協定需要另一個步驟,以確保安全;B 使用者必須建立下列部分 (或全部) 的資料:
A->B B->A hello, are you User B?User A, This Is User B { digest[User A, This Is User B] } User_B's_private_key
當 B 使用者使用此通訊協定時,由於 B 使用者知道傳送給 A 使用者的是何種訊息,因此,B 使用者可以安全地簽署訊息。B 使用者會先傳送未加密版本的訊息「User A, This Is User B」,再傳送處理過的加密版本。A 使用者可以很容易地確認 B 使用者就是 B 使用者,而且 B 使用者不需要簽署並非 B 使用者所建立的任何訊息。
提供公開金鑰
使用者要如何以安全的方式提供公開金鑰?下列範例說明 B 使用者的驗證通訊協定:
A->B B->A A->B B->A
hello Hi, I'm User B, User_B's_public_key prove it User A, This Is
User B { digest[User A, This Is User B] } User_B's_private_key
如果使用此通訊協定,任何人都可以模擬 B 使用者。詐欺者只需要公開金鑰和私密金鑰。詐欺者可以提供詐欺者自己的公開金鑰,而非 B 使用者的公開金鑰,以欺騙 A 使用者並模擬 B 使用者。然後,詐欺者會使用詐欺者的私密金鑰加密某個項目,以「證明」其為 B 使用者,讓 A 使用者無法分辨詐欺者不是 B 使用者。
憑證是使用憑證發行者的私密金鑰來簽署的。每個人都知道憑證發行者的公開金鑰 (也就是說,憑證發行者也有憑證)。憑證是連結公開金鑰和名稱的標準方法。
如果使用憑證技術,每個人都可以檢查 B 使用者的憑證,看看憑證是不是偽造的。如果 B 使用者一直嚴密地控制私密金鑰,並且實際取得憑證,則憑證技術就是安全的。下面是使用這項技術的修改版通訊協定:
A->B B->A A->B B->A hello Hi, I'm User B, User_B's_certificate prove
it User A, This Is User B { digest[User A, This Is User B] } User_B's_private_key
當 A 使用者收到 B 使用者的第一個訊息時,A 使用者可以檢查憑證、檢查簽章 (如同在上一個範例中,利用摘要和公開金鑰解密),然後檢查主體 (也就是 B 使用者的名稱),以確認的確是 B 使用者。然後 A 使用者可以信任公開金鑰是 B 使用者的公開金鑰,而且可以要求 B 使用者的識別身分證明。
B 使用者會執行如上例中所列出的相同程序,設計訊息摘要,然後以摘要的簽署版本來回應 A 使用者。A 使用者可以使用來自憑證的公開金鑰及檢查結果,以確認 B 使用者的訊息摘要。
想要干擾安全通訊的人 (在本範例中為 C 使用者) 可以建立下列案例,以嘗試進行干擾:
A->C C->A A->C C->A hello Hi, I'm User B, User_B's_certificate prove it ????
然而,C 使用者在最後的訊息中無法滿足 A 使用者。由於 C 使用者沒有 B 使用者的私密金鑰,因此,C 使用者無法建構可讓 A 使用者相信來自於 B 使用者的訊息。
交換密碼
在 A 使用者驗證過 B 使用者之後,A 使用者就可以傳送只有 B 使用者可以解碼的訊息給 B 使用者,如下所示:
A->B {secret}User_B's_public_key
其中唯一可以判斷 secret 的方法,就是使用 B 使用者的私密金鑰來解密上述訊息。交換密碼是另一種使用公開金鑰加密的好用方法。即使注意到 A 使用者和 B 使用者之間的通訊,也只有 B 使用者可以判斷密碼資訊。
這項技術使用密碼做為另一個金鑰,以加強網際網路安全性,但是在這個情況中,此為對稱式密碼編譯演算法的金鑰,例如「資料加密標準」(Data Encryption Standard,DES)、RC4 或 IDEA。A 使用者會知道密碼,因為 A 使用者是先產生這個密碼,再將密碼傳送給 B 使用者,而 B 使用者會知道密碼,是因為 B 使用者擁有私密金鑰,可以解密 A 使用者的訊息。由於 A 使用者和 B 使用者都知道密碼,因此他們都可以啟動對稱式加密演算法,然後傳送以對稱式加密演算法加密的訊息。下面是使用這項技術的修訂版通訊協定:
A->B B->A A->B B->A A->B B->A hello Hi, I'm User B, User_B's_certificate
prove it User A, This Is User B { digest[User A, This Is User B] } User_B's_private_key
ok User B, here is a secret {secret} User_B's_public_key {some_message}secret_key
安全性干擾
即使使用上述所有的技術,想要干擾安全通訊的人 (C 使用者) 還是可能成功造成干擾。雖然 C 使用者無法找出 A 使用者和 B 使用者交換的密碼,但是 C 使用者可以重新排列 (或竄改) 密碼資訊,以干擾其對話。例如,如果 C 使用者位於在 A 使用者和 B 使用者之間,便可以原封不動地來回傳送大部分的資訊,而竄改特定的訊息 (這對 C 使用者來說相當容易,因為 C 使用者知道 A 使用者和 B 使用者用來進行通訊的通訊協定):
A->C C->B B->C C->A A->C C->B B->C C->A A->C C->B B->C C->A
hello hello Hi, I'm User B, User_B's_certificate Hi, I'm User B,
User_B's_certificate prove it prove it User A, This Is User B { digest[User A,
This Is User B] } User_B's_private_key User A, This Is User B { digest[User A, This Is
User B] } User_B's_private_key ok User B, here is a secret {secret} User_B's_public_key
ok User B, here is a secret {secret} User_B's_public_key {some_message}secret_key
Garble[ {some_message}secret_key ]
C 使用者會傳送未經修改的資料,直到 A 使用者和 B 使用者共用密碼為止。然後,C 使用者會竄改 B 使用者給 A 使用者的訊息。此時,由於 A 使用者信任 B 使用者,因此 A 使用者可能會相信被竄改的訊息,進而嘗試執行。請注意,C 使用者並不知道密碼,因此,C 使用者所能做的就是破壞使用密碼金鑰加密的資料。視通訊協定而定,C 使用者可能無法產生有效的訊息,但是如果運氣好,也可以產生有效的訊息。
為了防止這類破壞發生,A 使用者和 B 使用者可以在通訊協定中加入訊息驗證碼。訊息驗證碼是使用密碼和某些傳輸資料計算出來的一小段資料。上述的摘要演算法正好具有適用的內容,能用來建立可防禦 C 使用者的訊息驗證碼函數:
message_authentication_code := digest[ some_message, secret ]
由於 C 使用者不知道密碼,因此,無法計算摘要的正確值。即使 C 使用者隨機竄改訊息,如果摘要資料量相當龐大,C 使用者成功干擾的機率還是很小。例如,利用 MD5 (RSA 所發明的好用密碼編譯摘要演算法),A 使用者和 B 使用者就可以將 128 位元的訊息驗證碼值與他們的訊息一起傳送出去。C 使用者猜中正確訊息驗證碼的可能性大約是 18,446,744,073,709,551,616 分之 1。實際上,C 使用者無法猜出正確的訊息驗證碼。
下面是範例通訊協定,已再次修改為使用這項技術:
A->B B->A A->B B->A hello Hi, I'm User B, User_B's_certificate prove
it User A, This Is User B { digest[User A, This Is User B] }
User_B's_private_key ok
User B, here is a secret {secret} User_B's_public_key {some_message,message_authentication_code}secret_key
C 使用者可以嘗試竄改訊息,但是訊息驗證碼計算會顯示出訊息並非來自 B 使用者。A 使用者或 B 使用者能夠發現訊息驗證碼值是錯誤的,並停止通訊。C 使用者便無法再模擬 B 使用者。