天天看點

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

數字簽名、數字證書等技術,是現代資訊安全的核心技術,可謂使用面十分廣泛。其基本理論本身并不複雜,本文希望通過深入淺出的介紹,能夠讓大家有一些基本了解。

對稱加密、非對稱加密

讓我們通過一個例子開始:我們的主角分别是Alice和Bob。現在假設Alice要給Bob發送一份檔案,檔案内容非常機密。Alice不希望檔案在發送的過程中被人截取而洩密。

這個時候,自然想到的方法就是對檔案進行加密。當然除了加密外,我們還需要讓Bob能夠解密。就像Alice對檔案上了鎖,為了讓Bob能夠解開,則Bob必須有鑰匙來對檔案解鎖。在資訊安全或密碼學中,我們将這種鑰匙稱為密鑰。密鑰一般分為兩種,對稱密鑰與非對稱密鑰:

對稱密鑰很容易了解,如同Alice用一把鑰匙将檔案上鎖,而Bob使用相同的鑰匙就可以将檔案解鎖,即加密使用的密鑰與解密使用的密鑰是相同的。目前的對稱密鑰算法有DES、3DES、AES等,而密鑰則一般是一串固定長度的字元。

如下,Bob和Alice事先已經約定,将使用DES算法,并且已經約定好使用的密鑰。于是Alice使用這份密鑰對檔案進行了加密,并發送給Bob。Bob使用相同的密鑰對檔案解密即可:

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

對稱密鑰算法的安全性還是非常有保障的。拿DES算法舉例,到目前為止,除了用窮舉搜尋法對DES算法進行攻擊外,還沒有發現更有效的辦法。而56位長的密鑰的窮舉空間為256,這意味着如果一台計算機的速度是每一秒鐘檢測一百萬個密鑰,則它搜尋完全部密鑰就需要将近2285年的時間。而3DES(3次DES操作)、AES算法的安全性則更高。由此可見,使用對稱密鑰對檔案進行了加密,基本上不用太擔心檔案可能洩密。

目前大部分的開發語言都有對應的數字加密子產品,例如JAVA的JCE子產品就可以調用簡單的實作加解密。以下是一份JAVA代碼例子:

[java] view plain copy print ?

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
  1. package com.test.chiper;  
  2. import javax.crypto.Cipher;  
  3. import javax.crypto.spec.SecretKeySpec;  
  4. import sun.misc.BASE64Decoder;  
  5. import sun.misc.BASE64Encoder;  
  6. public class TestChiper {  
  7.     private static final BASE64Encoder base64En = new sun.misc.BASE64Encoder();  
  8.     private static final BASE64Decoder base64De = new sun.misc.BASE64Decoder();  
  9.     private static String AESKey="1234567890123456";  
  10.     public static String encrypt(String mText) throws Exception {  
  11.         SecretKeySpec secrekeysp = new SecretKeySpec(  
  12.                 AESKey.getBytes(),"AES");  
  13.         java.security.Key key = (java.security.Key) secrekeysp;  
  14.         Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");  
  15.         cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key);  
  16.         byte[] b = cipher.doFinal(mText.getBytes());  
  17.         return base64En.encode(b);  
  18.     }  
  19.     public static String decrypt(String mText) throws Exception {  
  20.         SecretKeySpec secrekeysp = new SecretKeySpec(  
  21.                 AESKey.getBytes(),"AES");  
  22.         java.security.Key key = (java.security.Key) secrekeysp;  
  23.         Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");  
  24.         cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key);  
  25.         byte[] b = cipher.doFinal(base64De.decodeBuffer(mText));  
  26.         return new String(b);  
  27.     }  
  28.   }  
