OpenSSL:最好的SSL TLS加密庫
OpenSSL項目的目的是通過開源合作精神開發(fā)一種健壯的、可以和同類型商業(yè)程序媲美的、全功能的,且開源的應用于SSL v2/v3(Secure Sockets Layer)和TLS v1(Transport Layer Security)協(xié)議的普遍適用的加密庫工具集。本項目由世界范圍內(nèi)的志愿者們維護,他們通過互聯(lián)網(wǎng)聯(lián)絡、計劃和開發(fā)OpenSSL工具集及其相關(guān)文檔。
下載鏈接:http://down.51cto.com/data/155531
系統(tǒng)需求
OpenSSL可以在多種操作系統(tǒng)上安裝,但是本文只討論在Linux或BSD系統(tǒng)上的安裝。
安裝OpenSSL的系統(tǒng)需求很低,只要有 ANSI C 編譯器(推薦GCC)、Perl 5 、make 即可。但是OpenSSL的測試程序依賴于GNU BC,如果你需要運行測試程序的話,就要事先安裝好它。
編譯選項
將下載回來的壓縮包解壓,進入解壓后的目錄,即可使用 config 或 Configure 腳本進行配置。OpenSSL的配置腳本與大多數(shù)典型的軟件包不同,它有自己的一套規(guī)則。詳細的安裝信息位于源碼樹下的 INSTALL Configure(特別是"PROCESS_ARGS"段) Makefile.shared Makefile.org 文件中。安裝后的使用與配置信息位于 doc 目錄中, FAQ 文件也可以提供一些參考。
config 腳本檢查系統(tǒng)環(huán)境并調(diào)用 Configure 完成配置,因此配置選項是通過 config 腳本向 Configure 傳遞的。事實上 config 腳本的作用相當于 config.guess ,所以如果你想直接調(diào)用 Configure 的話就一定要正確指定"操作系統(tǒng)-目標平臺"(筆者推薦這個用法)。所有可用的目標機器列表可以使用"./Configure LIST"命令獲取。Configure 腳本除了根據(jù) Makefile.org 生成 Makefile 之外,還在 crypto/opensslconf.h 中定義了許多宏(基于 crypto/opensslconf.h.in)。
在 config 或 Configure 命令行上可以使用許多選項,大體上可以分為3類。
全局選項
第一類是全局性選項:
--openssldir=OPENSSLDIR
安裝目錄,默認是 /usr/local/ssl 。
--prefix=PREFIX
設置 lib include bin 目錄的前綴,默認為 OPENSSLDIR 目錄。
--install_prefix=DESTDIR
設置安裝時以此目錄作為"根"目錄,通常用于打包,默認為空。
zlib
zlib-dynamic
no-zlib
使用靜態(tài)的zlib壓縮庫、使用動態(tài)的zlib壓縮庫、不使用zlib壓縮功能。
threads
no-threads
是否編譯支持多線程的庫。默認支持。
shared
no-shared
是否生成動態(tài)連接庫。
asm
no-asm
是否在編譯過程中使用匯編代碼加快編譯過程。
enable-sse2
no-sse2
啟用/禁用SSE2指令集加速。如果你的CPU支持SSE2指令集,就可以打開,否則就要關(guān)閉。
gmp
no-gmp
啟用/禁用GMP庫
rfc3779
no-rfc3779
啟用/禁用實現(xiàn)X509v3證書的IP地址擴展
krb5
no-krb5
啟用/禁用 Kerberos 5 支持
ssl
no-ssl
ssl2
ssl3
no-ssl2
no-ssl3
tls
no-tls
啟用/禁用 SSL(包含了SSL2/SSL3) TLS 協(xié)議支持。
dso
no-dso
啟用/禁用調(diào)用其它動態(tài)鏈接庫的功能。[提示]no-dso僅在no-shared的前提下可用。
[提示]為了安裝Apache的mod_ssl成功,SSLv2/SSLv3/TLS都必須開啟。
算法選項
第二類用于禁用crypto目錄下相應的子目錄(主要是各種算法)。雖然理論上這些子目錄都可以通過"no-*"語法禁用,但是實際上,為了能夠最小安裝libcrypto,libssl,openssl,其中的大部分目錄都必須保留,實際可選的目錄僅有如下這些:
no-md2,no-md4,no-mdc2,no-ripemd
這些都是摘要算法,含義一目了然。
no-des,no-rc2,no-rc4,no-rc5,no-idea,no-bf,no-cast,no-camellia
這些都是對稱加密算法,含義一目了然。"bf"是"Blowfish"的意思。
no-ec,no-dsa,no-ecdsa,no-dh,no-ecdh
這些都是不對稱加密算法,含義一目了然。
no-comp
數(shù)據(jù)壓縮算法。因為目前實際上并沒有壓縮算法,所以只是定義了一些空接口。
no-store
對象存儲功能。更多細節(jié)可以查看 crypto/store/README 文件。
[提示]OpenSSH 只依賴于該軟件包的加密庫(libcrypto),而帶有 HTTPS 支持的 Apache 則依賴于該軟件包的加密庫和 SSL/TLS 庫(libssl)。因此,如果你不打算使用 HTTPS 的話,可以只安裝加密庫(no-ssl no-tls);更多介紹可以查看 README 文件的"OVERVIEW"部分。事實上,為了能夠讓OpenSSH安裝成功,ripemd,des,rc4,bf,cast,dsa,dh目錄不能被禁止。
編譯器選項
第三類是編譯器選項。大多數(shù)軟件包都是通過在運行 configure 腳本的時候定義 CPPFLAGS CFLAGS LDFLAGS 環(huán)境變量來設置編譯選項的,但是OpenSSL卻不是這樣。OpenSSL的 Configure 腳本允許你在命令行上直接輸入 CPPFLAGS CFLAGS 的內(nèi)容。比如:-DDEVRANDOM='"/dev/urandom"' 可以用來指定隨機設備, -DSSL_FORBID_ENULL 則可以用于禁止使用NULL加密算法。`echo $CFLAGS` 則可以將 CFLAGS 變量添加上來。另一方面,LDFLAGS卻是無法通過Configure進行設置的。因為Configure會強制清空Makefile中的LDFLAGS,所以在運行完Configure之后,可以使用一個sed修改所有Makefile中的 LDFLAGS(用于連接openssl)和SHARED_LDFLAGS(用于連接libcrypto,libssl庫)。
比如筆者就經(jīng)常這樣使用 Configure 進行配置:
./Configure ... -DSSL_FORBID_ENULL -DDEVRANDOM='"/dev/urandom"' `echo $CFLAGS`
find . -name "Makefile*" -exec sed -r -i -e"s|^(SHARED_)?LDFLAGS=|& $LDFLAGS |" {} \;
[提示]不能省略find命令內(nèi)"Makefile*"兩邊的引號。
編譯、測試、安裝
配置完畢后,需要使用 make depend 重新建立依賴關(guān)系,特別是你使用了"no-*"選項之后,否則編譯可能會失敗。
然后使用 make 命令編譯。如果編譯成功,那么最好使用 make test 進行一下測試。
如果測試也通過了,那么接下來就是安裝了。安裝很簡單,一條 make install 命令即可。你還可以使用 make install INSTALL_PREFIX=/other/dir 來將 /other/dir 當作"根"進行安裝,這通常用于打包。
配置文件
安裝完畢之后,接下來就是配置。OpenSSL的配置文件是 openssl.cnf ,位于 --openssldir 指定的目錄下。
在實踐中,OpenSSL 的一個重要用途就是證書簽發(fā)和管理,這需要配置文件的配合。如果你只是使用它的加密庫,而不使用證書功能的話,就不需要了解如何配置OpenSSL 。
下面是一個簡單的 openssl.cnf 文件,已經(jīng)可以用于證書簽發(fā)了。當然,這份配置用來自己玩玩還行,指望用這個去做真正的"Big Brother",沒人會信你 :)
- ########################
- # OpenSSL 配置文件示范 #
- ########################
- # [注意]這個示范文件并不是默認設置。
- ########
- # 語法 #
- ########
- #
- # 變量 = 值
- #
- # 語法很簡單,一看就懂,但是有幾點需要說明:
- # 1. 字符串值最好使用雙引號界定,并且其中可以使用"\n","\r","\t"這些轉(zhuǎn)義序列("\"怎么表示?)。
- # 2. 可以使用 ${變量名} 的形式引用同一字段中的變量,使用 ${字段名::變量名} 的形式引用其它字段中的變量。
- # 3. 可以使用 ${EVP::環(huán)境變量} 的形式引用操作系統(tǒng)中定義的環(huán)境變量,若變量不存在則會導致錯誤。
- # 4. 可以在默認字段定義與操作系統(tǒng)環(huán)境變量同名的變量作為默認值來避免環(huán)境變量不存在導致的錯誤。
- # 5. 如果在同一字段內(nèi)有多個相同名稱的變量,那么后面的值將覆蓋前面的值。
- #
- ############
- # 默認字段 #
- ############
- # 此部分是默認字段[配置段],必須放在所有字段之前。
- # 讀取配置文件數(shù)據(jù)時,會首先根據(jù)字段名稱去尋找相應的配置段,如果沒有找到則會使用這里的默認字段。
- # 定義 HOME 的默認值,防止操作系統(tǒng)中不存在 HOME 環(huán)境變量。
- HOME = .
- # 默認的隨機數(shù)種子文件,建議設置為 /dev/random 或 /dev/urandom
- RANDFILE = $ENV::HOME/.rnd
- # 擴展對象定義
- # 比如,OpenSSL中并未定義X.509證書的擴展項,在使用到的時候就會從下面對擴展對象的定義中獲取。
- # 定義的方法有兩種,第一種(反對使用)是存儲在外部文件中,也就是這里"oid_file"變量定義的文件。
- #oid_file = $ENV::HOME/.oid
- # 第二種是存儲在配置文件的一個字段中,也就是這里"oid_section"變量值所指定的字段。
- oid_section = new_oids
- [ new_oids ]
- # 可以在這里添加擴展對象的定義,例如可以被'ca'和'req'使用。
- # 格式如下:
- # 對象簡稱 = 對象數(shù)字ID
#p#
- ############################################################################################################
- ####################
- ## 證書請求配置 ##
- ####################
- # 在申請證書之前通常需要首先生成符合 PKCS#10 標準的證書請求封裝格式。
- # openssl 的 req 指令實現(xiàn)了產(chǎn)生證書請求的功能,其相關(guān)選項的默認值就來自于這里的設置。
- # 證書請求的配置分成幾個字段,包括一個基本字段和幾個附屬字段。
- ##### 證書請求配置的"基本字段",其它附屬字段都以它為入口 #####
- [ req ]
- # 生成的證書中RSA密鑰對的默認長度,取值是2的整數(shù)次方。建議使用4096以上。
- default_bits = 1024
- # 保存生成的私鑰文件的默認文件名
- default_keyfile = privkey.pem
- # 生成的私鑰文件是否采用口令加密保護,可以設為yes或no。
- encrypt_key = yes
- # 讀取輸入私鑰文件時的口令,如果未設置那么將會提示輸入。
- # input_password = secret
- # 保存輸出私鑰文件時的口令,如果未設置那么將會提示輸入。
- # output_password = secret
- # 簽名默認使用的信息摘要算法,可以使用:md5,sha1,mdc2,md2
- default_md = md5
- # 為一些字段設置默認的字符串類型,比如證書請求中的城市和組織名稱。可能的取值和解釋如下:
- # default: 包含了 PrintableString, T61String, BMPString 三種類型
- # pkix : 包含了 PrintableString, BMPString 兩種類型
- # utf8only: 只使用 UTF8 字符串。推薦使用這個,這樣可以完美的包含任意字符。
- # nombstr : 包含了 PrintableString, T61String 兩種類型(不使用 BMPStrings 或 UTF8String 兩種多字節(jié)字符類型)
- string_mask = nombstr
- # 如果設為yes,那么不管是命令行還是配置文件中的字符串都將按照UTF-8編碼看待。默認值no表示僅使用ASCII編碼。
- utf8 = no
- # 如果設為no,那么 req 指令將直接從配置文件中讀取證書字段的信息,而不提示用戶輸入。
- prompt = yes
- # 定義輸入用戶信息選項的"特征名稱"字段名,該擴展字段定義了多項用戶信息。
- distinguished_name = req_distinguished_name
- # 定義證書請求屬性的字段名,該擴展字段定義了證書請求的一些屬性,但openssl的證書簽發(fā)工具并不使用它們。
- attributes = req_attributes
- # 證書請求擴展的字段名,該擴展字段定義了要加入到證書請求中的一系列擴展項。
- # req_extensions = v3_req
- # 生成自簽名證書時要使用的證書擴展項字段名,該擴展字段定義了要加入到證書中的一系列擴展項。
- x509_extensions = v3_ca
- ##### "特征名稱"字段包含了用戶的標識信息 #####
- [ req_distinguished_name ]
- countryName = CN #只能使用2字母的國家代碼
- stateOrProvinceName = 省份或直轄市名稱
- organizationName = 組織名
- commonName = 網(wǎng)站的全限定域名
- ##### 證書請求屬性字段定義了證書請求的一些屬性(都不是必須的) #####
- [ req_attributes ]
- ##### 要加入到證書請求中的一系列擴展項 #####
- [ v3_req ]
- basicConstraints = CA:FALSE
- keyUsage = nonRepudiation, digitalSignature, keyEncipherment
- #### 生成自簽名證書時使用的證書擴展項 #####
- ### 因為這部分是非必須的,所以不翻譯了,事實上你完全可以刪除這部分內(nèi)容
- [ v3_ca ]
- # PKIX recommendation.
- subjectKeyIdentifier = hash
- authorityKeyIdentifier = keyid:always,issuer:always
- # This is what PKIX recommends but some broken software chokes on critical
- # extensions.
- #basicConstraints = critical,CA:true
- # So we do this instead.
- basicConstraints = CA:true
- # Key usage: this is typical for a CA certificate. However since it will
- # prevent it being used as an test self-signed certificate it is best
- # left out by default.
- # keyUsage = cRLSign, keyCertSign
- # Some might want this also
- # nsCertType = sslCA, emailCA
- # Include email address in subject alt name: another PKIX recommendation
- # subjectAltName = email:copy
- # Copy issuer details
- # issuerissuerAltName = issuer:copy
- # DER hex encoding of an extension: beware experts only!
- # obj=DER:02:03
- # Where 'obj' is a standard or added object
- # You can even override a supported extension:
- # basicConstraints = critical, DER:30:03:01:01:FF
#p#
- ############################################################################################################
- ####################
- ## 證書簽發(fā)配置 ##
- ####################
- # openssl 的 ca 指令實現(xiàn)了證書簽發(fā)的功能,其相關(guān)選項的默認值就來自于這里的設置。
- # 這個字段只是通過唯一的default_ca變量來指定默認的CA主配置字段的入口(-name 命令行選項的默認值)
- [ ca ]
- default_ca = CA_default
- ##### 默認的CA主配置字段 #####
- [ CA_default ]
- # 保存所有信息的文件夾,這個變量只是為了給后面的變量使用
- dir = ./demoCA
- # 存放CA本身根證書的文件名
- certificate = $dir/cacert.pem
- # 存放CA自身私鑰的文件名
- private_key = $dir/private/cakey.pem
- # 簽發(fā)證書時使用的序列號文本文件,里面必須包含下一個可用的16進制數(shù)字。
- serial = $dir/serial
- # 存放新簽發(fā)證書的默認目錄,證書名就是該證書的系列號,后綴是.pem
- new_certs_dir = $dir/newcerts
- # 已生成的證書的默認保存目錄
- certs = $dir/certs
- # 保存已簽發(fā)證書的文本數(shù)據(jù)庫文件,初始時為空。
- database = $dir/index.txt
- # 存放當前CRL編號的文件,對于v1版本的CRL則必須注釋掉該行
- crlnumber = $dir/crlnumber
- # 當前CRL文件
- crl = $dir/crl.pem
- # 生成的證書撤銷列表(CRL)的默認保存目錄
- crl_dir = $dir/crl
- # 同一個subject是否只能創(chuàng)建一個證書,設為no表示可以創(chuàng)建多個
- unique_subject = yes
- # 簽發(fā)新證書以及CRL時默認的摘要算法,可以使用:md5,md2,mdc2,sha1
- default_md = sha1
- # 通常,證書簽發(fā)的特征名稱(DN)域的各個參數(shù)順序與證書策略的參數(shù)順序一致。
- # 但是,如果這里設為yes則保持與證書請求中的參數(shù)順序一致。
- preserve = no
- # 當用戶需要確認簽發(fā)證書時顯示可讀證書DN域的方式。可用值與 x509 指令的 -nameopt 選項相同。
- name_opt = ca_default
- # 當用戶需要確認簽發(fā)證書時顯示證書域的方式。
- # 可用值與 x509 指令的 -certopt 選項相同,不過 no_signame 和 no_sigdump 總被默認設置。
- cert_opt = ca_default
- # 新證書默認的生效日期,如果未設置則使用簽發(fā)時的時間,格式為:YYMMDDHHNNSSZ(年月日時分秒Z)
- # default_startdate = 080303223344Z
- # 新證書默認的失效日期,格式為:YYMMDDHHNNSSZ(年月日時分秒Z)
- # default_enddate = 090303223344Z
- # 新簽發(fā)的證書默認有效期,以天為單位
- default_days = 365
- # 從當前CRL(證書撤銷列表)到下次CRL發(fā)布的間隔天數(shù)
- default_crl_days = 30
- # 是否將證書請求中的擴展項信息加入到證書擴展項中去。取值范圍以及解釋:
- # none: 忽略所有證書請求中的擴展項
- # copy: 將證書擴展項中沒有的項目復制到證書中
- # copyall: 將所有證書請求中的擴展項都復制過去,并且覆蓋證書擴展項中原來已經(jīng)存在的值。
- copy_extensions = none
- # 定義用于證書請求DN域匹配策略的字段,用于決定CA要求和處理證書請求提供的DN域的各個參數(shù)值的規(guī)則。
- policy = policy_match
- # 定義X.509證書擴展項的字段。如果沒有提供這個字段則生成X.509v1而不是v3格式的證書。
- x509_extensions = usr_cert
- # 定義生成CRL時需要加入的擴展項字段。如果沒有定義則生成v1而不是v2版本的CRL。
- # crl_extcrl_extensions = crl_ext
- ##### 證書請求信息的匹配策略 #####
- # 變量名稱是DN域?qū)ο蟮拿Q,變量值可以是:
- # match: 該變量在證書請求中的值必須與CA證書相應的變量值完全相同,否則拒簽。
- # supplied: 該變量在證書請求中必須提供(值可以不同),否則拒簽。
- # optional: 該變量在證書請求中可以存在也可以不存在(相當于沒有要求)。
- # 除非preserve=yes或者在ca命令中使用了-preserveDN,否則在簽發(fā)證書時將刪除匹配策略中未提及的對象。
- [ policy_match ]
- countryName = match
- stateOrProvinceName = match
- organizationName = match
- commonName = supplied
- organizationalUnitName = optional
- emailAddress = optional
- ### 下面的部分由于都是非必須的部分,因此也不翻譯了。
- ### 事實上你完全可以從配置文件中刪除這些內(nèi)容
- [ usr_cert ]
- # These extensions are added when 'ca' signs a request.
- # This goes against PKIX guidelines but some CAs do it and some software
- # requires this to avoid interpreting an end user certificate as a CA.
- basicConstraints=CA:FALSE
- # Here are some examples of the usage of nsCertType. If it is omitted
- # the certificate can be used for anything *except* object signing.
- # This is OK for an SSL server.
- # nsCertType = server
- # For an object signing certificate this would be used.
- # nsCertType = objsign
- # For normal client use this is typical
- # nsCertType = client, email
- # and for everything including object signing:
- # nsCertType = client, email, objsign
- # This is typical in keyUsage for a client certificate.
- # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
- # This will be displayed in Netscape's comment listbox.
- nsComment = "OpenSSL Generated Certificate"
- # PKIX recommendations harmless if included in all certificates.
- subjectKeyIdentifier=hash
- authorityKeyIdentifier=keyid,issuer
- # This stuff is for subjectAltName and issuerAltname.
- # Import the email address.
- # subjectAltName=email:copy
- # An alternative to produce certificates that aren't
- # deprecated according to PKIX.
- # subjectAltName=email:move
- # Copy subject details
- # issuerissuerAltName=issuer:copy
- #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
- #nsBaseUrl
- #nsRevocationUrl
- #nsRenewalUrl
- #nsCaPolicyUrl
- #nsSslServerName
- [ crl_ext ]
- # CRL extensions.
- # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
- # issuerissuerAltName=issuer:copy
- authorityKeyIdentifier=keyid:always,issuer:always
- [ proxy_cert_ext ]
- # These extensions should be added when creating a proxy certificate
- # This goes against PKIX guidelines but some CAs do it and some software
- # requires this to avoid interpreting an end user certificate as a CA.
- basicConstraints=CA:FALSE
- # Here are some examples of the usage of nsCertType. If it is omitted
- # the certificate can be used for anything *except* object signing.
- # This is OK for an SSL server.
- # nsCertType = server
- # For an object signing certificate this would be used.
- # nsCertType = objsign
- # For normal client use this is typical
- # nsCertType = client, email
- # and for everything including object signing:
- # nsCertType = client, email, objsign
- # This is typical in keyUsage for a client certificate.
- # keyUsage = nonRepudiation, digitalSignature, keyEncipherment
- # This will be displayed in Netscape's comment listbox.
- nsComment = "OpenSSL Generated Certificate"
- # PKIX recommendations harmless if included in all certificates.
- subjectKeyIdentifier=hash
- authorityKeyIdentifier=keyid,issuer:always
- # This stuff is for subjectAltName and issuerAltname.
- # Import the email address.
- # subjectAltName=email:copy
- # An alternative to produce certificates that aren't
- # deprecated according to PKIX.
- # subjectAltName=email:move
- # Copy subject details
- # issuerissuerAltName=issuer:copy
- #nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
- #nsBaseUrl
- #nsRevocationUrl
- #nsRenewalUrl
- #nsCaPolicyUrl
- #nsSslServerName
- # This really needs to be in place for it to be a proxy certificate.
- proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo