網頁伺服器,有兩種資料傳輸編碼方式,第一種是 HTTP 方式,這個方式是使用純文字傳輸,也就是完全沒有加密,在資料傳輸的過程中,會經過不少路由器,這樣傳輸的資料就有被盜取的可能性,所以才有人開發出 HTTPS 的編碼方式,這個方式會使用 SSL 加密,由於資料是經過加密的,所以沒有密碼檔的人是沒辦法解出資料內容的。
SSL : Secure Sockets Layer
SSL 使用的加密方式,其中包含兩個 key(密碼),這兩個 key 是對應關系,一個用來加密,一個是用來解密,一個 key 是 public key ,主要是用來加密資料,另一個 key 是 private key ,主要是用來解密, private key 只有伺服器知道,所以除了伺服器本身以外,其他人是很難解密的 (這理我只能說很難,因為還是有很低的機率被高人給解開!!) ,
CA : Certificate Authority
CA 是一個 key 的管理單位,這個單位主要是確認 private/public key 這兩個 key 的公正性,只有 CA 證証過的 key 才是合法的 key ,瀏覽器會自動通過並使用這些 Key ,而如果我們自已建立的網站,是使用未通過 CA 證証的 key,也就是自已建立的 private/public key ,這樣的話,瀏覽器就會出現警告的提示,提醒網頁用戶,這個 key 是未通過認證的。
一個有通過 CA 認証的 public key ,其內容會包含「公司名稱、網域、申請人」等等, CA的認証是有時間限制的,過期後,就要重新再申請一次,所以並不是一勞永逸的。
HTTP & HTTPS
HTTP 一般都是使用 80 port ,而 HTTPS 是使用 443 port ,所以兩種在網路上的傳輸是分開,同一台伺服器是可以同時支援兩種傳輸模式, HTTPS 是指,browser 將傳輸的資料以 SSL 加密後,再使用 HTTP Protocol 並透過 TCP 方式傳送出去,若是伺服器使用 HTTPS 傳輸方式,在 client 與 server 建立連線的同時,雙方必需先溝通加密模式,不同的 SSL 版本,使用的加密方式是不同的,如 SSL 2.0是使用 RSA 加密演算法 。
Apache Module mod_ssl
網頁伺服器 apache ,內建都已經有 ssl的模組,叫作 mod_ssl ,這個 module 支援 SSL 2.0 、SSL 3.0 、 TLS 1.0 加密模式, 這個 module會用到 OpenSSL library ,所以使用時,系統也必需安裝 OpensSSL。
- //先進入 apache module 路徑
- cd httpd-2.2.19/modules/ssl
- sudo apxs -c -i -D HAVE_OPENSSL -I/usr/include/ -lcrypto -lssl -ldl -A *.c
- LoadModule deflate_module modules/mod_ssl.so : apache conf 中指定要載入 Module
設定 apache 443 port 的 web site,首先在 http.conf 加入 Include httpd-ssl.conf ,然後在 httpd-ssl.conf 中加入下列設定,即可完成 HTTPS 的傳輸功能。
- Listen 443
- AddType application/x-x509-ca-cert .crt
- AddType application/x-pkcs7-crl .crl
- <VirtualHost *:443>
- ServerName xxx.com.tw
- DocumentRoot "/website/"
- SSLEngine on
- SSLCertificateFile /apache/server.crt // server 憑證
- SSLCertificateKeyFile /apache/server.key // private key
- SSLCertificateChainFile /apache/ca.cert // certification 公司的Certificate authorization 憑證,這個檔案必須是 CA 公司給的。
- </VirtualHost>
HTTPS 的 Rewrite 設定,將 443 port 導到 HTTPS ,非443 port 導到 HTTP
- RewriteEngine on
- RewriteRule ^/(.*):SSL$ https://%{SERVER_NAME}/$1 [R,L]
- RewriteRule ^/(.*):NOSSL$ http://%{SERVER_NAME}/$1 [R,L]
SSL 憑證製作
首先在 Linux 系統中,安裝 OpenSSL,一般來說系統內建都已經安裝好了,這裡就跳過這個流程,安裝好的 OpenSSL 路徑在 /usr/share/ssl/ ( 或是 /etc/pki/tls/openssl.cnf) ,
- mkdir ~/key : 先建立一個資料夾,準備來製作憑證。
- cd ~/key
- mkdir certs crl newcerts private : 建立這幾個資料夾
- cp /usr/share/ssl/openssl.cnf ~/key/ 將 OpenSSL設定檔搬過來
- openssl rand 1024 > ./private/.rand : 製作亂數檔
- chmod 600 ./private/.rand
- echo "0001" > serial
- touch index.txt
- 修改 openssl.cnf
- dir = /home/xxxid/key //改成你自已的路徑
- default_days = 365 //認証天數 365 天
- default_md = md5 //編碼方式
- default_bits = 1024 //有分 1024 , 2048 兩種位元數 ,2048 會比較安全,建議使用 2048
- certificate = $dir/cacert.pem // CA certificate 路徑
- database = $dir/index.txt
- serial = $dir/serial //序號 ,會自動去讀檔
- openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 3650 -config openssl.cnf : 建立 private key 以及 填寫 CA 申請資料
這一步會建立加密過的 private key ,以及 "certificate request " cacert.pem ,這個檔案是沒有經過簽証的,還不能拿來使用,我們必須將這個檔案傳給 certificate 公司,請他們認証, 例如 startssl.com 這個網站就有免費的 certificate 認証,而加密過的 private key 也必須先經過解密,才能在 web service 上使用 ,startssl.com 就有提供解密工具: https://startssl.com/ToolBox/DecryptPrivateKey 。
如果你不想經過官方認証這個步驟,那麼我們也可以偽造 certificate 認証,方式如下:
- openssl req -nodes -new -x509 -keyout mykey.pem -out myreq.pem -days 365 -config openssl.cnf : 填寫伺服器資料,並解出 private key。
- openssl x509 -x509toreq -in myreq.pem -signkey mykey.pem -out tmp.pem
- openssl ca -config openssl.cnf -policy policy_anything -out mycert.pem -infiles tmp.pem : 自已簽名,完成憑證
經過上述的步驟後,SSL certification 就算完成囉,接著把檔案 copy 到正確的位置。
- cp cacert.pem /apache/ca.crt
- cp mycert.pem /apache/server.crt
- cp mykey.pem /apache/server.key
CA 認証公司
這裡提供一些申請 CA 的公司,我自已是沒申請過啦 XD ,有需要的人再自行去嘗試囉。
- http://www.thawte.com/
- http://www.verisign.com/
- http://www.godaddy.com/ssl/ssl-certificates.aspx?ci=55902
測試是否可以成功用 ssl 連線
- openssl s_client -CAfile /www/xxx/xx/server.crt -showcerts -connect localhost:443
什麼是 .csr .key .pem
在製作 SSL 時,常會看到這三個副檔名,下面就來說明這三個名詞。
.csr: 全名為 Certificate Signing Request ,是一個被加密過的檔案,它的檔案格式為 PKCS Public Key Cryptography Standards ,這個檔案儲存組織名稱 ,國家,Domain Name 等,最重要的是這個檔案也包含一個 public key,而因為 public/private key 是成對出現的,所以當你有一個 csr 檔,也就代表你也會有一個 private key 檔。
.key 這個檔案就是一個私鑰 private key ,它的檔案格式為 PEM。
.pem 全名 privacy-enhanced mail, 它的檔案格式定義在 RFC 1421,這種檔案可以儲存多種格式,一個檔案可以有 public key 跟 CA certificate,也可以同時有 public key, private key, Root certificates,所有 SSL 相關的 public/private key , csr 都是使用 pem 格式。
測試 private key 與 certificate
如果你的 key 跟 certificate 不一致,那麼可能會出現像下面這種錯誤訊息。
- Server {0x40a65b30} ERROR: SSL::0:error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch:x509_cmp.c
- Server {0x40a65b30} ERROR: failed to load server private key from xxx
這時可以用下面這兩個簡單的指令來測試,如果這兩個指令印出的值不同,那麼你的 key 與 certificate 是不一致,必須再建立一個新的 certificate。
- openssl x509 -noout -modulus -in pxxxx.crt | openssl md5
- openssl rsa -noout -modulus -in private.key | openssl md5
如果你是在 startssl.com 申請的免費 certificate ,可以參考這裡的官方說明,如何設定你的 apache server
https://www.startssl.com/Support?v=21參考資料
- http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95 RSA 加密演算法
- http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html
- http://httpd.apache.org/docs/2.0/ssl/ssl_intro.html#ssl
- http://httpd.apache.org/docs/2.0/mod/mod_ssl.html apache module ssl
- http://www.openssl.org/ OpenSSL
- http://www.debianhelp.co.uk/selfcert.htm
- http://devsec.org/info/ssl-cert.html