package com.test.chiper;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class TestChiper {
	private static final BASE64Encoder base64En = new sun.misc.BASE64Encoder();
	private static final BASE64Decoder base64De = new sun.misc.BASE64Decoder();
	private static String AESKey="1234567890123456";
	
	public static String encrypt(String mText) throws Exception {
		SecretKeySpec secrekeysp = new SecretKeySpec(
				AESKey.getBytes(),"AES");
		java.security.Key key = (java.security.Key) secrekeysp;
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key);
		byte[] b = cipher.doFinal(mText.getBytes());
		return base64En.encode(b);
	}
	public static String decrypt(String mText) throws Exception {
		SecretKeySpec secrekeysp = new SecretKeySpec(
				AESKey.getBytes(),"AES");
		java.security.Key key = (java.security.Key) secrekeysp;
		Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key);
		byte[] b = cipher.doFinal(base64De.decodeBuffer(mText));
		return new String(b);
	}
  }           

前文提到的對稱密鑰算法,已經基本滿足了Alice對于檔案機密性的要求。然而還是存在兩個問題:

1、Alice與Bob彼此之間必須約定将使用的密鑰,而這個約定的過程本身就可能存在洩密的風險;

2、如果除了Alice以外,還有Jessica、Eva、Mary等100位女士也需要向Bob發送檔案。那麼,Bob可能需要有100次約定密鑰的過程。

由此可見,無論是安全性還是可用性上,對稱密鑰都是存在問題的。而兩個問題則是必須解決的。

1976年,美國斯坦福大學的研究所學生Diffie和教授Hellman發表一個基于非對稱密鑰加密的想法,這個想法開創了密碼學的變革。他們的想法其實非常簡單,将密鑰分為公鑰(publicKey)和私鑰(privateKey)兩種。公鑰加密的内容,使用私鑰可以解開;而私鑰加密的内容,公鑰可以解開。然而,單獨的知道公鑰或私鑰,卻沒有辦法推出另一份密鑰。

繼續我們的例子:仍然是Alice需要與Bob發送一份絕密檔案。在此之前,Bob生成了一對密鑰:公鑰和私鑰。Bob将公鑰釋出在了一個公共的密鑰庫中,而私鑰則不對外公開,僅Bob本人持有。如下圖所示,Alice從公鑰庫中取出Bob的公鑰,對檔案進行加密,再發送給Bob。而Bob通過自己持有的私鑰,即可将檔案解密:

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

通過非對稱密鑰,Bob隻是将公鑰公布,并沒有和Alice約定密鑰。僅僅知道公鑰是沒有辦法推出私鑰的,是以不用擔心私鑰洩密的問題。另一反面,如果有jessica也想向Bob發送檔案,僅需要從公鑰庫中取到Bob的公鑰即可,也不需要更多的密鑰。

非對稱密鑰算法很有效的解決了安全性和可用性的問題,非對稱密鑰算法又稱作“公開密鑰加密算法”,我們常說的PKI(Public Key Infrastructure)則是建立在此技術之上的安全基礎體系。目前使用最為廣泛的非對稱密鑰為RSA算法,該算法是由三位算法發明者的姓氏開頭字母命名而來。

由于非對稱加密算法的複雜度更高,是以非對稱加密的速度遠沒有對稱加密算法快,甚至可能比對稱加密慢上1000倍。

資訊摘要、數字簽名

基于上文的非對稱密鑰算法,我們可以繼續我們的場景:

假設有一天,Alice收到了一份署名為Bob的檔案。Alice希望能夠确認這份檔案一定是來自Bob;另外Alice希望能夠确信,這份檔案在傳輸過程中并沒有被它人篡改。那麼基于非對稱密鑰算法我們應該怎麼做?

确認檔案一定來自于Bob,其實就是Bob無法否認自己發送過這份檔案。資訊安全中稱作不可抵賴性;另一方面,确信檔案并沒有中途被篡改,則稱作不可篡改性。

