Req指令介紹
功能概述和指令格式
- req指令一般來說應該是提供給證書申請用戶的工具,用來生成證書請求以便交給CA驗證和簽發證書。但是,OpenSSL的req指令的功能遠比這樣的要求強大得多,它不僅可以生成RSA密鑰、DSA密鑰,以及將它們封裝成證書請求,還可以對現有的證書請求進行簽名驗證、格式轉換及信息修改等。下面將通過對req指令的各個參數的介紹來了解其全面的功能。首先來看看req指令的格式:
- eq指令的許多選項跟OpenSSL配置文件(默認為openslcnf)的證書請求部分是緊密相關的,如果在指令中有些選項需要指定的參數沒有給定,那么req指令就會從配置文件中相應的字段去查找設置值。此外,有相當部分的證書請求屬性都是由配置文件的相關部分決定的。在本節的介紹中,會指出相應的證書請求配置部分內容。?
輸入和輸出格式選項inform,outform和keyform
- inform選項指定了選項in指定的輸入證書請求文件的編碼格式,目前來說,支持的編碼格式有兩種:PEM編碼和DER編碼,默認為PEM編碼。in選項指定的文件輸入內容是一個已經存在的符合PKCS#10標準的證書請求,在這里輸入的目的一般是為了驗證和顯示其中的一些內容。outform選項指定了輸出選項out輸出的證書請求或自簽名證書的編碼格式,目前支持的編碼格式包括PEM編碼和DER編碼,默認為PEM編碼。需要注意的是,該選項指定的格式不影響keyout選項的密鑰編碼格式和pubkey輸出的公鑰編碼格式。keyform選項指定了密鑰輸入選項key指定的密鑰編碼格式,目前來說,可以接受的編碼格式包括PEM編碼格式、DER編碼格式、PKCS#12編碼格式、Netscape編碼格式、舊版本的IISSGC編碼格式及Engine格式。
輸入和輸出文件選項in,out,key和keyout
- in選項指定了保存證書請求的文件名,默認是標準輸入。如果啟用了該選項,那么指令將根據一個已經存在的證書請求生成自簽名根證書或者顯示其中的一些內容,但是該證書請求的內容基本上是不能進行變更的。如果是要根據現有的證書請求生成自簽名根證書(使用x509選項),那么要求同時使用key選項指定證書請求里面的公鑰相應的私鑰以便對自簽名根證書進行簽名。
- 如果使用了new選項或者newkey選項,那么in選項指定的證書請求文件將被忽略。
- in選項輸入的證書請求的編碼可以是PEM格式也可以是DER格式,由inform選項指定。
- out選項指定了輸出文件名,默認是標準輸出。輸出文件可以保存包括證書請求、自簽名證書、編碼公鑰,以及由text、subject、modulus等選項指定的明文輸出信息。
- 其中,證書請求和自簽名證書的輸出編碼格式可以為DER編碼或者PEM編碼,由outform選項指定。
- 公鑰(如果使用了pubkey選項輸出)的編碼格式固定為PEM格式。
- key選項指定了輸入私鑰的文件,該文件內的私鑰編碼格式由keyform指定。
- 需要注意的是,如果keyform指定的編碼格式是ENGINE格式,那么key指定的文件內容要根據具體的Engine接口而定,可能是一個編碼公鑰,也可能是一個字符串ID,甚至可能是毫無意義的內容。
- 密鑰類型可以是RSA私鑰,也可以是DSA私鑰。
- keyout選項指定了新生成的私鑰的輸出保存文件,如果沒有指定,那么默認情況下會從OpenSSL配置文件中的req字段的default_keyfile選項的參數中獲取輸出私鑰文件名(openssl.cnf文件默認值是privkey.pem)。僅在使用了newkey或new選項導致生成新密鑰對的時候該選項才有效,如果使用了已有的私鑰(key選項指定),那么該選項就會被忽略。該選項輸出的私鑰編碼格式固定為PEM編碼。
- 輸出到keyout選項指定文件的私鑰一般都會被加密保護,加密的算法是DES3的CBC模式。
輸入和輸出口令選項passin和passout
- passin選項指定了讀取key選項指定的私鑰所需要的解密口令,輸入口令的方式可以是多樣的。如果沒有使用該選項,而key選項指定的私鑰又要求提供解密口令,那么指令會在指令行提示用戶輸入口令。
- passout選項指定了使用keyout選項輸出私鑰時使用的加密口令。如果使用了nodes選項,則表示不對私鑰進行加密,那么該選項指定的口令無效。如果該選項沒有使用,并且輸出了私鑰,也沒有使用nodes選項,那么指令會要求用戶從指令行界面輸入加密口令。
指令操作類型new,newkey,nodes和x509
- new選項告訴指令執行生成新的證書請求操作,這時候,in選項指定的輸入文件會被忽略。使用new選項后,如果沒有使用key選項指定私鑰用于生成證書請求,那么就會根據newkey選項的參數生成新的密鑰對。
- 默認情況下,如果指令既沒有使用key選項,也沒有使用newkey選項,那么指令就會生成一個RSA密鑰,其長度由OpenSSL配置文件中req字段的default_bits選項的參數決定。newkey選項讓指令生成一個新的密鑰對,該選項只有在沒有使用key選項的時候才有效。
- newkey選項有兩項功能:指定生成的密鑰類型和密鑰長度。
- newkey選項的參數有如下兩種形式:
- rsa : numbits
- dsa : file
- 其中,rsa代表生成RSA密鑰作為證書請求的密鑰對,dsa則表示生成DSA密鑰對作為證書請求的密鑰對。
- numbits表示要生成RSA密鑰的長度,一般來說使用1024位作為普通證書請求是合適的。
- file是存儲了DSA密鑰參數的文件名,DSA密鑰的長度由該文件存儲的DSA參數決定。
- nodes選項告訴指令不對新生成的私鑰進行加密保存,這樣,passout選項將被簡單忽略。如果沒有使用nodes選項,并且生成了新的私鑰,那么私鑰輸出到keyout指定的文件中時將會被以DES3的CBC模式加密。x509選項讓指令生成一個自簽名根證書而不是輸出一個證書請求。
- 所謂自簽名根證書,就是指用一對密鑰對的私鑰對自己相應的公鑰生成的證書請求進行簽名而頒發證書,這樣,證書申請人和簽發人都是同一個,所以稱為自簽名根證書。如果根證書不是用于根CA,那么一般來說只有測試上的意義。在req指令中,既可以直接生成一個新的自簽名根證書,也可以根據現有的證書請求和其相應私鑰生成自簽名根證書。如果是根據現有證書請求生成自簽名根證書,那么一定要key選項提供相應的私鑰指令才能執行成功。
屬性設置選項digest,subj,days和set_serial
- digest選項指定了生成證書請求或者自簽名根證書時使用的信息摘要算法,該信息摘要算法一般在生成數字簽名的時候使用
- 需要注意的是,如果使用的是RSA算法,理論上除了DSS數字簽名標準指定的信息摘要算法(ds1)不能使用以外,其他信息摘要算法都能夠用于生成數字簽名并且req指令也能夠正確執行,但是,由于RIPEMD算法在標準中沒有得到支持,很可能導致某些CA和應用程序不能正確使用。如果使用的密鑰是DSA密鑰,那么digest的任何設定都會被忽略,事實上,這時digest的值就固定為DSS規定的信息摘要算法。默認的digest算法是MD5。
- subj選項直接從指令行指定了證書請求的主體名稱,如果沒有出示該選項,那么req指令將會根據配置文件特征名稱字段的設定提示用戶輸入必要的信息,比如國家代號(通常是兩個字符)、省份、單位名稱,等等。如果使用subj選項,那么這些提示信息就不會再出現。
- subj選項的參數格式如下:
- ?參數應該以“/”開頭,每個值直接使用“/”作為分隔符號。“type* ”應該是OpenSSL內部支持的數據對象名稱。比如下面是一個例子:
- days選項設定了生成的自簽名根證書的有效期,單位是天。該選項只有在使用了x509選項生成自簽名根證書的時候才有效。默認值是30天。set_serial選項指定了生成的自簽名根證書的序列號,默認情況下生成的自簽名根證書序列號是0。該選項也只有在生成自簽名根證書的時候有效。?
配置文件選項config,extensions和reqexts
- config選項指定了req指令在生成證書請求的時候使用OpenSSL配置文件,該文件的最好例子是openssl.cnf,一般來說,openssl.cnf也是默認的req指令配置文件。但是,如果在Windows環境中使用并且在編譯的時候沒有指定正確的路徑,那么該默認配置文件很可能因為路徑不正確而不能不到,這時候使用config選項就顯得非常必要了。當然,config選項并非指定配置文件的唯一方法,你還可以使用OPENSSL_CONF或者SSLEAY_CONF環境變量指定默認的配置文件
- extensions選項指定了生成自簽名根證書的時候使用的擴展字段,其參數為OpenSSL配置文件中某個字段名(比如opensl.cnf文件中的v3_ca字段)。該字段一般規定了一些證書的擴展項信息,比如證書的用途,是否能夠作為CA證書等性質。
- reqexts選項指定了生成證書請求時使用的擴展字段,該字段參數也是配置文件中的某個字段名,比如openssl.cnf文件中的v3_req字段,該字段也是證書請求中設置的要求申請的證書的一些使用限制信息。其內容跟證書擴展項內容基本一致。extensions選項和reqexts選項使得在同一個配置文件中可以存在多個不同的字段用于生成不同用途和目的的證書,比如,申請一個CA證書和用戶證書的證書請求擴展字段設置是不一樣的,那么可以在配置文件中將兩種不同的證書請求設置分別寫成兩個不同的字段,在生成證書請求的時候根據需要使用reqexts選項指定不同的字段即可達到不同的目的。
屬性格式化選項asn1-kludge,newhdr和utf8
- 一般情況下,如果證書請求的某個屬性沒有填寫,那么對應的證書請求字段會填寫一個空的值。
- 但是某些不完全標準的CA不能正確處理這些空值,它們的要求是:如果沒有填寫任何值,那么該屬性字段就不應該出現在證書請求中。
- 對于這些CA,你可能就需要使用asn1-kludge選項實現這個目的(與屬性相對應的字段為空就不出現在證書請求中)。
- newhdr選項使用后將會在輸出的PEM編碼的證書請求開始和結束行增加“NEW”標記字符串,這是為了跟Netscape和其他一些證書服務器兼容設置的選項。使用newhdr和不用newhdr選項的證書請求格式如下。
- utf8選項使用之后,將對輸入的信息采用UTF8編碼,而不是默認的ASCI編碼。UTF8編碼對于中文來說具有很重要的作用。
engine選項
- engine選項指定后,所有指定Engine支持的操作都將使用Engine指定的加密庫或者硬件設備進行,而不再是使用OpenSSL默認的算法庫。對于req指令來說,可能使用Engine設備的操作包括RSA或者DSA密鑰產生、簽名時使用的信息摘要算法、簽名時使用的私鑰加密算法、簽名驗證操作的公鑰解密操作、隨機數產生和對私鑰進行加密的DES3算法。如果engine選項指定了有效的Engine設備,那么指令中任何該Engine設備支持的上述操作都會使用Engine設備的操作流程而不再使用OpenSSL算法庫本身提供的函數。
輸出內容選項text,reqopt,pubkey,noout和subject
- text選項讓指令輸出證書請求或者自簽名根證書內容的明文解析,默認情況下,它將輸出所有可能輸出的內容
- 但是如果使用了reqopt選項,其輸出內容就取決于reqopt選項。
- reqopt選項用于指定text選項輸出的內容,其參數可以是多個,每個之間使用“,”作為連接符號。
- reqopt支持的參數如表所示。?
- ?對于證書請求來說,上表中的很多內容沒有,對于這種情況,指令會自然忽略,相關的參數也就不會產生任何作用。
- reqopt選項只有在跟text選項一起使用的時候才有效。
- 例如我們要使輸出自簽名證書的文本信息不包含序列號和公鑰信息,則可以使用下面的指令:
- pubkey選項使用后,指令將會輸出PEM編碼的公鑰到out選項指定的文件中。默認情況下只輸出私鑰到keyout指定的文件,并不輸出公鑰。
- noout選項使用后,指令將不會輸出編碼的證書請求或者自簽名根證書到out選項指定的文件中,該選項一般用來測試指令或者查看證書請求的信息。
- subject選項告訴指令輸出主體名信息,即使已經使用text選項輸出了主體名信息,該選項的啟用也會讓指令重復輸出一遍主體名信息。
輸出字符編碼選項nameopt
- nameopt選項指定了如何顯示主體名稱和簽發者名稱,主要用于顯示名稱中不同編碼的內容,比如UTF8編碼等。如果沒有使用該選項,那么默認使用的是“oneline”參數。該選項可以同時使用多個參數,每個參數之間使用“,”作為連接符。此外,每個參數之前還可以使用“-”表示不使用該參數定義的顯示方式。
- 如表所述是nameopt選項支持的所有參數。
- 需要注意的是,nameopt選項只影響使用text和subject選項輸出的主體名稱和簽發者名稱的顯示方式,對其他項目的顯示方式沒有影響。上述的功能對于正確顯示中文信息來說具有很重要的意義。前面說過,可以同時使用多個參數,下面是一個例子:?
- 上述指令指定在顯示自簽名證書的主體名稱和簽發者名稱時,使用單行顯示方式,但是禁止在顯示之前進行UTF8格式的轉換,并且域名稱使用長名稱進行顯示。?
證書請求數字簽名驗證選項verify
- 使用verify選項的指令將對證書請求的數字簽名進行驗證操作,并給出失敗或者成功的提示信息。其驗證的過程是從證書請求里面提取公鑰,然后使用該公鑰對證書請求的數字簽名進行驗證。
其他選項rand,batch和verbose
- rand選項指定了生成密鑰對或者其他一些操作需要的隨機數種子文件。如果沒有使用rand選項,指令會從其他可能得到的資源取得隨機數種子數據。
- 使用batch選項將不再提示用戶輸入生成證書請求需要的用戶信息,而是直接從OpenSSL配置文件特征名稱字段讀取默認值,如果沒有默認值,則不填寫該值域。一般來說,在你做測試的時候使用該選項會提高效率。
- verbose選項讓指令輸出執行的各個操作的詳細信息,一般來說,該選項也僅對調試程序有意義。
?生成證書密鑰
證書請求中使用RSA密鑰
- RSA密鑰是目前證書中最經常使用的密鑰類型,這一部分是因為其既可以支持密鑰交換,又可以支持數字簽名的特性;
- 更重要的是RSA算法是一種經過充分考驗和密碼分析的算法,其安全性得到了公認。在使用req指令生成證書請求時,我們可以采用兩種方法生成RSA密鑰對:一種是使用genrsa指令預先生成密鑰對,一種是直接在req指令中生成密鑰對。從本質上來說,這兩種方法沒有區別,但是,使用第一種方式能夠更靈活地處理密鑰的保存和格式等問題。
- 我們首先看下面的指令,它使用req指令直接生成了一個新的1024位RSA密鑰用于新的證書請求中:
- 上述指令對生成的RSA私鑰進行了加密,加密的算法自己是沒有選擇余地的,只能是DES3-CBC模式,當然,你可以使用rsa指令對密鑰使用的加密方法和口令進行重新的更改。此外,私鑰輸出的編碼格式也沒有選擇的余地,只能是PEM編碼。這些限制可能很多時候不能滿足你的要求。
- 為了避免上面這些限制,你可以使用genrsa指令先生成需要的RSA密鑰對,然后再使用req指令生成證書請求。事實上,在實際應用中,你的RSA密鑰對甚至可能不是使用OpenSSL的指令工具生成的,但這沒有關系,只要你的密鑰封裝格式是req指令中keyform選項支持的,那么就能夠使用req指令生成證書請求。下面我們來看怎么使用genrsa指令和req指令生成一個證書請求。雖然說DES3-CBC方式的安全性一般還是值得信賴的,但我們更愿意使用256位的AES算法保護我們的RSA私鑰,畢竟對于私鑰來說,怎么提高它的安全性都不為過。
- 顯然,req指令滿足不了我們的要求,那么可以使用genrsa指令:?
?證書請求中使用DSA密鑰
- DSA密鑰是專門用于數字簽名的密鑰,當你要申請一個用于數字簽名的證書的時候就可能需要使用這種類型的密鑰。跟RSA密鑰產生不同,DSA密鑰一般通過其預先生成的DSA密鑰參數來生成DSA密鑰。req指令提供了根據DSA密鑰參數生成DSA密鑰的功能,而DSA密鑰的長度則由給定的DSA密鑰參數決定。當然,你也可以根據給定的DSA密鑰對生成證書請求。下面我們介紹利用req指令本身生成DSA密鑰的功能。由于req指令要求輸入一組DSA密鑰參數來生成DSA密鑰,所以我們必須首先使用dsaparam指令生成DSA密鑰參數。
- 需要注意的是,req指令只能接受PEM編碼的DSA密鑰參數。
- 首先生成DSA密鑰參數的指令如下:
- ?跟使用req指令生成RSA密鑰對相同的是,輸出DSA私鑰的加密算法只能是DES3-CBC模式,編碼方式也只能是PEM方式。所以為了靈活和方便,你可能愿意使用gendsa指令來生成DSA密鑰,然后再使用req指令生成證書請求文件。首先我們利用剛才生成的DSA密鑰參數文件生成一對DSA密鑰:
- ?再次強調,上面我們在生成RSA或者DSA密鑰對的時候,都只輸出了私鑰文件,這是因為私鑰文件結構中已經包含了相應的公鑰參數,req指令使用私鑰的時候,事實上主要是從其中提取出相應的公鑰,并封裝在PKCS#10的證書請求結構中,然后采用私鑰對整個證書請求結構簽名從而完成操作。
誰來生成密鑰對
- 如果私鑰由用戶本地生成,使用其公鑰加密數據,如果用戶消失會給組織帶來巨大的危險。考慮到這點,為了方便管理,通常就由CA或者RA來生成用戶的密鑰對,并在發放證書的時候將證書和密鑰對一起發送給用戶。但這顯然違背了私鑰是唯一被主人擁有的假設,這樣你可能覺得非常沒有安全感,因為掌握備份密鑰庫的人可能隨時可以查看你的任何資料和通信內容,但是你沒有任何辦法。
- 對于用于數字簽名的證書來說情況會好一點,因為數字簽名不需要對整個文件進行加密,它不存在數據恢復的問題。即便私鑰丟失或者破壞了,也只是不能使用它繼續簽名其他文件而已,換一個就是了。所以用于數字簽名的密鑰對不需要備份功能,一般可以由用戶自己產生。從法律角度而不是保密角度來看,數字簽名的唯一性顯得尤為重要。
- 由于上述的這些原因,現在很多系統都使用所謂雙證書的概念,即一個證書用于密鑰交換,一個證書用于數字簽名。用于密鑰交換的證書其密鑰對一般由CA或者RA代替用戶產生;而用于數字簽名的證書的密鑰對則由用戶自己產生。事實上,這樣的做法只是在法律上得到了保證,而數據保密性能則很值得懷疑,尤其是個人的隱私問題。具體到技術上,如果采用的是用戶自身生成密鑰對,那么req指令的功能應該由用戶來使用。但是如果是CA或者RA生成密鑰對,req指令跟用戶基本就沒有關系了,事實上這時候req指令的功能應該由RA或者CA執行,而用戶只要簡單地把自己的信息交給RA或者CA就可以了。但是,CA真的那么值得信任?
在證書中添加擴展項
- 要真正用好req指令提供的功能,僅僅了解req指令的選項和參數是不夠的,還需要對req指令所依賴的OpenSSL配置文件中的req指令相關字段有比較深入的了解。一下子要全部了解是不可能的,使用OpenSSL配置文件中的證書請求相關字段實現一些擴展的功能。首先我們看看怎么在證書請求中增加一個自己定義的擴展項。在某些特殊情況下,可能需要在證書中擴展一些標記以便實現一些特定的功能,比如,你可能需要在給你公司員工發放的證書中增加一項權限的功能,這可能給會給管理帶來很大的方便,尤其對于有多個服務器的分布式系統中,這種證書尤其有用。下面我們就通過往證書的特征名稱字段中添加一個擴展的字段實現存取用戶的權限信息。
- 首先請打開OpenSSL默認的配置文件opensl.cnf,然后確保其中的下列語句沒有被注釋掉:
- 上面定義了一個新的OID對象,其簡短名稱和長名稱都是UserRights,而OID則為2.5.4.255。下面,我們就要在證書請求的特征名稱字段添加我們新增加的這個OID對象,使得證書主體名稱中能夠增加一項代表用戶權限的值域。
- 為了使得管理方便,我們限定該項的值只能是兩個字符,默認的值是“US”(User),表示普通用戶權限。
- 下面是往req_distinguished_name字段添加的語句:?
?
- ?設置完上面這些內容,我們就可以使用這個配置文件作為req指令的配置文件,進行新證書請求的簽發。你會發現在生成證書請求時提示輸入信息中多了一項提示內容,即“UserRights”選項,用戶就可以根據自己對不同權限的命名填寫內容了。
- 如果你用text選項則顯示的證書請求主體名稱形式如下:
- 如果證書應用的系統是一個分布式的系統,那么這些選項對于分布式的權限控制等會產生非常大的好處。當然,要在最后生成的證書中增加這些擴展項,CA的配置文件相應的一些選項也需要做一些更改?
申請用戶證書
- 證書按照其在證書鏈中的位置分類,一般可以分為兩種:終端用戶證書和CA證書。所謂CA證書,是指該證書可以用于簽發別的用戶證書,也就是說,它可以有下級的證書。終端用戶證書則用于具體應用程序或協議中,它不能用來簽發別的證書,在證書鏈中,它處于最末端。
- 對于一般用戶來說,申請的證書都是終端用戶證書。對于生成證書請求的req指令來說,生成的證書請求是用于申請一個終端用戶證書還是CA證書是由OpenSSL配置文件的證書請求X.509v3擴展項字段來決定的,opensl.cnf文件中的默認字段名是req_v3。
- 為了使req_v3擴展字段生效,首先必須確保配置文件req字段中的下面語句沒有被注釋掉:
- 接著,我們修改v3_req字段中的basicConstraints選項為下面的形式:
?
- ?然后保存,利用這個配置文件作為req指令的配置文件,其生成的證書請求就是一個申請終端用戶證書的證書請求,如果你使用text選項輸出明文信息,你會發現在“RequestedExtensions”部分出現下面的信息:
- ?上述的CA:FALSE值即表示該證書請求不是CA證書請求,而是普通的終端用戶證書請求。當然,證書請求的這個擴展字段最后能起到什么作用,還得取決于簽發證書的CA的具體策略。
- 生成一個CA證書請求而不是普通的終端用戶證書請求,修改如下
- ?然后保存,利用這個配置文件作為req指令的配置文件,其生成的證書請求就是一個申請CA證書的證書請求,如果你使用text選項輸出明文信息,你會發現在“RequestedExtensions”部分出現下面的信息:
- 上述的CA:TRUE值即表示該證書請求是CA證書請求。同樣,證書請求的這個擴展字段最后能起到什么作用,還得取決于簽發證書的上級CA的具體策略。
建立CA
- CA是集技術和管理于一體的龐大機構
CA服務器的基本功能
- CA服務器是一個應用程序,它從技術上實現了符合PKI和X.509等相關標準的證書簽發和管理功能。
- 總的來說,其基本功能應該包括以下幾個方面:接受申請證書的請求、審核證書請求、簽發證書、發布證書、吊銷證書、生成和發布證書吊銷列表(CRL)及證書庫的管理。
接受證書請求
- 這是首先必備的功能,一個CA應用程序必須能夠從各種途徑接受用戶的證書請求,至少需要一個這樣的途徑和接口。一般來說,證書請求的提交歸納起來有三種:在線實時提交、在線非實時提交和本地提交。
- 在線實時提交是指提供一個應用接口(一般是個服務端口),用戶可以通過支持CA服務器規定的證書請求協議發送證書請求信息,CA服務器能夠實時響應提交的請求并作出是否提交成功的回復,如果CA服務器是自動簽發證書并且你的申請符合設定的條件,用戶就有可能快速得到簽發好的證書。這種方式的實現一般采用C/S的模式,需要客戶端軟件的支持。
- 在線非實時提交一般通過Web方式實現,用戶可以通過Web頁面把證書請求提交到服務器指定的一個目錄或者數據庫中,然后,CA服務器程序或其管理員可以定期或者不定期檢測數據庫,如果發現有新的證書請求,則起動證書請求審核和簽發流程。這種方式的實現一般采用B/S結構。
- 本地提交方式即用戶到CA服務器所在地或者RA服務器所在地提交或填寫自己的資料和申請證書的請求,然后交給CA服務器管理員處理。一般來說,如果你的CA實現的是密鑰對由用戶自己生成的方式,那么一般接受的證書請求都是符合PKCS#10標準的。如果不是這樣,即CA服務器號稱可以替代用戶生成“安全”的密鑰對的方式,那么接受的資料很可能就是一些文本資料,至于具體的格式,就根據自己的需要決定了。
- 上述三種接受證書請求的模式各有其不同的應用環境。在線實時接受申請模式,實現起來工作量會比較大,并且需要客戶端軟件的支持;但是也有好處,在某些必須使用數字證書的客戶端軟件中可以集成證書自動申請功能,這樣就簡化了用戶使用客戶端軟件時候的配置操作。而基于Web方式的在線非實時提交方式實現起來顯然比較容易。本地提交方式能夠提供對用戶身份進行嚴格確認的機會,這對于證書的安全應用能夠提供很好的保障。
審核證書請求
- 很難說審核證書請求僅僅是一個技術上的問題,事實上,審核過程要求得更多的是管理的策略。當然,你可以通過CA服務器程序將你的管理策略實現,比如必須要求用戶提交的證書請求中國家名稱跟規定的相一致,等等。當然,僅僅這些是不夠的,嚴肅對待一個證書請求的態度是驗證嚴格審核其各個條目的信息,并在有必要的時候跟用戶本人進行核實。這就至少要求CA服務器能夠向管理員顯示出一個證書請求的所有詳細內容,這就是CA服務器對審核證書請求的基本要求,當然,CA服務器可以實現
簽發證書
- 如果通過了證書請求的審核過程,那么簽發證書就是CA服務器馬上要執行的操作。該操作實際上是將證書請求的信息和CA服務器自己的部分信息按照X.509的標準進行格式化,然后CA服務器使用自己的私鑰對所有這些信息進行數字簽名,然后形成一個X.509標準的證書。
- 接著,當然要將證書保存在證書庫中,并對證書庫進行更新。
發布證書
- 證書簽發好后,就需要將證書發布出去。發布對象有兩種:一種是申請證書的用戶本人,必須讓他能夠及時獲得自己的證書;一種是其他用戶,可以向他們提供獲得所有用戶證書的途徑。
- 一般來說,可以通過Web方式或LDAP目錄發布證書,當然,對于申請證書的用戶本人,也可以通過Mail或其他途徑發送。在某些情況下,比如是CA服務器生成證書密鑰對的情況下,還要考慮私鑰的傳輸問題,這一般來說需要高度考慮其安全性,最好采用硬件設備來傳送私鑰。如果非要考慮用軟件的方式來保存私鑰,那么一般需要對私鑰進行加密保存,最簡單的方式,就是將證書和私鑰一起封裝成PKCS#12的證書然后通過可能的途徑發送給用戶本人。
吊銷證書
- 有些情況下需要取消一個沒有過期的證書的有效性,那么這就需要CA服務器執行吊銷該證書的操作,這是確保整個CA證書域安全性的必備條件。吊銷證書的操作一般就是更新證書數據庫,發布新的CRL等,目的就是為了盡可能讓所有用戶都知道該證書已經無效。
生成和發布CRL
- 雖然所有已經吊銷的證書在CA有效的證書數據庫中都已經不存在,但是用戶在很多時候并不能實時地訪問和查詢CA數據庫,當然也就不能就此終止所有基于證書的應用服務。這時候就需要利用CA服務器發布的證書吊銷列表(CRL)來進行證書的驗證。CA服務器必須能夠定期更新和發布CRL,以便用戶能夠獲得準確的CRL信息。
證書庫管理
- CA服務器的證書庫存儲了CA簽發的所有有效證書,有時候,甚至也包括無效的證書和證書相應的私鑰,這就要求CA服務器能夠對證書進行有效的管理。例如對證書狀態的更新,無效和過期的證書應該刪除或者做相應的標記狀態,等等.
CA服務器的基本要素
- 要建立和運行一個CA服務器,那么至少應該具備以下一些要素:
- 一個具備CA應用程序;
- 一個CA證書和一個其相應的私鑰,可能是自簽名的根證書,也可能是向另一個CA申請的證書;
- 證書數據庫,用于存儲證書(有時候還包括私鑰)。
- CA應用程序的選擇有很多,如果你不介意微軟的神秘代碼可能隱含的安全性問題,那么可以用Windows系統的CA服務器程序。你還可以選擇OpenCA提供的CA服務器,當然,它事實上就是OpenSSL的封裝版本。
- CA證書和私鑰的產生根據不同的應用而定,如果你的CA服務器是自成體系,并不需要一個上級CA的支持,那么可以使用OpenSSL的req指令生成一個自簽名根證書作為CA服務器的證書即可。
- 如果你的CA服務器是上級CA的一個下級CA,那么就需要生成一個CA證書請求并發送給上級CA,然后等待上級CA簽發你的CA證書。
- 證書數據庫的選擇是多樣的,你可以使用任何像SQLServer,Oracle和MySql這樣的數據庫,也可以使用自定義的文本數據庫,甚至可以使用特定的目錄結構等。這需要根據自己的需要而定。如果你選擇現有的CA應用程序,你可能沒有這么多選擇,比如OpenSSL的ca指令,就僅僅使用文本數據庫。具備了上述這些基本的要素,你的CA服務器就可以啟動并運行簽發證書的服務了。
OpenSSL模擬CA服務器架構
- 默認的CA目錄結構上面介紹了各種CA應用服務器,本章節的目的只有一個:就是介紹基于OpenSSL的ca指令的證書服務器。
- 當然,并非僅僅想告訴你OpenSSL的CA服務器是如何配置和使用的,而是希望通過上面的介紹,讓你深刻理解CA服務器的工作流程和操作過程。OpenSSL的ca指令是一個模擬的CA服務器程序,它實現了CA服務器的基本功能。
- ca指令的正常運行依賴于一個目錄結構和一個OpenSSL配置文件,OpenSSL配置文件我們已經相對熟悉了,本節主要對這個目錄結構進行介紹。
- 如圖所示展現了整個CA目錄的結構。圖中,粗線條框顯示的是目錄,而細線條框顯示的則是文件。圖中,certs和crl目錄是使用ca.pl程序創建生成的,目前來說,ca指令并沒有使用這兩個目錄,可以忽略。
- newcerts目錄存放新簽發的證書文件,證書文件名是序列號,后綴名是pem,即輸出的證書默認都是PEM編碼的。比如簽發的證書如果其序列號是01,那么其保存在newcerts目錄的證書文件名就是“01.pem”。
- private目錄目前僅對于存放CA證書相應的私鑰文件有意義,其默認私鑰文件名為cakey.pem。每次使用CA指令如果沒有指定特別的密鑰,那么就會使用該密鑰簽發證書。
- demoCA根目錄下的cacert.pem文件就是PEM編碼的CA證書文件,里面保存了CA的證書。如果沒有使用ca指令的選項指定別的證書文件,那么每次使用ca指令簽發證書的時候就使用該證書。
- demoCA根目錄下的index.txt文件是ca指令相應的文本證書數據庫,index.txt文件保存了已經簽發的證書的信息和狀態。
- demoCA根目錄下的serial文件是ca指令決定簽發證書的序列號所依賴的文件,其格式和內容請參考第6章相關內容。在使用ca指令簽發證書后,你還會發現在根目錄下還會產生serial.old和index.txt.old文件,這是上次簽發證書時serial和index.txt文件的備份文件,一般來說不用理會它們。
OpenSSL配置文件
-
事實上,上面所說的所有目錄結構都是可以改變的,它們都由OpenSSL配置文件的CA字段所決定,讓我們來看看默認的opensl.cnf文件的這些相關配置選項:?
?
- ?如果你愿意,你可以通過更改上述這些選項的值來更改ca指令使用的目錄結構和文件。事實上,在使用ca指令時,指定特定的OpenSSL配置文件也是必備的條件之一。為了方便起見,本書后面的章節在介紹ca指令時,都以默認的目錄結構為準。
建立基于OpenSSL的CA服務器
手動創建一個CA目錄結構
- 假設我們已經擁有了ca指令程序和配置文件,為了使ca指令能夠正確運行,首先就是按前面介紹的CA目錄結構的要求創建這樣一個CA目錄結構和相應的文件。如果你愿意自己來一步一步建立這么一個目錄,那么可以按照下面的步驟進行。
- 1 在opensl可執行程序(Windows下是opensl.exe)所在目錄下創建一個名為“demoCA”的目錄。
- 2 在demoCA目錄下創建newcerts,private,crl和certs子目錄。
- 3 在demoCA目錄下創建一個空的名為index.txt的文本文件。
- 4 在demoCA目錄下創建一個空的名為serial的文件,用文本編輯器打開(vi或者記事本),在文件中填入01,保存退出。
- 5 將CA證書文件轉換成PEM格式,復制到demoCA根目錄下,并重新命名為cacert.pem。
- 6 將CA私鑰文件轉換成PEM格式,復制到demoCA/private目錄下,并重新命名為cakey.pem。
- 經過上述兩個步驟,你就建立了一個ca程序能夠使用的CA目錄結構。如果你的CA使用上級CA簽發的證書,那么你可能需要將證書和私鑰文件轉換成PEM編碼的格式以完成第5和第6步的配置。
- 如果你使用的是自簽名根證書,那么可以使用下面的req指令生成一個自簽名根證書和私鑰:
自動創建一個CA目錄結構
- 手動創建一個CA目錄的過程是很煩瑣的,OpenSSL開發者能夠理解大家的這種心情,提供了一個基于Perl的腳本幫助大家自動創建一個CA目錄結構。
- 前提是,你正確安裝了Perl軟件。首先你將OpenSSL的apps目錄下的ca.pl文件復制到你想要放置CA目錄結構的目錄。
- 接著,在指令行界面進入到ca.pl所在的目錄,運行下面的指令:
?證書配置文件選項config,name,extensions,extfile和policy
- ca指令跟OpenSSL的配置文件關系非常緊密,ca指令的證書請求值域匹配策略、擴展項參數及其他默認的參數設置都是依賴于OpenSSL配置文件的相關字段。
- ca指令除了會自動尋找和使用默認的OpenSSL配置文件和字段外,還運行用戶在指令中指定的配置文件及特定的字段。
- config選項指定將要使用的配置文件。在默認情況下,如果不使用config選項,ca指令首先會尋找環境變量OPENSSL_CONF或者SSLEAY_CONF定義的文件名,如果這兩個環境變量都沒有定義,那么就使用OpenSSL安裝時默認的路徑。這個默認的路徑通常情況下是“/usr/local/sl/opensl.cnf”,當然,你可以在安裝OpenSSL的時候使用configure腳本指令更改這個默認的安裝目錄。
- 比如通常在Windows下編譯完OpenSSL后,可執行文件openssl.exe通常在目錄out32dll下,而其配置文件則在apps目錄下,為了在out32dll目錄下能夠正確使用OpenSSL的ca指令,可以使用config選項:
- 在默認的情況下,ca指令使用的CA主配置字段由配置文件中ca字段的default_ca選項的參數值決定。其形式如:?
- ?當然,某些情況下你可能想使用在同一配置文件下(由config選項指定或默認得到的配置文件值)另外一個字段作為CA的主配置字段,那么name選項就可以實現你這個目的。name選項的參數是字段名,比如上面的“CA_default”,指定的字段名應該是已經在使用的配置文件中定義好了的。
- 例如在下面的名為openssl.cnf的配置文件中,定義了一個新的名為My_CA的CA主配置字段:
- ?policy選項讓指令使用其參數指定的字段名作為簽發證書請求時的匹配策略字段,其參數是配置文件中定義的一個字段名稱。事實上,在OpenSSL提供的openssl.cnf文件中,就已經定義了兩個匹配策略字段:policy_match和policy_anything。
- 默認情況下,ca指令通過CA主配置字段的下列選項采用policy_match字段作為匹配策略:
- 如果你不想更改openssl.cnf,但想使用policy_anything字段作為匹配策略字段,則可以使用下面的指令實現你的要求:?
- ?假設你的CA需要管理不同的用戶群,而每個用戶群需要自己特定的匹配策略,比如每個用戶群組織名稱都不同但是要求同一用戶群的用戶組織名稱必須相同,那么就可以在配置文件中預先定義不同的匹配策略字段,然后根據具體用戶使用不同的匹配策略字段來簽發證書。policy選項在這種情況下可以大顯身手。
- extensions和extfile兩個選項用來選定簽發證書時候使用的X.509v3擴展項定義字段。extensions的參數是字段名,用來選定配置文件中用于定義X.509v3擴展項的特定字段,默認的字段所在文件跟config選項選定的配置文件或者默認的配置文件是同一個文件。
- 但是某些情況下你可能希望使用一個專用的文件用來保存X.509v3擴展項信息,那么這時候可以使用extfile選項指定這個文件。如果僅僅使用了extfile選項指定額外的X.509v3擴展項配置文件,而沒有使用extensions選項,那么具體使用extfile指定的文件中那個字段,由默認配置文件中CA主配置字段的x509_extensions選項決定,類似如下的格式:
- 如果extensions和extfile兩個選項都沒有使用,那么默認的情況下就會使用config選項指定或者默認配置文件的CA主配置字段中x509_extensions選項參數指定的字段。例如在opensl.cnf文件中指定的就是上面所描述的usr_cert字段。假設我們在my_con.fig.cnf文件中定義了一個X.509v3擴展項字段如下:?
- 使用好extensions和extfile兩個選項能夠使ca指令的運用更加靈活。例如,你管理的用戶可能其證書用途各不相同,這可以通過在X.509v3的擴展項中來定義。為了方便簽發各種不同用途的證書,如果你不使用extensions選項,或許你需要不斷煩瑣地更改配置文件的X.509v3擴展項字段(默認是usr_cert),相信這樣下去,很快你就會產生辭職的想法。不過,如果你會使用extensions選項,事情就不一樣了,你可以根據需要預先編輯好幾個不同的x509_v3擴展項字段,然后根據簽發證書的需要使用extensions和extfile選項選用不同的字段,從而實現不同權限的證書的簽發。需要注意的是,如果你提供了有效的X.509v3擴展項字段(不管通過指令選項提供還是配置文件選項提供),即便字段是空的,指令也會生成一個X.509v3版本的證書。但是如果沒有提供有效的X.509v3擴展項,那么就生成X.509v1證書。
輸入和輸出選項in,infiles,out和outdir
- in選項的參數是一個可以包含路徑的文件名,該文件保存的應該是一個PEM編碼的PKCS#10格式的證書請求。事實上,in選項僅用于證書請求的輸入,而不能輸入其他類型的內容,也就是說,如果你使用了in選項,那么表示你要執行的操作就是簽發一個證書。
- infiles選項的參數是一系列包含PEM編碼證書請求的文件,跟in選項唯一不同的是,它可以一下子輸入多個證書請求文件,而不是一個。該選項總是作為指令的最后一個選項,其后面的所有參數都被認為是證書請求文件。
- out選項指定了輸出簽發好的證書或者新生成的CRL的文件。此外,如果沒有使用notext選項,那么證書的明文信息也會輸出到out選項指定的文件中,這在大多數Windows平臺上會導致證書文件不能被正確解釋,解決的最簡單辦法是使用notext選項禁止這些明文信息的輸出。不過,在較新的Windows系統,如WindowsServer2003,這個問題得到了解決。
- out選項指定的文件中輸出的證書或者CRL都是PEM編碼的。
- outdir選項指定了新生成證書的輸出目錄,在默認情況下,新生成證書總是輸出到newcerts目錄,并且是以序列號加“pem”后綴成為一個完整的證書文件名。這些證書都采用了PEM編碼。如果使用outdir選項指定了新的目錄,那么新生成的證書文件就會輸出到這個新指定的目錄。需要注意的是,不管out選項是否給出,都不會對輸出到outdir或者其默認目錄的證書文件產生影響。
特殊的證書請求輸入選項s_cert和spkac
- 前面介紹的兩種證書請求的輸入方式,即使用in或者infiles選項。它們的區別是輸入單個證書請求文件還是輸入多個證書請求文件。而它們的共同點則是輸入的都是PEM編碼的符合PKCS#10標準的證書請求。
- OpenSSL還提供了其他兩種輸入證書請求的方法,即ss_cert選項和spkac選項支持的方法。
- ss_cert選項允許用戶輸入一個自簽名的證書作為申請證書的證書請求,ca指令將會從這個自簽名證書中提取用戶信息和公鑰用于簽發最后的用戶證書。也就是說,你可以使用req指令生成一個自簽名證書而不是證書請求,然后用這個自簽名證書來向上級CA提供信息申請你的證書。
- spkac選項允許用戶輸入一個SPKAC格式的文件作為申請證書請求的資料,spkac是Netscape規定的一種格式,該格式包含了一個簽名的公鑰和其他附加用戶信息。需要注意的是,使用spkac作為證書請求輸入時,輸出的證書編碼是DER格式,而不是PEM格式的。
證書有效期選項
- startdate,days和enddate這三個都是用來設置證書有效日期的選項,分別是設置證書的生效時間、證書的到期時間及有效時間。
- startdate設置證書的生效時間,其參數格式是“YYMMDDHHMMSSZ”,每兩位代表一個時間變量,分別是“年月日時分秒”。比如要定義簽發的證書生效時間是2003年9月10日12時24分36秒(格林威治時間),那么startdate選項的參數就應該為“030910122436Z”。證書生效時間除了可以在ca指令的startdate選項指定外,也可以在配置文件的CA主配置字段的default_startdate選項指定,其參數格式跟startdate選項參數格式一致。如果沒有設置startdate選項,也沒有在配置文件中定義default_startdate選項,那么證書生效時間就是簽發證書的時間。
- days選項設置證書的有效天數。所謂有效天數,也就是從證書生效的時間到證書到期的時間之間的天數。
- enddate選項的參數格式跟startdate選項一樣,用來設置證書的到期時間。同樣,你也可以通過配置文件CA主配置字段中的default_enddate選項設定證書到期時間。如果設置了enddate選項,那么days選項將會被自動忽略。如果沒有設置證書到期時間,那么就會根據days選項設置的有效時間來決定證書到期時間。如果指令中也沒有使用days選項,那么指令就會從CA主配置字段讀取default_days選項的參數來決定證書有效期。
證書內容選項subj,preserveDN,noemailDN,md和msie_hack
- 一般情況下,簽發證書的時候,證書的主體名稱(subjectname,也稱為特征名稱)由證書請求中的主體名稱決定。不過,有時候用戶自己填寫的資料可能并不能讓你這個挑剔的CA管理員滿意,那么你可以使用subj選項重新填寫用戶的證書主體名稱。
- subj選項的參數格式應該如下:
- ?其中,“type*”必須是已經由OpenSSL內部定義或者在配置文件中定義了的數據對象。preserveDN選項使指令在簽發證書的時候讓證書主體名稱內的各項內容順序跟證書請求中的順序保持一致。
- 而在默認情況下,證書主體名稱內的各個選項順序是按照配置文件中的證書匹配策略字段的選項順序進行排列的。這個選項對于老版本的IE證書管理器是必要的,而現在則顯得很不必要了。
- 一般來說,證書的主體名稱里面可以包含E-mail項目,但是,因為E-mail可能是一個經常變動的項目,所以如果不把它放在證書主體名稱中而是放在主體別名中會更好一點。noemailDN選項可以幫你做到這一點,當證書請求中有E-mail這一項,但是你不希望在證書主體名稱中出現E-mail時,可以使用這個選項來去除。如果你還使用了證書主體別名,并使用了“email:move”或者“email:copy”策略,那么使用該選項后指令會自動將證書請求中的E-mail項目移動到證書主體別名中。
- 缺少 md 和 msie_hack
CA證書和私鑰選項cert,keyfile,keyform,passin和key
- 在簽發證書的時候,需要使用CA的證書和私鑰對用戶的證書請求進行簽發證書操作。默認情況下,證書和私鑰文件都是通過配置文件的CA主配置字段的certificate和private_key兩個選項決定的。
- 不過,OpenSSL的ca指令提供了cert和keyfile選項讓用戶能夠選擇另外的證書和私鑰文件作為簽發證書的CA證書和私鑰文件。或許你很難想像這種特殊的需要,為什么不使用預先設置好的證書和私鑰文件呢?但是,至少在測試的時候,我們需要這些靈活的選項。事實上,這些選項不僅僅可以用于測試,因為CA的指令不僅僅用于簽發證書,還可以用于吊銷證書和發布CRL,某些時候,發布CRL的角色跟CA的角色可以是不同的,即需要使用不同的證書來完成證書簽發工作和生成CRL的工作,但是它們都使用同一個ca指令,所以這些選項就能派上用場了。cert選項的參數是一個可以包括路徑的文件名,文件里面是一個PEM編碼的X.509證書文件。
- keyfile選項的參數也是一個可以包括路徑的文件名,不過,該文件里面可以包含的私鑰格式就比證書文件豐富多了。目前來說,支持的編碼格式包括PEM編碼格式、DER編碼格式、PKCS#12編碼格式、Netscape編碼格式、舊版本的IISSGC編碼格式及ENGINE格式。當然,OpenSSL指令不能自動識別這些格式,必須使用keyform選項指定某種具體的格式。
- pasin選項給定了讀取私鑰文件的時候需要提供的口令,當然,跟我們所熟悉的一樣,提供口令的方式可以是多樣的,比如從指令直接輸入、從環境變量獲取或者從文件獲取,等等。
- key選項是一個老選項,其作用是直接從指令輸入一個口令,其功能可以被“-pasinpass:”選項所替代。
證書吊銷選項revoke,crl_reason,crl_hold,crl_compromise和crl_CA_compromise
- revoke選項讓你能夠輕松地吊銷一個證書,其參數就是你需要吊銷的證書文件名,revoke選項吊銷的證書應該是PEM編碼的X.509證書。
- 當然,僅僅這樣吊銷可能還滿足不了你的管理需求,某些情況下,你甚至希望告訴所有用戶為什么要吊銷這個證書以證明你是正確的。那么,使用crl_reason選項吧,crl_reason選項的參數是CRLv2版規定的一些吊銷理由
- 如表所示。
- 上述的吊銷參數對大小寫是不敏感的。如果在吊銷操作的時候使用了這些吊銷參數,那么生成的CRL就是v2版本的,如果所有吊銷證書操作都沒有使用任何參數,那么生成的CRL將是v1版本的。
- 當你希望使用certificateHold碼作為吊銷一個證書的理由時,還可以使用凍結指示代碼擴展,這可以通過使用crl_hold參數來添加。
- 目前,crl_hold支持的參數包括holdInstructionNone,holdInstructionCalIsuer和holdInstructionReject。
- crl_hold選項使用后,設置證書吊銷碼為certificateHold,并且用其參數設置凍結指示代碼擴展項。
- crl_compromise選項使用后,將證書吊銷原因設定為keyCompromise,其參數表示私鑰泄密的時間。它的參數是符合“YYYYMMDDHHMMSSZ”格式的時間。其中“YYYY”代表4位的年份,而其他位跟startdate選項的參數代表的意義一樣的。crl_CA_compromise選項使用后,將證書吊銷原因設定為CACompromise,其參數表示私鑰泄密的時間。它的參數格式跟crl_compromise格式一致。
- 上述的crl_reason,crl_hold,crl_compromise和crl_CA_compromise只要同時使用一項即可,如果同時使用了多項,那么在指令中最靠后的一個將是有效的,而前面的都視為無效。
CRL生成選項gencrl,crldays,crlhours和crlexts
- 執行完證書吊銷操作后,證書庫中相應的證書記錄會更新,但是,對于離線的應用驗證程序而言,還是沒有辦法知道被吊銷的證書的序列號。為了讓所有證書用戶及時得到吊銷證書的消息,CA必須及時生成和發布CRL。
- gencrl選項用于生成一個CRL,并將生成的CRL使用PEM編碼輸出到out選項指定的文件,如果沒有使用out選項,則輸出到標準輸出設備。為了保證CRL能及時反映證書庫的更新信息,CRL也必須不斷定期或者不定期更新,最好的方法就是,當發布一個CRL的時候,同時限定該CRL的有效期,那么到了有效期之后,用戶就必須下載新的CRL來使用。CRL更新的間隔時間可以根據需要選擇,如果是非常重要的證書應用系統,并且用戶數量比較大,那么單位時間內執行吊銷操作的可能性就大,這時候可以將CRL的更新時間設置得短一點。反之,如果系統用戶數量不多,證書應用系統的安全性也不是要求特別高,那么更新時間可以設置得稍微長一點。
- crldays和crlhours選項跟gencrl選項一起使用以設置CRL的更新時間。默認情況下,如果沒有使用crldays選項或者crlhours選項,指令會從配置文件的CA主配置字段的default_crl_days或者default_crl_hours選項讀取默認值。crldays以“天”為單位設置CRL的有效期,而crlhours則以小時為單位設置CRL有效期,這兩個選項可以一起使用,比如你要設置CRL的有效期為5天12個小時,那么可以設置crldays的參數為5,而crlhours為12。crlexts指定了生成CRL的時候使用的擴展項定義字段,其參數為字段名稱。CRL擴展項字段是在OpenSSL配置文件中定義的。如果定義了CRL擴展項字段,即便該字段是空的,生成的CRL也將是v2版本的。如果沒有提供CRL擴展項字段,則將生成v1版的CRL。
證書管理選項status和updatedb
- status選項用來查看證書庫中指定證書的狀態,比如是否有效、吊銷或者過期等。該選項的參數是證書序列號。
- updatedb選項用來更新文本數據庫的證書狀態,它主要用來更新證書庫中已經過期的證書的狀態信息。通常情況下,即便證書已經過了有效期,如果不使用這個選項,OpenSSL的ca指令也不會自動更新證書庫中相應證書條目的狀態,所以需要使用這個選?項來自動更新證書庫的狀態信息。
engine選項
- engine選項告訴ca指令盡可能使用Engine設備提供的加密函數和算法替代OpenSSL本身的函數。對于ca指令來說,可能替代的算法包括:簽名時使用的信息摘要算法、簽名時使用的私鑰加密算法、驗證證書請求中的數字簽名時使用的公鑰解密算法、隨機數函數及私鑰數據。
- engine選項對于使用硬件加密設備中的私鑰作為CA的私鑰具有重要的意義,因為硬件中的私鑰一般是不能導出的,從而能夠增加CA私鑰的安全性。當然,這需要相應Engine接口的支持。
notext,batch和verbose選項
- 使用ca指令簽發完一個證書的時候,你是不是經常發現大部分版本的Windows都不能正確解釋你的PEM編碼的證書文件?事實上這是因為OpenSSL的ca指令在簽發證書的時候,同時將證書的明文解析信息輸出到了保存編碼證書的文件前面,從而導致這些不怎么標準的Windows程序解碼失敗(WindowsServer2003已經解決了這個問題)。
- 解決這個問題很簡單,在簽發證書的時候使用notext選項,那么指令就不會輸出明文信息到證書文件。
- 使用batch選項后ca指令以批處理方式工作,在這種方式下,ca指令不提示用戶輸入任何信息而直接簽發所有輸入的證書請求。
- 使用verbose選項將會輸出更詳細的一些操作過程信息
例子
?在證書中添加擴展項
- 先前介紹了怎么在證書請求中增加自定義的擴展項。但是,證書請求中增加了擴展項,并不等于簽發的證書就會自動增加擴展項。事實上,從嚴格意義上說,證書請求應該是用戶生成的申請文件,也就是說,其所有內容基本上都是代表了用戶的意愿,并不能由此推斷CA的策略。所以,為了使證書中能夠順利增加擴展項信息,我們還需要在CA指令的配置文件上做一些工作。你可能已經可以想像得到,我們的證書擴展項工作同樣需要在OpenSSL的配置文件中完成。首先,請確認你已經在OpenSSL配置文件opensl.cnf中增加了擴展項的OID,即以下信息:
- 注意,如果證書請求指令(req)使用的配置文件跟證書簽發指令(ca)使用的配置文件不相同,必須確保上面的信息在兩個配置文件中都存在并且一致。
- 下面,找到配置文件中的CA策略配置字段,如在openssl.cnf文件中是policy_match或者policy_anything字段,在其中增加新增擴展項:
?
- 當然,跟其他DN字段信息一樣,新增擴展項的匹配策略也可以根據CA的需要調整為optional或者match等。
- 完成上面的配置之后,保存配置文件,并使用該配置文件簽發證書,就可以生成增加了擴展項的證書。當然,上述配置方法使得擴展項信息是增加在證書主體名稱中的。
簽發用戶證書
- 先前介紹了怎么申請一個終端用戶證書,即怎么使用OpenSSL的req指令生成一個終端用戶證書請求。同樣,簽發什么類型的證書事實上是由CA決定的,也就是說,即便生成了一個有效的終端用戶證書請求,但是如果接受申請的CA不簽發終端用戶證書,或者,甚至因為錯誤配置導致簽發了CA證書,都是可能發生的。
- 可以通過在OpenSSL配置文件中的X.509v3擴展項字段告訴ca指令簽發用戶證書。ca指令在使用默認的openssl.cnf作為配置文件的情況下,使用的X.509v3擴展項字段是user_cert字段。
- 在openssl.cnf文件中找到該字段,確保basicConstraints選項的參數如下:?證明頒發的是終端證書
- ?當然,默認情況下一般就是如此。使用該配置文件簽發的證書就是一個終端用戶證書。如果你使用的是自己定義的另外的X.509v3擴展字段,那么也只需要保證上述的basicConstraints選項值為CA:FALSE,就可以成功簽發一個終端用戶證書了。使用自定義的字段的方法就是在ca指令中使用extensions選項,當然,也可以通過修改配置文件中CA主配置字段的x509_extensions選項的值來實現。事實上,當OpenSSL的ca指令使用默認的openssl.cnf作為配置文件的時候,其簽發的證書總是終端用戶證書
簽發下級CA證書
- 如果你正在為一個大型的跨區域企業或者政府部門建立一個CA系統,那么你可能需要建立一個多級的CA體系,這就涉及簽發下級CA證書的問題。從技術上來說,一個CA證書和一個用戶證書并沒有本質區別,它們的數據項是基本相同的,格式也是相同的,一個下級CA證書的合法性也是通過上級CA的數字簽名來保證和證明的。事實上,區別普通終端用戶證書和CA證書的唯一標記就是X.509v3擴展項字段中的選項basicConstraints。如果該選項值為CA:FALSE,則表示證書是普通的終端用戶證書;如果該選項值是CA:TRUE,則表示該證書是CA證書。
- 在OpenSSL的默認配置文件opensl.cnf文件中已經存在一個簽發CA證書的X.509v3擴展字段v3_ca。
- 將該字段的basicConstraints設置為如下格式:
- 當然,你還可以使用自己定義的X.509v3擴展項字段,其使用方法是相同的。
- 通過上面這些介紹,你就可以使用OpenSSL的指令順利簽發一個下級CA證書,從而建立整個證書域的分級管理,對于大型的企業或者機構來說,這非常方便?
例子 建立多級CA
- ?在完成這些步驟的整個過程中,使用的OpenSSL指令只有req和ca兩個,并且參數形式基本是相同的。此外,還需要配置OpenSSL的配置文件。
建立rootCA
- 建立RootCA技術上抽象的任務有三部分:建立一個CA目錄結構、生成一個自簽名根證書和修改配置文件。
- 為了管理方便,我們選定RootCA的根目錄在C盤。首先,在C盤根目錄創建一個名為“RootCA”的目錄。從編譯好的OpenSSL目錄中復制“openssl.exe”程序,“opensl.cnf”和ca.pl文件到“C:\RootCA”目錄下。
- 打開Windows的指令行界面,進入到“C:\RootCA”目錄,執行下面的指令:
- 根據其提示步驟完成整個操作流程,就可以成功在C:\RootCA目錄下創建一個demoCA目錄。執行ca.pl腳本指令的過程中,會提示產生自簽名的根證書,可以忽略。下面我們使用req指令來生成一個使用2048位密鑰的自簽名根證書作為RootCA的證書。
- 首先執行如下指令啟動OpenSSL.exe程序進入OpenSSL的運行環境。?
- ?然后,將文件rootca_cert.pem重命名為cacert.pem,復制到“C:\RootCA\demo.CA”目錄下取代原來的文件;將文件rootca_key.pem重命名為cakey.pem,復制到“C:\RootCA\demoCA\private”目錄下取代原來的同名文件。這就完成了RootCA證書和其相應私鑰的設置。
- 為了使RootCA能夠同時簽發普通用戶證書和下級CA證書,很多時候我們還需要對OpenSSL配置文件(C:\RootCA\opensl.cnf)進行一些配置,但是,由于OpenSSL默認的配置文件本身已經具有了兩個不同的X.509v3擴展字段用于簽發用戶證書(usr_cert)和簽發CA證書(v3_ca),所以在這里不需要再做更多的配置。當然,在實際的應用中,可能還需要對其他一些擴展項和匹配策略等配置信息進行修改。到此為止,我們已經成功建立了一個RootCA,是不是很簡單?
建立SubCA
- SubCA是RootCA的下級CA,它的證書的合法性需要由RootCA簽名來證明。建立一個SubCA的簡要步驟如下
- SubCA跟RootCA是兩個不同的CA,在實際情況下,它們一般不在同一個計算機內運行,但是,大家都應該明白,這里只是一個演示操作,所以我們選定在C盤根目錄下建立一個名為“SubCA”的目錄作為SubCA的主目錄。然后,跟建立RootCA一樣,從編譯好的OpenSSL目錄中復制“opensl.exe”、“opensl.cnf”和ca.pl文件到C:\SubCA目錄下。
- 打開Windows的指令行界面,進入到C:\SubCA目錄,執行下面的指令:?
- 根據其提示步驟完成整個操作流程,就可以成功在“C:\SubCA”目錄下創建一個demoCA目錄。這樣,SubCA的目錄結構就建好了,但是SubCA還沒有合法的經過RootCA簽名的證書和相應的密鑰,緊接下面的步驟就是完成這個任務。SubCA的證書跟普通證書是基本相同的,除了其X.509v3擴展項的某些選項的限制有一些區別。首先,為了向RootCA申請一個CA證書,需要生成一個密鑰對和證書請求。因為要申請的是一個CA證書,所以證書請求的X.509v3擴展項跟普通證書請求有區別,我們通過修改OpenSSL的配置文件來達到這一目的。
- 用文本編輯器打開C:\SubCA\openssl.cnf文件,修改其中v3_req字段的basicConstraints選項為下面的值:?
?
- 這個指令生成了一個2048位的密鑰對作為SubCA的密鑰,并同時生成了一個相應的證書請求。私鑰保存在文件subca_key.pem中,而證書請求保存在subca_req.pem中。為了獲得合法的CA證書,需要將證書請求提交給RootCA簽發,提交的途徑是多樣的,可以通過網絡連接提交,也可以通過遠程數據庫提交,而在這里,我們只需要將subca_req.pem文件復制到C:\RootCA目錄下就可以了。?
- 上述的操作只是簡單地使用新簽發的證書和其相應私鑰替換原來demoCA目錄下的證書文件和私鑰文件,從而完成SubCA證書和私鑰的設置。SubCA并沒有下級的CA,所以在OpenSSL配置文件中只要設定一個簽發普通用戶證書的X.509v3擴展字段即可。幸好,OpenSSL默認的配置文件已經設置好,我們不需要費神再去配置它。RootCA和SubCA都已經配置好了,現在可以簽發用戶證書了。?
簽發用戶證書A
- 結構顯示,用戶證書A是RootCA簽發的普通用戶證書,所以我們首先在指令行界面下到C:\RootCA目錄下,啟動openssl.exe程序。生成一個用戶證書事實上包含三個部分:生成密鑰對、生成證書請求及簽發證書。在這里,我們使用req指令完成第一和第二個部分,使用ca指令完成第三部分。
- 普通用戶證書的密鑰對一般使用1024位密鑰就可以了,可使用下面的指令生成密鑰對和證書請求:
- ?根據配置文件“C:\RootCA\opensl.cnf”的配置,ca指令默認X.509v3擴展項使用的是用于簽發普通用戶證書的usr_cert字段,所以我們執行下面的ca指令即可簽發用戶證書A:
- 執行完上述指令后,用戶A就擁有了一個合法的RootCA簽發的證書A和相應的私鑰,分別保存在C:\RootCA\userA_cert.pem和C:\RootCA\userA_key.pem文件中。?
簽發用戶證書B
- 用戶證書B的申請和簽發跟用戶證書A的申請和簽發基本相同,只是,因為用戶證書B是SubCA簽發的證書,所以應該在指令行界面下進入“C:\SubCA”目錄并啟動opensl.exe程序。然后,執行下面的兩條指令完成用戶證書B的申請和簽發:
- 執行完上述兩條指令,用戶B就擁有了一個合法的SubCA簽發的證書B和相應的私鑰,分別保存在C:\SubCA\userB_cert.pem和C:\SubCA\userB_key.pem文件中。到此為止,就完成了上述CA目錄結構的構造任務。整個過程使用的指令非常簡單,只有req和ca兩個。
證書使用
X.509證書
x509指令功能概述和格式
- x509指令是一個功能強大的指令,甚至超出了其名稱所涉及的范圍,它既可以以各種方式顯示一個證書的內容,也可以對一個證書的格式進行各種有趣的轉換,甚至可以簽發證書等。
- 下面是x509指令的格式和選項:
輸入和輸出格式選項inform,outform,keyform,CAform和CAkeyform
- ?inform選項指定了in選項所指定的輸入文件的格式,輸入的文件可能是證書,也可能是證書請求文件(當使用了req選項的時候)。無論哪種文件,該選項可以接受的格式包括PEM、DER編碼和老式的Netscape的編碼格式。
- CAform跟inform參數的意義相類似,不過它指定的是CA選項所指定的輸入文件的格式。
- outform則指定了out選項輸出的文件格式,但是,并非所有的內容都會受到這個選項的影響,僅輸出文件是證書或者證書請求文件的時候會受到該選項的影響。目前,支持的格式同樣包括PEM、DER和NET格式。
- keyform選項指定了signkey選項指定的輸入私鑰文件的格式,支持PEM、DER和ENGINE三種格式,其中ENGINE是指通過第三方驅動設備提供的私鑰。
- CAkeyform的參數意義跟keyform相同,不過,它相關的文件是選項Cakey所指定的文件。
輸入和輸出選項in,out,CA和CAkey
- in選項指定了輸入的證書文件的路徑,如果使用了req選項,則輸入文件將被視為是一個證書請求文件而不是證書文件。
- 文件的編碼格式由inform參數決定。默認情況下輸入是標準輸入設備。
- out選項指定了接受輸出的文件的路徑,默認情況下,輸出目標是標準輸出設備。如果輸出的是證書或者證書請求,則其輸出格式由outform參數決定。
- CA選項指定了在簽發證書或者轉換證書格式的時候需要的CA證書文件路徑。其格式由CAform參數指定。
- CAkey選項則指定了簽發證書或者轉換證書格式的時候需要使用的CA證書相對應的私鑰文件路徑,如果使用的私鑰是Engine提供的,則是一個Engine的索引文件,如公鑰文件等,根據具體的Engine私鑰索引方法具體決定。普通的私鑰文件格式由CAkeyform參數決定。
輸入口令選項passin
- passin參數給出了當使用signkey輸入私鑰文件時需要提供的口令字符串。在使用CA證書的私鑰簽發證書的時候,則給出的是使用CAkey選項輸入私鑰文件時需要提供的口令字符串。一般來說,signkey選項與CAkey選項是不會同時出現的。輸入口令的方式可以是多樣的。如果沒有使用該選項,而指定的私鑰又要求提供解密口令,那么指令會在指令行提示用戶輸入口令。
輸出顯示內容選項serial,hash,subject,isuer,email,purpose,modulus,fingerprint,ocspid,startdate,enddate,dates,pubkey,C和nout
輸出證書更加靈活的內容的選項text和certopt
- 使用text選項,就可以看到證書的內容
- certopt選項可以幫助選擇所需要的東西。certopt選項一般只有出現text選項的時候才使用,它的參數值很多,可以同時提供一個或者多個,如果是多個,它們之間要使用分號分開。certopt選項還可以在指令中多次使用,這可以讓你更隨意地更改你的想法。certopt的參數具體意義詳見表10.3,但參數no_attributes在certopt選項中是無效的。?
證書信任設置選項trustout,addtrust,clrtrust,addreject,clreject,setalias和alias
- 這些選項都是對可信證書擴展字段進行設置的選項。事實上,所謂的可信證書就是普通的證書加上一些擴展字段,這些字段定義了該證書可以用來做什么和不能用來做什么,并定義了證書的別名。
- 一般來說,在進行證書驗證的過程中,證書鏈中至少有一個證書應該是“可信證書”,否則就不能完成驗證過程。默認情況下,必須在本地保存一個可信證書,并且該可信證書應該是一個根CA證書,這種情況下,任何一個結束于該可信根CA的證書鏈上的證書可以用于指定用途。事實上,現在OpenSSL并沒有要求那么嚴格,如果一個根證書沒有可信選項,那么它就默認該證書是一個可以用于任何用途的可信證書。
- 目前OpenSSL的版本僅在根CA上支持可信選項設置,從而實現在最終的CA上統一控制證書的用途,比如允許CA頒發的證書用于SSL客戶端驗證或者SSL服務器驗證等。當然,OpenSSL的開發組承諾在以后的版本中將支持在所有證書中設置可信選項,而不僅僅限于根證書。下面回到x509指令的顯示世界中來,讓我們看看這些選項的具體含義和用法。
- trustout選項是最容易明白的一個選項了,它會在輸出的證書中加上可信的標記,從而使其成為一個可信證書。x509指令可以接受的輸入包括可信證書和普通的X.509證書,但是,如果沒有trustout選項,默認情況下輸出的證書都會把可信選項去掉,成為普通的X.509證書。當然,如果你通過其他選項設置或者修改了證書的可信選項字段,那么會自動輸出一個可信證書。
- 設置證書的信任選項在OpenSSL的指令中顯得很簡單,使用addtrust選項就可以設置可信證書的用途,你可以在這里使用任何有效的參數,但是目前真正使用的參數僅僅包括clientAuth,serverAuth和emailProtection。其中,clientAuth參數表示用于SSL客戶端驗證,serverAuth參數表示用于SSL服務器驗證,而emailProtection參數則用于S/MIME郵件的保護。
- 相反,clrtrust則將清除證書中所有可信選項的用途設置。
- 相反,如果你想禁止證書用于某種用途,那么可以使用addreject選項,該選項的參數內容和addtrust相同。
- 而使用clrreject則可以清除所有設置好的禁止用途選項。我們猜你不會喜歡用一個證書的序列號來記憶或者標識一個證書,雖然實際的計算機系統是如此的,但畢竟人跟計算機還存在一些區別。
- 那么我們的證書設計者充分利用了以人為本的設計理念,提供了一種定義證書的名稱的方法,即證書的別名,setalias選項就是為了讓你擁有這種自由。證書別名通常是一個好記的字符串,比如“OpenSSL‘sCertificate”,等等,看著比“0x00cd0e”愉快多了是不是?
- alias則事實上只是一個輸出選項,使用該選項,輸出的內容中就會包括證書的別名了。
證書簽發轉換選項signkey,clrext,req,x509toreq,days,set_serial,CAserial,CAcreateserial,extfile和extensions
- 首先來看看signkey選項,這個選項指定了輸入的保存私鑰的文件路徑。這個選項使用后,會將輸入的證書文件或者證書請求文件轉換成一個自簽名的證書。如果輸入的是證書文件,那么x509指令會執行下面的操作:
- 1 使用證書所有者名稱替代證書簽發者名稱;
- 2 更改證書有效期,其中生效期從當前時間開始,結束日期取決于days選項,而其他擴展項和內容都會保留,如果你想清除這些過時的擴展項,那么就需要使用clrext選項;
- 3 使用signkey提供的私鑰重新簽發證書。
- 但是如果在使用signkey的時候同時使用了x509toreq選項,過程則與上面不一樣,signkey提供的私鑰將會被用來對生成的證書請求進行簽名。如果輸入的是證書請求文件,事情就很簡單,簽發一個自簽名證書即可,簽發者名稱當然跟證書持有人名稱一致。
- 通過上面signkey的介紹,clrext選項的功能大家已經有所了解,事實上clrext選項僅當x509指令通過一個證書創建另一個證書的時候有意義。也就是說,僅當輸入是證書,并且使用signkey或者CA選項創建一個新的證書的時候,clrext選項會將原來證書中的擴展項全部清除,否則,默認情況下所有擴展項都會被保留下來形成新證書的一部分。
- 一般情況下,x509指令會認為輸入選項in輸入的是一個證書,如果你想輸入的是一個證書請求,那么使用req選項就是通知x509指令的唯一途徑。有些情況下,一些特殊需要總是會出現的,比如將一個證書轉換成證書請求,這時候x509toreq選項就能幫助你達到這個目的。這功能看起來或許有些奇怪,但是在證書到期續簽的時候可能就有些用處了。使用這個選項的時候,需要使用signkey選項提供相應的私鑰在生產證書請求的時候進行數字簽名。
- 簽發證書的時候需要指定有效期,days選項就定義了有效期的長短,默認情況下,x509指令證書簽發的有效期是30天。我們知道證書都有一個序列號,這個序列號就像你的身份證號碼一樣獨特而重要,ca指令是通過文本數據庫中的serial文件來保存確定的。而在x509指令中,則可以有多種方法確定一個將要生成的證書的序列號。首先最直接的是可以使用set_serial選項來直接指定序列號,該方法優先級是最高的,如果使用了該方法,后面的兩種方法即便在指令中使用了也會被忽略。
- 其次是可以使用CAserial選項指定序列號文件來提供序列號,事實上,所謂序列號文件事實上是一個僅包含一個十六進制正整數的文件。使用CAserial選項后,指令會自動將該序列號文件中的整數加1并保存回文件,默認情況下,x509指令的序列號文件名稱為證書文件名稱加上.srl后綴,比如輸出的證書文件名為certpem,那么指令會試圖從文件cert.srl中獲取序列號。最后,如果你這個文件也沒有(其實你真的可以自己用文本編輯器編一個),就使用CAcreateserial選項生成一個證書序列號文件,該序列號文件保存的是2,而所簽發的證書序列號是1,這時候你可以打開這個序列號文件好好研究一下了。
- 有時候在證書中需要加入擴展項,這時候可以使用extfile選項,extfile選項指定的是一個擴展項配置文件。指定擴展項定義文件之后,
- 可能還需要使用extensions指定使用的擴展字段,因為一個擴展項配置文件中可能存在多個擴展字段,如果不使用該選項,那么需要加入的擴展項應該定義在文件的默認字段(未命名字段)或者默認字段中應該包含一個名為extensions的變量來指明擴展項所在的字段。
證書顯示名稱格式選項nameopt
- 利用nameopt的參數,完全可以顯示所有人和簽發者的中文信息,包括名稱、單位和城市,等等。首先,我們需要一個能夠輸入中文的控制臺終端,比如普通的中文Windows指令行界面。在該控制臺可以按照正常的req指令生成一個證書,其用戶信息用中文填寫完成,從而得到一個中文的證書。如果你直接使用下面的指令,
驗證證書是否過期
- 選項checkend這個選項非常簡單實用,目的就是驗證輸入的證書是否在有效期內。如果本選項返回0,說明輸入的證書沒有過期,如果返回是1,則說明證書過期了
信息摘要算法選擇選項md5,md2,sha1和mdc2
- 對于這些名詞,大家應該已經非常熟悉了,它們是進行信息摘要時可能用到的四種算法,在前面章節有對于這幾種算法的詳細介紹。信息摘要算法在證書中主要是用于CA頒發證書簽名的時候,具體到x509指令來說,如果信息摘要算法變化了,對于前面介紹的-fingerprint,-signkey和-CA等證書信息的輸入輸出選項的結果都會有影響。在x509指令里,如果沒有特別指定,默認使用的是MD5算法。由于DSA算法固定使用SHA1算法作為數字簽名的信息摘要算法,所以如果你使用DSA密鑰進行數字簽名,則SHA1的使用將是固定不變的,這些選項也就沒有任何使用的必要。
engine選項
- engine選項告訴x509指令盡可能使用Engine設備提供的加密函數和算法替代OpenSSL本身的函數。對于x509指令來說,可能替代的算法包括:簽名時使用的信息摘要算法、簽名時使用的私鑰加密算法、驗證證書請求中的數字簽名時使用的公鑰解密算法、隨機數函數及私鑰數據等。?
例子
-
查看一個證書的內容
CRL
- 當證書被CA吊銷時,它將被添加到該CA的證書吊銷名單中,CA中心必須定期發布更新吊銷列表(CRL),以保證所有CA相關的應用都能及時得知證書的有效性信息。所謂CRL,事實上就是一系列已經被吊銷的證書序列號組成的文件,并且為了確保該文件的真實性,該文件經過了CA的合法簽名。一般來說,CRL都具備有效期限制,其有效期由CA決定,可能是一天、一周或者一個月等,當然,有效期越長,其跟實際情況相差的可能性越大。
- CRL的頒發和公布都是由CA定期進行的,發布的方式是多種多樣的,可以是在網上發布或者通過E-mail發布,無關緊要。CRL的使用者是所有使用該CA簽發證書的系統和用戶,他們需要隨時獲取最新的CRL,并在進行證書驗證的時候查看該CRL,確定接收到的證書不在該CRL列表內(如果在該列表內,則證書就是無效的了)。
crl指令功能概述和格式
- OpenSSL提供了crl指令用于顯示、處理和驗證CRL文件信息,而發布CRL文件則在前面介紹的CA指令中可以實現。
- 下面是crl指令的格式和選項:?
輸入和輸出格式選項inform和outform
- inform和outform選項指定了輸入和輸出文件格式,相對應于in和out選項,可以接受的格式包括PEM和DER編碼格式,默認接受的格式是PEM。
輸入和輸出選項in和out
- in選項指定了輸入的CRL文件的路徑,文件的編碼格式由inform參數決定。默認情況下輸入的是標準輸入設備。
- out選項指定了接受輸出的文件的路徑,默認情況下,輸出目標是標準輸出設備。其輸出格式由outform參數決定。
輸出顯示內容選項hash,issuer,noout,text,lastupdate,nextupdate和date?
- hash選項顯示CRL文件中CA簽名的HASH值。
- isuer選項顯示CRL文件簽發者信息,一般來說,就是CA的信息。
- noout選項要求指令不輸出編碼CRL的內容。
- text選項要求指令輸出CRL文件的可理解的形式,也就是說,能夠讓你一看就懂的形式。
- lastupdate和nextupdate選項分別顯示CRL文件的最近更新時間和下次更新時間,
- 而使用date選項則同時顯示上述兩種時間。事實上,所謂下次更新時間,也就是本CRL文件失效的時間。
輸出字符編碼選項nameopt
- nameopt選項指定了如何顯示主體名稱和簽發者名稱,主要用于顯示名稱中不同編碼的內容。沒有使用該選項時,默認使用的是“oneline”參數。該選項可以同時使用多個參數,每個參數間使用“,”分開即可。具體的參數可以參照表10.4。
CA文件和目錄選項CAfile和CApath
- CAfile指定一個CA證書文件,該CA證書用于核實CRL中的簽名是否正確和有效。
- CApath則告訴指令從一個目錄中查找有效的CA證書,此目錄必須是標準證書目錄,所謂標準目錄,即OpenSSL要求的基于文件HASH值為文件名排序的一個目錄,詳見x509指令的介紹。
簡單的例子
- 把CRL文件的格式從PEM轉化成DER:
?PKCS#12證書
- 事實上,除了Microsoft的產品,Netscape的瀏覽器也需要PKCS#12格式證書的支持。基于此,OpenSSL除了在一般的指令中對PKCS#12證書提供支持,還開發了專門用于處理PKCS#12證書的指令pkcs12,用于PCKS#12證書的生成、解釋和驗證等。
pkcs12指令功能概述和格式
- pkcs12指令功能總體來說可以分成創建PKCS#12證書和解釋PKCS#12證書。
- 創建PKCS#12證書即將普通的X.509證書和私鑰封裝成PKCS#12證書;
- 解釋證書可以將PKCS#12證書轉換成X.509證書,并提取出相應的私鑰,并可以輸出其他必要的信息。
- 一般來說,PKCS#12證書的私鑰是經過加密的,密鑰由用戶提供的口令產生。所以,在使用pkcs12指令編碼或者解碼PKCS#12證書的時候,一般都會要求用戶輸入密鑰口令。
- 下面是pkcs12指令的格式和選項:
- 需要把PKCS#12證書轉化成X.509證書時,僅僅用-in和-out選項就可以完成了。如果你想把X.509證書和其私鑰封裝成PKCS#12證書,再增加-export一個選項即可輕松完成。
- 當然,如果你需要更加具體復雜的要求,你需要了解的指令選項也會多一些。?
輸入和輸出文件選項in和out
- 默認情況下,輸入和輸出指定的都是標準輸入輸出設備。
- 在解釋PKCS#12證書的時候,即沒有使用-export選項的時候,
- in選項的參數默認情況下是一個PKCS#12格式的文件,它將被解釋為單獨的證書和私鑰,并總是以PEM格式寫入到out選項指定的輸出文件中。
- 在創建PKCS#12證書的時候,out選項參數輸出的是一個PKCS#12格式的證書文件。in選項輸入的文件是包含一系列證書和私鑰的文件。這些證書和私鑰必須是PEM編碼的,它們在該文件中的順序不受限制,但要求至少有一個私鑰和其相對應的證書存在。如果存在其他附加的證書,則這些證書都會被封裝到輸出的PKCS#12證書文件中。
輸入和輸出口令選項passin,passout,password
- pasin選項指定了使用輸入文件的時候需要的口令源。如果是解釋PKCS#12證書,則是該證書文件解密口令源;如果是創建PKCS#12證書,則是讀取私鑰文件時候可能需要的口令源。
- pasout選項則指定了輸出文件時進行加密的口令源。如果是解釋PKCS#12證書,則是輸出私鑰加密口令源;如果是創建PKCS#12證書,則是加密PKCS#12證書文件時可能需要的口令源。
- password選項提供的總是PKCS#12證書的加密口令源,即在解釋PKCS#12證書時,其參數為讀取PKCS#12證書需要的口令源;在創建PKCS#12證書的時候,其參數為加密PKCS#12證書需要的口令源。
- 口令源的形式多種多樣,可以是直接輸入,也可以是從文件、環境變量、標準輸入輸出等獲取
輸出內容選項noout,clcerts,cacerts,nocerts,nokeys和info
- 這些選項都是在解釋PKCS#12證書時使用的
- noout選項告訴指令不要輸出任何私鑰和證書信息到輸出文件中。
- clcerts選項告訴指令只輸出客戶證書(不是CA證書)到輸出文件中。
- cacerts選項告訴指令只輸出CA證書到輸出文件中。
- nocerts選項告訴指令不要輸出任何證書到輸出文件中。
- nokeys選項告訴指令不要輸出私鑰到輸出文件中。
- info選項告訴指令輸出一些其他PKCS#12證書文件相關的信息,如構成、算法及其迭代次數等。
加密算法選項des,des3,idea,aes128,aes192,aes256和nodes
- 這些選項僅在解釋PKCS#12證書的時候使用。
- des,des3,idea,aes128,aes192和aes256選項用于指定在輸出私鑰時,對私鑰進行加密使用的算法。默認情況下,pkcs12指令會使用des3作為加密算法。
- nodes選項則告訴指令對私鑰不進行加密處理。
nomacver和twopass
- 這兩個選項使用較少,也僅在解釋PKCS#12證書的時候使用。
- nomacver選項告訴指令在讀取PKCS#12證書之前,不需要對文件進行MAC的完整性驗證。
- twopass選項告訴指令提示輸入完整性驗證和加密需要的密碼源。
- 大多數PKCS#12軟件實現都假設這兩個密碼是一樣的,不需要使用這個選項。
創建PKCS#12證書選項export
- 該選項在創建PKCS#12證書的時候必須使用,告訴指令這時候需要創建一個PKCS#12證書,而不再是解釋一個已有的PKCS#12證書。
證書內容輸入選項inkey和certfile
- 這兩個選項在創建PKCS#12證書的時候使用。
- inkey選項指定一個包含了私鑰的文件,指令將從這個文件中讀取創建PKCS#12證書需要的私鑰。如果該選項沒有使用,則在in參數指定的輸入文件中必須包含一個私鑰。
- certfile選項指定向創建的pkcs#12證書中封裝額外的證書,這些證書存儲在該選項的參數文件中,可以是一個或者多個。
證書別名選項name和caname
- 這兩個選項在創建PKCS#12證書的時候使用。
- name選項指定了證書和私鑰的一個好記的別名,該名稱通常顯示在需要導入該PKCS#12證書文件的軟件中的證書列表中。
- caname選項用于為其他證書指定一個好記的別名,該選項可以使用多次以為多個證書指定名稱,名稱的順序跟證書出現的順序保持一致即可。該選項一般僅在IE里面有效,在Netscape軟件中則通常被忽視。
證書加密算法選項descert,keypbe和certpbe
- 這三個選項在創建PKCS#12證書的時候使用。descert選項告訴指令使用3DES算法加密證書,在默認情況下,指令使用3DES算法加密私鑰,但是使用40位的RC2算法加密證書。
- keypbe和certpbe選項分別指定對密鑰和證書進行加密的算法。雖然,所有的PKCS#5v1。5或者PKCS#12算法都是支持的,但是OpenSSL還是建議你只用PKCS#12標準中的加密算法。這些算法包括DES,3DES,RC2和RC4等。這些參數的形式諸如:
?
- 支持的具體算法和其參數形式見表11.1。
密鑰用途選項keyex和keysig
- 這兩個選項在創建PKCS#12證書的時候使用,而且僅在Microsoft的IE和其他Microsoft軟件中才有效。
- keyex選項指定密鑰和證書用于密鑰交換,
- keysig則指定密鑰和證書用于數字簽名。
- 如果僅使用keysig選項,則密鑰僅能用于進行簽字。僅用于簽名的密鑰可以用來進行S/MIME簽名、驗證碼(ActiveX控制簽名)和SSL客戶端驗證。需要注意的是,由于OpenSSL本身存在的BUG,只有IE5.0和其后的版本才能夠支持僅用于簽名用途的密鑰進行SSL客戶端驗證。
迭代次數選項nomaciter,noiter和maciter
- 這幾個選項在創建PKCS#12證書的時候使用,而且僅在你需要兼容Microsoft的IE4.0的時候需要。因為算法通常使用普通口令產生密鑰,為了降低受到字典攻擊的可能性,可以將口令進行多次迭代從而產生復雜的口令。這通常以重復密碼算法中的一部分步驟和降低速度為代價。MAC雖然一般用于驗證文件的完整性,但因為私鑰和證書也是使用與其相同的口令,所以MAC同樣存在被攻擊的可能性。通常情況下,MAC和算法的迭代次數都設置為2048次,如果使用了nomaciter和noiter選項,迭代次數將分別降為1。
- 顯然,這兩個選項大大降低了文件的安全性,所以,除非不得已,建議不要使用這兩個選項。除了IE4.0不支持MAC迭代外,大部分軟件都支持多次MAC和算法迭代。
- maciter目前來說意義不大,指明需要使用MAC迭代,目前版本這已經是默認的,只是為了兼容以前的版本該選項才沒有取消。
其他選項chain和rand
- 這兩個選項同樣在創建PKCS#12證書的時候使用。chain選項告訴指令要建立一個完整的用戶證書相關的證書鏈保存在PKCS#12文件中。指令會從一個標準的CA證書容器中尋找建立證書鏈需要的證書,如果失敗,則視為發生致命性錯誤。這個功能當然比較特殊,不過,很多時候,驗證方確實需要被驗證方提供完整的證書鏈來進行驗證操作,尤其當多級CA存在的情況下,這種要求就是常見的了。
- 隨機數文件選項rand提供了產生隨機數的參考種子文件。如果沒有提供該選項,那么程序會從標準輸出設備的狀態讀取信息作為隨機數種子。隨機數文件可以為任意類型的文件。rand選項可以支持多個文件,用分隔符隔開即可,Windows平臺使用“;”分隔,OpenVMS系統使用“,”分隔,其他系統都使用“;”分隔。
例子
PKCS#7證書
- ?PKCS#7格式的證書可以封裝X.509標準證書、相關證書鏈上的CA證書和CRL,這樣就可以直接把PKCS#7證書發給驗證方驗證,免去了把以上的驗證內容一個一個發給接收方的煩瑣了。微軟對PKCS#7證書的支持依賴文件后綴名p7,當然,OpenSSL則是從來不關心后綴名的。OpenSSL對PKCS#7協議提供了將普通用戶證書、CA證書和CRL封裝成PKCS#7格式證書的指令crl2pkcs7,此外還提供了pkcs7指令來解釋PKCS#7格式證書,下面就具體介紹一下crl2pkcs7和pkcs7指令。
crl2pkcs7指令功能概述和指令格式
- crl2pkcs7指令名不符實,并不僅僅是把CRL轉換成PKCS#7證書。其實,在OpenSSL中,該指令是唯一可以生產PKCS#7證書的指令,主要用于把CRL和一個或多個證書封裝成一個PKCS#7格式的證書。
- 并且,CRL是一個可供選擇項,即PKCS#7證書里面不一定需要一個CRL。
- crl2pkcs7指令的格式如下:
輸入和輸出格式選項inform和outform
- inform選項指出了輸入的CRL文件的編碼格式。目前只支持兩種格式:PEM和DER。
- outform選項指出了輸出的PKCS#7文件的編碼格式。目前支持PEM和DER兩種格式。
輸入和輸出選項in,out和certfile
- in選項指定了存儲輸入CRL的文件名。此選項如果不指定,默認采用標準輸入。
- out選項指定了存儲輸出PKCS#7證書的文件名,默認采用標準輸出。
- certfile選項指定的文件可以包含一個或多個證書,文件中的證書將會全部被封裝到PKCS#7證書中,這個選項也可以多次使用以加入多個證書。需要注意的是,所有的證書都應該是PEM格式編碼的。
不包含CRL的PKCS#7證書選項nocrl
- nocrl選項指定在輸出文件中不包含CRL文件。一般情況下,在輸出的PKCS#7文件中包含CRL。指定此選項后,操作過程中將不會去讀輸入文件中的CRL。
簡單的例子
- crl2pkcs7指令最常用的用法是用來生成PKCS#7證書。
- 下面就是生成PKCS#7簡單例子。
pkcs7指令功能概述和指令格式
- 查看這個包含多個X.509證書和CRL信息的文件里面的內容,OpenSSL提供pkcs7指令滿足你的這種愿望。
- pkcs7指令的格式如下:?
(1)輸入和輸出格式選項inform和outform
- inform和outform選項指定了in和out選項相關文件的格式,可以是PEM或者DER格式。
(2)輸入和輸出選項in和out
- in選項指定了輸入的證書文件的路徑,文件的編碼格式由inform參數決定。默認情況下輸入的是標準輸入設備。
- out選項指定了接受輸出的文件的路徑,文件的編碼格式由outform參數決定。默認情況下,輸出目標是標準輸出設備。
(3)輸出顯示內容選項ptint_certs,text和noout
- print_certs選項要求輸出該PKCS#7證書文件內的所有證書和CRL,該選項逐行輸出所有證書的主題名和簽名者。
- text選項要求輸出證書的所有內容。
- noout選項要求不要輸出編碼結構的PKCS#7證書。
(4)engine選項
- engine選項指定后,所指定的Engine(通過唯一的id指定)會使用Engine設備指定的庫或者硬件設備相關接口來處理本指令的一些操作。
(5)簡單的例子
?驗證證書
- 證書的結構中的關鍵內容包括:序列號、公鑰、用戶名稱、簽發者、CA 簽名和其他 一些附屬信息等。證書驗證過程就是依賴于這些信息和公鑰對應的私鑰進行。
通常的證書 驗證過程包括以下要點:
- 1確認證書內容是正確的和完整的,沒有被篡改,CA簽名是正確的;
- 2確認證書是有效的,在有效期內并且沒有被吊銷(CRL中沒有該證書序列號);
- 3確認CA證書是可以被信任的證書,如果CA證書不是根證書,還要繼續對CA證書進行驗證;
- 4通過與用戶的交互,基于證書中的公鑰和公開密鑰算法確認用戶的身份。其中,確認用戶身份的過程是基于公開密鑰算法的,基本過程如下:
- 1被驗證方發送自己的用戶證書給驗證方;
- 2驗證方提取證書中的公鑰,并產生一個隨機數Rp,使用該公鑰加密該隨機數得到加密的隨機數Re并發給被驗證方;
- 3被驗證方使用自己的私鑰解密Re得到Rep并發回給驗證方;
- 4驗證方對比Rp和Rep,如果一致,則驗證通過,否則,驗證不通過。
- 從上述的過程可以知道,因為證書中公鑰對應的私鑰僅真正的證書所有者才可能持有(理論上是這樣的,當然現實的系統和社會中不盡如此),所以如果被驗證方能夠正確解密使用該證書上的公鑰加密的信息,即可認為被驗證方確實是證書的持有人,也就可以確定其身份。
- 無論何種類型的證書,其驗證過程都是基本一致的,當然,根據具體的情況,其驗證協議和要求提供的材料可能有一些區別。關于證書驗證的更多情況,也可以參考前面。不過,在這一節,我們關心的是驗證證書的有效性,而不對證書持有人的身份真實性進行驗證。
- OpenSSL提供了證書驗證的一些指令,包括普通驗證指令和一種標準的OCSP協議處理指令。
verify指令介紹
功能概述和指令格式
- verify指令提供了證書或者說證書鏈的驗證功能,下面是verify指令的選項和格式:
- 在驗證過程中遇到什么錯誤,雖然通常情況下這時候應該算作驗證失敗,應該停止驗證過程了,但是我們OpenSSL中的verify指令還是不辭勞苦地將整個驗證過程執行完。這樣的好處是可以告訴用戶在整個證書鏈的驗證過程中存在的所有問題,而不需要用戶一個一個問題進行逐步排除。
- 為了執行驗證過程,verify指令首先做的事情是試圖從提供的所有證書里建立一個證書鏈,證書鏈從提供的用戶證書開始,而結尾應該是一個根CA證書。
- 證書鏈建立的規則是尋找當前證書的簽發者證書,如果一個證書的簽發者就是其自己,那么該證書就是根證書。
- 如果verify指令不能成功建立一個證書鏈,那么就認為驗證失敗。?
- 尋找當前證書的簽發者證書這個過程本身也是一個復雜的過程。在OpenSSL早期版本中(0.9.5a),第一個找到的持有者名稱跟當前證書簽發者名稱一致的證書,即被認為是當前證書的簽發者證書。
- 而在0.9.6和后面的版本中,所有找到的持有者名稱與當前證書簽發者名稱一致的證書,都被認為是可能的簽發者證書,需要進行進一步的驗證來確定。也就是說,除了前面的條件,當前證書的密鑰標識字段內容必須跟候選簽發者證書的密鑰標識、簽發者和序列號等相匹配,此外,候選簽發者證書的密鑰用途擴展字段也應該包含允許簽發證書的功能。
- 建立證書鏈的時候,程序首先查找不信任列表,如果找不到當前證書的簽發者證書,則開始在信任列表中查找證書。而根CA證書總是在信任列表中被找到的。如果需要驗證的證書本身就是一個根證書,那么必須在信任證書列表中找到一個完全一致的證書才能認為是驗證通過。
- 建立一個完整證書鏈后,verify程序開始檢查每一個非信任證書的擴展項是否跟purpose選項提供的參數內容相一致。當然,如果purpose選項沒有出現,則在本步驟verify指令將不進行任何操作。需要驗證的證書或者“葉子”證書其擴展項必須跟要求驗證的purpose參數一致,其他CA證書也必須是有效的證書。完成上述步驟后,verify開始檢查根CA證書的信任設置,以確定其是否支持purpose的要求。OpenSSL為了兼容以前的版本,假定如果CA證書沒有任何信任設置,則默認為支持任何用途。
- 如果你使用的是0.9.7以后的版本,很幸運,OpenSSL將支持CRL驗證的操作,這時候verify將根據CRL檢查整個證書鏈的每個證書是否有效,即沒有被管理員吊銷。最后,verify程序將檢查整個證書鏈上所有證書的有效期,根據當前的系統時間進行檢測。需要注意的是,各個證書的數字簽名也是在這個最后的時刻進行檢驗的。通過上面所有的驗證步驟,證書驗證才算成功,否則,任何一步的失敗,都意味著證書驗證不通過。
CA證書選項CApath和CAfile
- CApath選項用來指定我們信任的CA的證書存放目錄。
- 但是這些證書的名稱應該是下面這樣的格式:xxxxxxxx.0(xxxxxxxx代表證書的哈希值,可以參看x509指令的-hash選項)。
- CAfile選項用來指定我們信任的CA證書文件,其中可以包含多個CA證書。目前只支持PEM格式的文件
非信任證書選項untrusted
- untrusted選項用來指定非信任證書文件,同樣,該文件可以包含多個PEM格式的證書。
- 所謂非信任的證書文件,一般是指在構造證書鏈的時候需要使用的CA證書,但一般都不是根證書。你千萬不要以為這是不被信任的證書。通常,CRL也可以通過這個選項指定的文件輸入到verify驗證過程中。
證書用途選項purpose
- 此選項主要驗證證書的擴展字段,顯示證書的用途。如果沒有設置此選項,那么verify將不會對證書鏈進行驗證操作。
- 目前,purpose支持的參數包括:sslclient,sslserver,nssslserver,smimesign和smimeencrypt。
驗證選項isuer_checks,crl_check,crl_check_al和ignore_critical
- issuer_checks選項告訴指令輸出在查找簽發者證書過程中的詳細信息,從而可以知道每個候選簽發者證書被拒絕的原因。
- crl_check選項告訴指令檢查被驗證證書的CRL,如果不幸CRL中存在被驗證證書的序列號,則證書將不能通過驗證。CRL通過untrusted選項的參數輸入
- crl_check_all選項告訴指令檢查證書鏈中所有證書的CRL,即不僅僅要對被驗證證書是否被吊銷進行驗證,還要對整個證書鏈中其他證書是否被吊銷進行驗證
- ignore_critical選項告訴指令可以忽略一些比較少用的擴展項,即如果該擴展項指令沒有處理的話,則忽略。
如何輸入被驗證的證書?
- 在verify指令中,在指令所有參數最后面輸入要驗證的證書文件名即可指定需要驗證的證書。如果有多個證書文件需要驗證,可以以空格為間隔一起列在后面,但是這些證書都應該是PEM格式的數字證書。如果不提供證書文件,則指令將試圖從標準輸入中讀取被驗證的證書。
- 使用verbose選項,指令將把驗證過程中的所有詳細過程輸出。
- engine選項用來指定可以用于替代OpenSSL的函數庫的其他算法庫或者硬件,詳見前面章節。
診斷證書驗證結果
- 如果驗證操作有問題,OpenSSL提供了一些輸出來讓我們弄明白到底出現了什么問題,雖然這些信息看起來有些難懂,不過還是有用的。診斷信息輸出格式如下:?
- 第一行說明哪個證書文件出問題,后面是其證書的主題。
- 第二行說明錯誤號,驗證的深度,并給出錯誤的解釋,雖然這些解釋不甚明了。其中,驗證深度是從0開始計算的。
- 表10-6給出了錯誤號及其描述的詳細說明。需要注意的是,有的錯誤雖然有定義,但沒用使用,這里用unused標識。?
?例子:
- verify指定的選項應該是較少的,用起來也非常簡單。只需要按上述的各個選項的操作進行。下面是證書certpem驗證的例子,此證書用根證書cacert.pem生成:
在線證書狀態服務協議指令 OCSP
- 在許多情況下,需要驗證證書真實性的人(當然也可能計算機或者程序)并不能完成證書驗證的過程,也就是說,必須提供一種手段或者服務,能夠幫助完成證書驗證的需要。這就是為什么OCSP協議(OnlineCertificateStatusProtocol),即在線證書狀態協議會出現在我們面前的原因。
- OCSP協議使得普通證書應用程序可以通過服務方式知道一個特定證書的(吊銷)狀態,從而使得普通程序不需要了解證書驗證的細節和實現方式。OCSP接受一個客戶端發來的證書驗證請求信息(通常是以HTTP協議發出),然后OCSP查詢證書庫的狀態。
- 當然,用戶請求里面只是包含了證書的一些關鍵信息,而并不需要一個完整的證書。根據結果,OCSP響應器一般返回給客戶端的狀態信息包括三種:1良好,說明請求證書是正確的,而且沒有被吊銷;2吊銷,說明證書已經被吊銷;3未知,證書不在該OCSP響應器的范圍內。
- 為了防止可能發生的欺騙,每一個OCSP返回的回應信息都有簽名,而簽名者必須是用戶所信任的,也就是說,用戶還必須對每一個回應信息進行驗證。
- 在OpenSSL實現上,這個簽名者可能是以下三種之一。
- 1 被驗證證書的CA。即回應信息簽名是用驗證證書的CA證書簽發的。
- 2 被驗證證書CA特殊授權的OCSP響應器。即使用OCSP本身的證書簽發回應信息,OCSP的證書跟被驗證證書是同一個CA頒發的,并且OCSP證書的用途被指明具有OCSP簽名的權限。
- 3?被信任的OCSP響應器。即使用OCSP本身的證書簽發回應信息,OCSP證書本身的CA的根CA在信任設置里面必須是明確指明是可以用于OCSP簽名的,或者是用戶明確定義可以信任的OCSP響應器。
- 可見,OpenSSL的實現跟OCSP協議規定的是基本相符合的,雖然在第三種方式上不完全一致。OpenSSL對OCSP回應信息的驗證也是通過基于OCSP證書建立一個證書鏈來進行的,關于OCSP更多的詳細內容在RFC2560中有明確定義。?
?功能概述和指令格式
- OpenSSL提供的指令總是超出人們的預期,這次看到的ocsp指令也不例外。它幾乎可以完成大部分OCSP協議通常的功能。該指令既可以用來輸出OCSP請求和應答內容,也可以創建OCSP請求并發送給一個OCSP服務器,甚至,它還可以作為一個OCSP服務器運行。
- 下面是ocsp指令格式和其參數:
- ocsp指令里大部分選項都是用于測試和調試目的的,一般情況下,CAfile,Capath和VAfile才是要經常使用的選項。?
- ocsp使用的時候可以作為客戶端或者服務器兩種模式,下面我們對其參數的具體介紹也分為這兩部分來進行。區分ocsp指令在服務器模式還是在客戶端模式工作的標志就是是否使用index選項:如果使用index選項,就是在服務器模式下工作,否則就是在客戶端模式下工作。
輸入和輸出選項out,reqout,respout,reqin和respin
- out選項指定通用的輸出文件,可以在服務器模式或者客戶端模式使用,默認情況下使用標準輸出設備。一般來說,只有可讀寫的信息會在out參數指定的文件中輸出,如提示信息、文本的請求或者響應解釋信息等。
- reqout選項告訴ocsp指令輸出OCSP請求信息并且存儲在參數指定的文件中。
- respout則告訴指令輸出OCSP響應并存儲到該參數指定的文件中。上述選項輸出的請求和響應都是以DER格式存儲的。這兩個選項同樣都可以用于客戶端和服務器模式。
- reqin和respin選項分別告訴指令從這兩個選項指定的文件中讀取OCSP請求或者OCSP響應。
- 如果創建請求或者響應的選項出現,如cert,serial或者host選項生效,那么這兩個選項將會被自動忽略。reqin選項在服務器模式和客戶端模式都可能使用,而respin選項則僅在客戶端模式有效。
輸出內容選項req_text,resp_text和text
- req_text選項和resp_text選項分別告訴指令輸出證書請求或者證書響應的文本信息,如果使用text選項,則指令將同時輸出請求和響應文本信息。這些輸出會保存在out指定的文件中或者標準輸出設備中。這些選項在服務器和客戶端模式都可以使用。
證書相關選項issuer,cert和serial
- isuer選項指定存儲要驗證證書的簽發者證書的文件,該證書必須是PEM格式的。該選項可以重復使用多次以選擇多個簽發者證書。該選項在創建OCSP請求的時候是必須的。
- cert選項指定要驗證的證書,即加到OCSP請求中的證書。簽發該證書的CA證書必須在issuer選項中指定,否則指令就不能正常執行。
- serial跟cert選項的功能一樣,用于向OCSP請求中增加證書,不同的是,該選項使用證書序列號來標識要加入的證書。該序列號默認是以十進制表示,如果在參數前增加了0x,則認為是十六進制。
- 如果你要輸入負數序列號(似乎是很奇怪的需求),只要在輸入參數前面增加“-”號作為標識即可。
請求相關選項signer,signkey,nonce和no_nonce
- 如果需要對OCSP請求進行簽名,則可以利用signer選項來指定簽名的證書,其相應的私鑰則可以在signkey選項指定的文件中輸入。如果沒有使用signkey選項,則ocsp指令將從signer選項指定的文件中讀取私鑰。
- 如果signer和signkey都沒有使用,那么OCSP請求就不會被加密。
- 為了區分每個請求,OCSP定義了所謂的nonce,事實上,它是一個使用摘要算法生成的跟時間相關的隨機數,為了防止重放攻擊等行為的發生。使用reqin輸入已有OCSP請求的時候,默認情況下是不會向請求中增加nonce的,如果選擇了nonce選項,則將強制向OCSP請求中增加nonce擴展項。
- 相反,當使用ocsp指令創建新的請求的時候(使用cert,serail或者host選項等),默認情況下會在請求中增加nonce擴展項,如果不想使用nonce擴展項,則可以使用no_nonce選項去除請求中可能增加的nonce擴展項。
OCSP響應器地址選項host,path和url
- OpenSSL提供給我們的ocsp指令不僅僅可以處理一些OCSP請求或者響應信息,還可以實時模擬一個OCSP客戶端,即時產生OCSP請求,發送給指定的OCSP響應器并得到返回的響應信息。OCSP響應器一般提供基于HTTP或者HTTPS的服務,其定位一般都是通過IP地址、端口和HTTP文件路徑來進行。
- host選項參數指定了OCSP響應器的地址和服務端口,一般是host:port的方式。
- 而path選項則指定了HTTP文件的路徑名,默認情況下使用“/”。
- url選項是另外一種指定OCSP響應器地址的方式,使用HTTP或者HTTPS請求的格式。
- 事實上,在OpenSSL的ocsp指令中,url參數也是被解釋成host和path參數進行實際連接的建立的。
響應驗證證書選項CAfile,CApath,verify_certs,trust_other和VAfile
- CAfile和CApath選項大家已經非常熟悉,它們用來指定CA證書文件或者一個標準的存放CA證書文件的目錄,這里輸入的CA文件用于驗證響應信息的簽名。
- 很多OCSP響應器在返回的響應信息中不會加入完整的OCSP證書,那么這使得客戶端在驗證響應信息的時候就會有一定麻煩。為了兼容這種情況,verify_certs選項可以指定增加一個或者多個證書,在驗證OCSP響應時候可以查找使用這些附加的證書。
- trust_other選項告訴指令,verify_certs指定的證書都是可信任的,不需要對這些證書進行進一步的驗證工作,這時候,指令不會執行完整的證書驗證過程,這對于不能夠建立完整證書鏈的情況就非常有幫助。
- VAfile選項的功能是verify_certs和trust_other選項的綜合,該選項指定的證書都是默認為可信任的附加證書,不需要進行進一步驗證。
響應驗證策略選項noverify,no_signature_verify,no_cert_verify,no_cert_checks,no_intern,no_chain,validity_period和status_age
- noverify選項告訴指令對OCSP響應簽名和nonce字段不進行任何驗證,該選項事實上放棄了所有對OCSP響應的驗證。
- no_signature_verify選項告訴指令不用驗證OCSP響應中的簽名信息,即便簽名無效。
- no_cert_verify選項告訴指令不用驗證響應簽名者的證書,也就是說,任何人簽名的響應都是有效的。
- no_cert_checks選項則告訴指令對響應簽名證書的狀態不用做任何附加的檢查,即如果證書已經被吊銷或者過期,也是不會被發現的。上述的選項因為都在不同程度降低了響應驗證的強度和響應的安全性控制,所以理論上一般僅在測試的時候使用上述選項。
- no_intern選項告訴指令忽略OCSP響應中包含的證書信息,在這種情況下,必須使用verify_certs或者VAfile選項來增加額外的OCSP響應者證書以保證驗證響應簽名過程的順利完成。no_chain告訴指令不要使用響應中的證書作為附加的非信任CA證書,也就是說,不要讓響應中的證書增加到驗證過程中建立的證書鏈中去,這確保了驗證過程中使用的證書完全是由用戶來控制。
- 每個證書響應都會包括一個有效期,這個有效期由一個notBefore字段和一個可選的notAfter字段組成,當前的時間必須在這兩個字段規定的時間之間,響應才有效。但是,這個時間間隔有時候是非常短的,可能只有幾秒,而實際系統的客戶端和服務器的時間可能不同步,存在誤差。為了避免這種情況導致響應失效,OpenSSL提供了validity_period和status_age選項來設定可以允許的時間誤差值,其參數單位是秒。其中,validity_period選項適用于notAfter擴展項存在的情況下,其設定的是一個誤差秒數值,默認值是5分鐘。如果notAfter擴展項不存在,這一般意味著該響應只是即時有效,這時候可以使用status_age選項來設定有效期,即notBefore時間比當前早的時間不應該超過status_age選項設定的值。
- 默認情況下,這項檢查是不會執行的,即響應在notBefore時間后總是有效。
OCSP服務器選項index和CA
- 上面介紹的選項大部分是用于處理OCSP請求、OCSP響應或者模擬客戶端,事實上,ocsp還可以用于模擬一個OCSP響應器(服務器)。
- index選項是否在指令中出現是區分ocsp指令運行在服務器還是客戶端的標記,如果使用了index選項,則表明指令已經運行在OCSP服務器(或者說響應器)的模式下。
- 顯然,OCSP響應器就是為了處理OCSP請求的,在OpenSSL的ocsp指令中,OCSP請求的輸入方式是靈活多樣的:第一種是指令行方式,即直接在ocsp指令行中輸入,使用issuer和serial參數產生請求信息;第二種是采用文件輸入方式,即使用reqin選項指定一個要處理的OCSP請求;第三種方式是采用其他OCSP客戶端輸入,即定義好OCSP運行的服務端口port或者服務URL即可。
- index選項跟我們在ca指令中看到的index選項相同,指定的是OpenSSL提供的模擬CA中的證書庫文件,該文件包含了該CA所有頒發的證書信息和其(吊銷)狀態。在服務器運行模式下,CA選項是必須使用的,它指定了index證書庫相應的CA證書文件。
OCSP響應簽發者選項rsigner,rkey和resp_key_id
- OCSP響應必須是經過簽名的,所以在服務器模式下,rsigner選項是務必要使用的,它指定了用于對OCSP響應簽名的證書。
- rkey則指定了rsigner證書選項相對應的私鑰,如果rkey選項在指令中沒有出現,那么在服務器模式下,指令會從rsigner指定的文件中讀取用于響應簽名的私鑰。OCSP響應被簽名后,還需要在響應中標識用于簽名的私鑰,默認情況下使用的是證書主題名。
- 如果使用resp_key_id選項,則將使用私鑰ID標識OCSP響應信息簽名私鑰。
OCSP響應內容選項rother,resp_no_certs,nmin和ndays
- 如果想在返回給客戶端的響應信息中包含其他附加證書信息(可能用于客戶端驗證響應簽名時使用),那么可以使用rother選項指定存儲這些附加證書的文件。
- 相反,如果不想在響應信息中放入任何證書(包括簽發響應的證書),那么可以使用resp_no_certs選項。
- nmin和ndays選項用來填充響應信息中的nextUpdate字段,該字段告訴客戶端下一次吊銷列表更新的時間將會在多長時間之后,nmin和ndays分別以分鐘和日為單位進行定義。
- 如果在ocsp指令中這兩個選項都沒有使用,那么nextUpdate字段就會從響應信息中刪除,這意味著吊銷列表隨時都會進行更新。
OCSP服務器運行方式選項port和nrequest
- 這兩個參數僅在ocsp指令以服務器方式運行且請求是從OCSP客戶端輸入的情況下使用。
- 其中,port選項定義了OCSP服務器的服務端口,而nrequest選項則告訴指令在接受和處理該參數指定數量的OCSP請求后退出運行狀態。
- 事實上,還有其他一些參數沒有一一介紹,比如engine選項,其意義跟其他指令中的同名選項是一樣的,即使用第三方密碼設備或者密碼庫來執行一些運算操作。讀者可以根據指令的使用和源代碼的閱讀來進一步了解這些指令的更多參數。