2012
Jan
15





網頁伺服器,有兩種資料傳輸編碼方式,第一種是 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的認証是有時間限制的,過期後,就要重新再申請一次,所以並不是一勞永逸的。

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 mod_ssl 編譯方式
Example
  1. //先進入 apache module 路徑
  2. cd httpd-2.2.19/modules/ssl
  3. 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 的傳輸功能。

Example
  1. Listen 443
  2. AddType application/x-x509-ca-cert .crt
  3. AddType application/x-pkcs7-crl .crl
  4. <VirtualHost *:443>
  5. ServerName xxx.com.tw
  6. DocumentRoot "/website/"
  7. SSLEngine on
  8. SSLCertificateFile /apache/server.crt // server 憑證
  9. SSLCertificateKeyFile /apache/server.key // private key
  10. SSLCertificateChainFile /apache/ca.cert // certification 公司的Certificate authorization 憑證,這個檔案必須是 CA 公司給的。
  11. </VirtualHost>

HTTPS 的 Rewrite 設定,將 443 port 導到 HTTPS ,非443 port 導到 HTTP

Example
  1. RewriteEngine on
  2. RewriteRule ^/(.*):SSL$ https://%{SERVER_NAME}/$1 [R,L]
  3. 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
Example
  1. dir = /home/xxxid/key //改成你自已的路徑
  2. default_days = 365 //認証天數 365 天
  3. default_md = md5 //編碼方式
  4. default_bits = 1024 //有分 1024 , 2048 兩種位元數 ,2048 會比較安全,建議使用 2048
  5. certificate = $dir/cacert.pem // CA certificate 路徑
  6. database = $dir/index.txt
  7. 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 ,有需要的人再自行去嘗試囉。

測試是否可以成功用 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 不一致,那麼可能會出現像下面這種錯誤訊息。

Example
  1. Server {0x40a65b30} ERROR: SSL::0:error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch:x509_cmp.c
  2.  
  3. 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

參考資料


回應 (Leave a comment)