在非對稱密鑰算法中提到,公鑰加密的内容使用私鑰可以解密。同樣的,基于私鑰加密的内容使用公鑰也可以解密,兩者一一對應。是以我們可以很容易想到。如果Bob利用自己手裡的私鑰對檔案進行加密後,傳輸給Alice。Alice再通過公鑰庫中Bob的公鑰進行解密,則可以證明檔案一定是由Bob發出(由于隻有Bob持有私鑰)。另外,因為傳輸的是密文,如果能夠使用公鑰解密,同時也證明了檔案并沒有中途被篡改。這樣的做法其實已經同時滿足了不可抵賴性和不可篡改性。

然而,由于傳輸的檔案可能很大,為了證明檔案的不可抵賴性和不可篡改性,需要對整個檔案進行加密,由于非對稱算法效率較低,這樣做的代價太大。是以正常的做法是用到資訊摘要和數字簽名的方式。

所謂資訊摘要,其實就是某種HASH算法。将資訊明文轉化為固定長度的字元,它具有如下特點:

①無論輸入的消息有多長,計算出來的消息摘要的長度總是固定的;

②用相同的摘要算法對相同的消息求兩次摘要,其結果必然相同;

③一般地,隻要輸入的消息不同,對其進行摘要以後産生的摘要消息也幾乎不可能相同;

④消息摘要函數是單向函數,即隻能進行正向的資訊摘要,而無法從摘要中恢複出任何的消息;

⑤好的摘要算法,沒有人能從中找到“碰撞”,雖然“碰撞”是肯定存在的。即對于給定的一個摘要,不可能找到一條資訊使其摘要正好是給定的。或者說,無法找到兩條消息,是它們的摘要相同。

一般的,我們将資訊的摘要也稱作資訊的指紋。如同指紋的含義,相同的資訊一定會得相同的指紋,而僅通過指紋又無法還原出原始資訊。目前主要的摘要算法有MD5和SHA1。

當有了資訊摘要技術以後,基于Bob向Alice發送檔案的場景,我們可以進行如下的操作:

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

第一步:

① Bob将原始的資訊進行一次資訊摘要算法,得到原始資訊的摘要值;

② Bob使用自己的私鑰,對該摘要值進行加密。得到資訊摘要的密文;

③ Bob将原始檔案和摘要值的密文一起發送給Alice。

④ 一般的,我們将原始檔案和摘要密文稱作Bob對原始檔案的簽名結果。

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

第二步:

① 當Alice接收到Bob傳輸的資訊(原始檔案,資訊摘要密文)後,使用Bob的公鑰将摘要密文解密,得到資訊摘要明文;

② 使用資訊摘要算法,取原文的摘要資訊,擷取原始檔案摘要資訊;

③ Alice比較解密後的摘要資訊和取得的摘要資訊。如果相同,則可以證明檔案一定由Bob發送,并且中途并沒有經過任何篡改。一般将這個過程稱作驗簽。

所謂數字簽名,就是對原始檔案的“指紋”進行了私鑰加密。這樣,即可保證檔案的特征(摘要值)一定經過了私鑰的加密。同時由于資訊摘要的長度普遍不長(MD5為128位,SHA1主要為256位),也并沒有帶來太大的開銷。

如同對稱密鑰算法,在大部分開發語言中,基于非對稱算法的數字簽名,數字加密算法。也都進行了一定的封裝。如下連結就比較詳細的描述了基于JCE如何實作數字簽名、加密、驗證等:

http://blog.csdn.net/centralperk/article/details/8538697

數字證書

基于非對稱密鑰算法,Bob生成了一對公私鑰。Bob将公鑰釋出在公開的密鑰庫中。而Alice在向Bob發送加密檔案或者驗證Bob簽名的檔案時,均要從公鑰庫取到Bob的公鑰。我們已經知道,一般來說公鑰就是一段固定長度的字元串,并沒有特定的含義。

為了讓Alice能夠友善的辨識公鑰,我們可以考慮對給公鑰附加一些資訊,例如該公鑰使用的算法,該公鑰的所有者(主題),該公鑰的有效期等一系列屬性。這樣的資料結構我們稱作PKCS10資料包

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

公鑰的主題我們采用唯一标示符(或稱DN-distinguished name),以盡量唯一的标示公鑰所有者。以下是基于抽象文法表示法所定義的PKCS10資料結構:

[plain] view plain copy print ?

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
  1. CertificationRequestInfo ::= SEQUENCE {    
  2.         version          INTEGER { v1(0) } (v1,...),   
  3.         subject          Name,    
  4.         subjectPKInfo  SubjectPublicKeyInfo{{ PKInfoAlgorithms }},    
  5.         attributes       [0] Attributes{{ CRIAttributes }}    
  6.         }    
  7.     SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {    
  8.         algorithm     AlgorithmIdentifier {{IOSet}},   
  9.         subjectPublicKey  BIT STRING    
  10.         }    
  11.     PKInfoAlgorithms ALGORITHM ::= {     
  12.         ...  -- add any locally defined algorithms here -- }    
  13.     Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}     
  14.     CRIAttributes  ATTRIBUTE  ::= {    
  15.         ... -- add any locally defined attributes here -- }    
  16.     Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {    
  17.         type    ATTRIBUTE.&id({IOSet}),    
  18.         values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})   
  19.     }   
CertificationRequestInfo ::= SEQUENCE {  
		version          INTEGER { v1(0) } (v1,...), 
		subject          Name,  
		subjectPKInfo  SubjectPublicKeyInfo{{ PKInfoAlgorithms }},  
		attributes       [0] Attributes{{ CRIAttributes }}  
		}  
	SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE {  
		algorithm     AlgorithmIdentifier {{IOSet}}, 
		subjectPublicKey  BIT STRING  
		}  

	PKInfoAlgorithms ALGORITHM ::= {   
		...  -- add any locally defined algorithms here -- }  
	
	Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}   
	
	CRIAttributes  ATTRIBUTE  ::= {  
		... -- add any locally defined attributes here -- }  

	Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {  
		type    ATTRIBUTE.&id({IOSet}),  
		values  SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) 
	}            

我們已經有了PKCS10資料包,除了公鑰資訊外,還有公鑰的持有者,公鑰的版本号等資訊。然而這樣的資料結構其實并沒有任何權威性。例如有一天一個叫做Richard的人想冒充Bob,也生成一對公私鑰,并且使用了相同的公鑰主題封裝為P10資料結構。Alice其實并沒有辦法分辨哪個是真實Bob的公鑰。

為了解決這個問題,就需要一個權威的第三方機構,對P10結構的資料進行認證。就如同對P10檔案蓋上一個權威的章,防止仿照。這樣的權威機構,我們稱作CA(Certificate Authority)數字證書認證中心。而CA如何為P10資料蓋章呢?非常簡單,就是我們前文已經提到的數字簽名技術:

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

① 如上圖所示,CA機構其實也持有一張私鑰。一般來說,CA會對這份私鑰進行特别的保護,嚴禁洩漏和盜用。

② Bob将自己的公鑰附加上一系列資訊後,形成了P10資料包(請求包),并發送給CA。

③ CA機構通過其他一些手段,例如檢視Bob的身份資訊等方式,認可了Bob的身份。于是使用自己的私鑰對P10請求進行簽名。(也可能會先對資料進行一些簡單修改,如修改有效期或主題等)

④ 這樣的簽名結果,我們就稱作數字證書。

數字證書同樣遵循一個格式标準,我們稱作X509标準,我們一般提到的X509證書就是如此。以下是X509的格式:

[plain] view plain copy print ?

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書
  1. [Certificate ::= SEQUENCE {  
  2.     tbsCertificate TBSCertificate,  
  3.     signatureAlgorithm AlgorithmIdentifier,  
  4.     signature BIT STRING  
  5. }  
  6. TBSCertificate ::= SEQUENCE {  
  7.     version [0] EXPLICIT Version DEFAULT v1,  
  8.     serialNumber CertificateSerialNumber,  
  9.     signature AlgorithmIdentifier,  
  10.     issuer Name,  
  11.     validity Validity,  
  12.     subject Name,  
  13.     subjectPublicKeyInfo SubjectPublicKeyInfo,  
  14.     issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,  
  15.     -- If present, version must be v2or v3  
  16.     subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,  
  17.     -- If present, version must be v2or v3  
  18.     extensions [3] EXPLICIT Extensions OPTIONAL  
  19.     -- If present, version must be v3  
  20.     }  
  21. Version ::= INTEGER {  
  22.     v1(0), v2(1), v3(2)  
  23. }  
  24. CertificateSerialNumber ::= INTEGER  
  25.     Validity ::= SEQUENCE {  
  26.     notBefore CertificateValidityDate,  
  27.     notAfter CertificateValidityDate  
  28. }  
  29. CertificateValidityDate ::= CHOICE {  
  30.     utcTime UTCTime,  
  31.     generalTime GeneralizedTime  
  32. }  
  33. UniqueIdentifier ::= BIT STRING  
  34.     SubjectPublicKeyInfo ::= SEQUENCE {  
  35.     algorithm AlgorithmIdentifier,  
  36.     subjectPublicKey BIT STRING  
  37. }  
  38. Extensions ::= SEQUENCE OF Extension  
  39. Extension ::= SEQUENCE {  
  40.     extnID OBJECT IDENTIFIER,  
  41.     critical BOOLEAN DEFAULT FALSE,  
  42.     extnValue OCTET STRING  
  43. }  
[Certificate ::= SEQUENCE {
	tbsCertificate TBSCertificate,
	signatureAlgorithm AlgorithmIdentifier,
	signature BIT STRING
}

TBSCertificate ::= SEQUENCE {
	version [0] EXPLICIT Version DEFAULT v1,
	serialNumber CertificateSerialNumber,
	signature AlgorithmIdentifier,
	issuer Name,
	validity Validity,
	subject Name,
	subjectPublicKeyInfo SubjectPublicKeyInfo,
	issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
	-- If present, version must be v2or v3
	subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
	-- If present, version must be v2or v3
	extensions [3] EXPLICIT Extensions OPTIONAL
	-- If present, version must be v3
	}
Version ::= INTEGER {
	v1(0), v2(1), v3(2)
}

CertificateSerialNumber ::= INTEGER
	Validity ::= SEQUENCE {
	notBefore CertificateValidityDate,
	notAfter CertificateValidityDate
}

CertificateValidityDate ::= CHOICE {
	utcTime UTCTime,
	generalTime GeneralizedTime
}

UniqueIdentifier ::= BIT STRING
	SubjectPublicKeyInfo ::= SEQUENCE {
	algorithm AlgorithmIdentifier,
	subjectPublicKey BIT STRING
}

Extensions ::= SEQUENCE OF Extension
Extension ::= SEQUENCE {
	extnID OBJECT IDENTIFIER,
	critical BOOLEAN DEFAULT FALSE,
	extnValue OCTET STRING
}           

基于數字證書,我們可以再來看看Bob如何給Alice發送一份不可否認、不可篡改的檔案:

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

第一步:Bob除了對檔案進行簽名操作外,同時附加了自己的數字證書。一同發給Alice。

數字簽名與數字證書技術簡介 . 對稱加密、非對稱加密 資訊摘要、數字簽名 數字證書

第二步:Alice首先使用CA的公鑰,對證書進行驗證。如果驗證成功,提驗證書中的公鑰,對Bob發來的檔案進行驗簽。如果驗證成功,則證明檔案的不可否認和不可篡改。

可以看到,基于數字證書後,Alice不在需要一個公鑰庫維護Bob(或其他人)的公鑰證書,隻要持有CA的公鑰即可。數字證書在電子商務,電子認證等方面使用非常廣泛,就如同計算機世界的身份證,可以證明企業、個人、網站等實體的身份。同時基于數字證書,加密算法的技術也可以支援一些安全互動協定(如SSL)。下一篇文章,将為大家介紹SSL協定的原理。

繼續閱讀