本文只讨论 SSL X.509 凭证做法,不讨论系统安全问题,不讨论加解密的演算法,也不讨论 OpenSSL 的如何安装。我假设你了解基本 Public Key/Private Key 不对称加解密的观念,知道什么是 RSA/DSA 演算法。我也假设你已经装好了 OpenSSL ,安装时使用下列符合 FHS[1] 标准的设定:
./config --prefix=/usr --openssldir=/usr/share/ssl
或安装 RPM 或 apt 的 openssl 套件。
本文是做法教学 (HOWTO) ,所以在编排上,把做法步骤 (how) 放在最前面,观念说明和讨论 (what and why) 等,都放在文末。若你看不懂做法,或想先学一些基本概念,请先往后翻阅,不需由前到后阅读。
请注意:依本文制作的凭证,还是会在浏览器等 SSL 程式上出现凭证无效的警告。
按 X.509 的规定,凭证可以用 RSA Key ,也可以用 DSA Key 。不过在 SSL 通讯中,伺服器的凭证因为要用来传 Key ,而只有 RSA 可以传 Key ,所以只能用 RSA 。至於认证中心,只是签名查核用,不用传 Key , DSA 或 RSA 都可以,但因为还有一些 SSL 程式不认得 DSA[2] ,为相容性起见,这里我们也做成 RSA 。
要制作最高层认证中心,可以以一般使用者权限来做,不一定要是 root 。但如果做出来的最高层认证中心,是整个组织签发凭证要用的,建议以 root 的权限来做,比较安全。同理,制作凭证,也可以以一般使用者权限来做。但如果做出来的凭证,是这个伺服器要用的,为安全起见,建议以 root 的权限来做。
若你是 root ,要安装给整个组织来用:
设定 OpenSSL 的环境
若你是用上述方法安装:
./config --prefix=/usr --openssldir=/usr/share/ssl
或装 Red Hat 的 RPM , OpenSSL 的设定档目录会在 /usr/share/ssl 。若你是安装 Mandrake 的 RPM ,设定档目录会在 /usr/lib/ssl 。这两个位置都不符合 FHS 的要求,资料备份起来也不方便。设定档应该放在 /etc/ssl 下。若你是安装 Debian 的 apt ,设定档目录会在 /etc/ssl 下,不会有问题。
# 设定相关的目录
mkdir -p /etc/ssl
mkdir -p /etc/ssl/private
chmod og-rwx /etc/ssl/private
mkdir -p /etc/ssl/certs
mkdir -p /etc/ssl/crl
mkdir -p /etc/ssl/newcerts
# 设定 OpenSSL 设定档[3]
mv /usr/share/ssl/openssl.cnf /etc/ssl
ln -s /etc/ssl/openssl.cnf /usr/share/ssl/openssl.cnf
# 设定 OpenSSL 设定档的位置[4]
export OPENSSL_CONF="/etc/ssl/openssl.cnf"
# 把 OpenSSL 设定档的位置加进 .bashrc 中[5]
echo "# OpenSSL 设定档的位置" >> ~/.bashrc
echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.bashrc
# 制作乱数档[6]
openssl rand -out /etc/ssl/private/.rand 1024
chmod og-rwx /etc/ssl/private/.rand
然后修改 /etc/ssl/openssl.cnf ,把这一行
dir = ./demoCA # Where everything is kept
改成这样
dir = /etc/ssl # Where everything is kept
制作最高层认证中心 (Root CA)
若你之前做过最高层认证中心,不要重做,不然原来签发的凭证,都会失效,都要重签。除非最高层认证中心自己过期、档案遗失、 Private Key 外泄,否则绝对不要重做最高层认证中心。
假设你要做的最高层认证中心叫做 myrootca 。
1. 制作 Private Key (及 Public Key )
这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。
请为最高层认证中心的 Private Key 设定一个适当的密码。
# 制作 RSA[7] Private Key
openssl genrsa -des3 -out /etc/ssl/private/myrootca.key 2048
chmod og-rwx /etc/ssl/private/myrootca.key
2. 填写凭证申请书
凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。请一一填写。详情请参考「什么是凭证?」。
若你要直接用最高层认证中心来直接当凭证用,凭证名称 (Common Name) 请用伺服器的全名 (www.abc.com) 。详情请参考「其她 SSL/X.509 凭证的做法」。
若不知如何填写,请参阅「如何填写凭证申请书」。
# 填写凭证申请书
openssl req -new -key /etc/ssl/private/myrootca.key -out /tmp/myrootca.req
3. 签发凭证
最高层认证中心因为没有上级了,没有人能给它签名,只能自己给自己签名。详情请参考「什么是最高层认证中心?」。
最高层认证中心最好永远不要过期。要是过期重签,所有原来它签发的凭证也都要重签,所有 SSL 程式也都要重新设定。所以我们效期签 7305 天(大约 20年)。若不设效期的话,预设是 30 天(一个月)。
签完凭证,凭证申请书就不用了,可以删掉。
# 自己给自己签名
openssl x509 -req -days 7305 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_ca -signkey /etc/ssl/private/myrootca.key -in /tmp/myrootca.req -out /etc/ssl/certs/myrootca.crt
# 删除凭证申请书
rm -f /tmp/myrootca.req
这样就好了。 Private Key 在 /etc/ssl/private/myrootca.key ,自己签名的 Public Key 凭证在 /etc/ssl/certs/myrootca.crt 。 myrootca.key 是 Private Key ,要小心存好保护,只有 root 才能读,权限建议 0444 。 myrootca.crt 是 Public Key 凭证,要尽量散出去,让大家用。最好放到内部网路上,或放到网站上,让大家自己下载,自己加进去。
制作伺服器用的凭证
假设你要做 myhost 的凭证:
1. 制作 Private Key (及 Public Key )
这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。
请先登入到要用凭证的那台伺服器上。
注意:伺服器的 Private Key 不要设密码,不然 SSL 伺服器程式启动的时候,一去读凭证和 Private Key ,就要问一次密码。每次重开机,依序启动每个伺服器程式的时候,一碰到要读 Private Key 的伺服器程式,都会停下来等键盘输入密码。要是放假没人,或伺服器放在 IDC 机房,从远端重开机或 Crash 后自行重开机,却当在那里等键盘敲密码,开不了机,那就不好玩了。
# 制作 RSA Private Key
openssl genrsa -out /etc/ssl/private/myhost.key 2048
chmod og-rwx /etc/ssl/private/myhost.key
2. 填写凭证申请书
凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。这里凭证名称 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她请一一填写。详情请参考「什么是凭证?」。
若不知如何填写,请参阅「如何填写凭证申请书」。
# 填写凭证申请书
openssl req -new -key /etc/ssl/private/myhost.key -out /tmp/myhost.req
3. 用最高层认证中心签发凭证[8]
伺服器凭证的效期其实无所谓,过期重签一张就好了。 SSL 程式认的是认证中心,不是凭证,所以凭证签了就会生效,不用去设定 SSL 程式。不过为免重签的麻烦,我们效期还是签 3650 天(大约十年)。
签完凭证,凭证申请书就不用了,可以删掉。
# 签发凭证
openssl x509 -req -days 3650 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_req -CA /etc/ssl/certs/myrootca.crt -CAkey /etc/ssl/private/myrootca.key -CAserial /etc/ssl/myrootca.srl -CAcreateserial -in /tmp/myhost.req -out /etc/ssl/certs/myhost.crt
# 删除凭证申请书
rm -f /tmp/myhost.req
这样就好了。[9] Private Key 在 /etc/ssl/private/myhost.key ,要小心存好保护,只有 root 才能读,建议权限为 0400 ; Public Key 凭证在 /etc/ssl/certs/myhost.crt ,要尽量散出去,让大家用。这组 Public/Private Key 凭证可以做为 myhost 的 SSL 凭证,用在 HTTPS 或 POP3S/TLS/SSL 上。最好不要把档案搬到别的地方。你可以在设定档里,把凭证位置设定到这里。 Private Key 不要到处放,以免不小心忘记保护。
若你是一般使用者:
设定 OpenSSL 的环境
# 设定相关的目录
mkdir -p ~/etc
mkdir -p ~/etc/ssl
mkdir -p ~/etc/ssl/private
chmod og-rwx ~/etc/ssl/private
mkdir -p ~/etc/ssl/certs
mkdir -p ~/etc/ssl/crl
mkdir -p ~/etc/ssl/newcerts
mkdir -p ~/tmp
# 设定 OpenSSL 设定档[10]
cp /usr/share/ssl/openssl.cnf ~/etc/ssl
# 设定 OpenSSL 设定档的位置[11]
export OPENSSL_CONF="$HOME/etc/ssl/openssl.cnf"
# 把 OpenSSL 设定档的位置加进 .bashrc 中[12]
echo "# OpenSSL 设定档的位置" >> ~/.bashrc
echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.bashrc
# 制作乱数档[13]
openssl rand -out ~/etc/ssl/private/.rand 1024
chmod og-rwx ~/etc/ssl/private/.rand
然后修改 ~/etc/ssl/openssl.cnf ,把这一行
dir = ./demoCA # Where everything is kept
改成这样
dir = ~/etc/ssl # Where everything is kept
制作最高层认证中心 (Root CA)
若你之前做过最高层认证中心,不要重做,不然原来签发的凭证,都会失效,都要重签。除非最高层认证中心自己过期、档案遗失、 Private Key 外泄,否则绝对不要重做最高层认证中心。
假设你要做的最高层认证中心叫做 myrootca 。
1. 制作 Private Key (及 Public Key )
这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。
请为最高层认证中心的 Private Key 设定一个适当的密码。
注意:伺服器的 Private Key 不要设密码,不然 SSL 伺服器程式启动的时候,一去读凭证和 Private Key ,就要问一次密码。每次重开机,依序启动每个伺服器程式的时候,一碰到要读 Private Key 的伺服器程式,都会停下来等键盘输入密码。要是放假没人,或伺服器放在 IDC 机房,从远端重开机或 Crash 后自行重开机,却当在那里等键盘敲密码,开不了机,那就不好玩了。
# 制作 RSA[14] Private Key
openssl genrsa -des3 -out ~/etc/ssl/private/myrootca.key 2048
chmod og-rwx ~/etc/ssl/private/myrootca.key
2. 填写凭证申请书
凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。请一一填写。详情请参考「什么是凭证?」。
若不知如何填写,请参阅「如何填写凭证申请书」。
若你要直接用最高层认证中心来直接当凭证用,凭证名称 (Common Name) 请用伺服器的全名 (www.abc.com) 。详情请参考「其她 SSL/X.509 凭证的做法」。
# 填写凭证申请书
openssl req -new -key ~/etc/ssl/private/myrootca.key -out ~/tmp/myrootca.req
3. 签发凭证
最高层认证中心因为没有上级了,没有人能给它签名,只能自己给自己签名。详情请参考「什么是最高层认证中心?」。
最高层认证中心最好永远不要过期。要是过期重签,所有原来它签发的凭证也都要重签,所有 SSL 程式也都要重新设定。所以我们效期签 7305 天(大约 20年)。若不设效期的话,预设是 30 天(一个月)。
签完凭证,凭证申请书就不用了,可以删掉。
# 自己给自己签名
openssl x509 -req -days 7305 -sha1 -extfile ~/etc/ssl/openssl.cnf -extensions v3_ca -signkey ~/etc/ssl/private/myrootca.key -in ~/tmp/myrootca.req -out ~/etc/ssl/certs/myrootca.crt
# 删除凭证申请书
rm -f ~/tmp/myrootca.req
这样就好了。 Private Key 在 ~/etc/ssl/private/myrootca.key ,自己签名的 Public Key 凭证在 ~/etc/ssl/certs/myrootca.crt 。 myrootca.key 是 Private Key ,要小心存好保护,只有自己才能读,权限建议 0400 。 myrootca.crt 是 Public Key 凭证,要尽量散出去,让大家用。最好放到网站上,让大家自己下载,自己加进去。
制作伺服器用的凭证
假设你要做 myhost 的凭证:
1. 制作 Private Key (及 Public Key )
这里我们做一支新的 Private Key 。 Public Key 可由 Private Key 推得,所以不用特别去做。
# 制作 RSA Private Key
openssl genrsa -out ~/etc/ssl/private/myhost.key 2048
chmod og-rwx ~/etc/ssl/private/myhost.key
2. 填写凭证申请书
凭证申请书,是把你的资料,和这个 Public Key 夹在一起,以便认证中心审核,签上签名用的。所以这个步骤,会问你这个 Key 的相关资料,包括国家、城市、单位名称、部门名称、凭证名称、联络人的信箱,以及申请的效期等等。这里凭证名称 (Common Name) 要用伺服器的全名 (www.abc.com) ,其她请一一填写。详情请参考「什么是凭证?」。
若不知如何填写,请参阅「如何填写凭证申请书」。
# 填写凭证申请书
openssl req -new -key ~/etc/ssl/private/myhost.key -out /tmp/myhost.req
3. 用最高层认证中心签发凭证[8][15]
伺服器凭证的效期其实无所谓,过期重签一张就好了。 SSL 程式认的是认证中心,不是凭证,所以凭证签了就会生效,不用去设定 SSL 程式。不过为免重签的麻烦,我们效期还是签 3650 天(大约十年)。
签完凭证,凭证申请书就不用了,可以删掉。
# 签发凭证
openssl x509 -req -days 3650 -sha1 -extfile ~/etc/ssl/openssl.cnf -extensions v3_req -CA ~/etc/ssl/certs/myrootca.crt -CAkey ~/etc/ssl/private/myrootca.key -CAserial ~/etc/ssl/myrootca.srl -CAcreateserial -in /tmp/myhost.req -out ~/etc/ssl/certs/myhost.crt
# 删除凭证申请书
rm -f /tmp/myhost.req
这样就好了。[16] Private Key 在 ~/etc/ssl/private/myhost.key ,要小心存好保护,只有自己才能读,建议权限为 0400 ; Public Key 凭证在 ~/etc/ssl/certs/myhost.crt ,要尽量散出去,让大家用。这组 Public/Private Key 凭证可以做为 myhost 的 SSL 凭证,用在 HTTPS 或 POP3S/TLS/SSL 上。
设定伺服器
常见的 SSL 通讯方式有两种:一种是传统的 SSL ,一种是新的 TLS 。
传统的 SSL ,一连上伺服器,就进入 SSL ,全程加密。这样做有一个缺点:为了不让使用者程式混淆,要把 SSL 开在另外一个 TCP 埠,还要设定使用者的程式,改连到 SSL 的那个 TCP 埠去。 HTTP 和 HTTPS 的方式就是这样。
新的 TLS ,则是在使用者程式连上伺服器后,下 STARTTLS 指令,如果伺服器有 SSL ,就会进入 SSL ,双方开始加密;如果伺服器没有 SSL ,看不懂 STARTTLS ,双方就按原来的方式继续连线。这样做的好处是,使用者程式不用改设连接埠,可以自行切入 SSL 或退回不加密连线,相容性高,也不用为了 SSL ,多开一个 TCP 埠。但 TLS 的缺点则是,就算凭证查核的结果有问题,不能做 SSL ,还是可以退回原来的方式继续连线,那凭证查核的工作,有做等於没做。只有连线加密的的优点而已,无法查证伺服器的身份。
以下依不同的通讯协定,分别讨论。
HTTP
HTTP 是最早用 SSL 的通讯协定。 Netscape 当初是为了加密 HTTP ,做安全网路交易,才设计了 SSL ,开一个新的 TCP 埠 443 给它专用,取名为 HTTPS ,延用至今。因此, HTTP 的 SSL 用的是传统的方式,没有 TLS ,要开 HTTPS(443) 。
Apache
Apache 要做 HTTPS ,可以搭配 Apache-SSL ,或搭配 mod_ssl 。请参考各自的设定说明。
要注意的是,一个 Apache 只能记一组凭证,而凭证上有伺服器的全名,浏览器会用来核对网站站名,所以一个 Apache ,也只能架一个 SSL 站,用一个站名。除非你跑很多份 Apache ,各自跑在不同的 IP 或不同的 TCP 埠上,才能在同一台伺服器上,跑好几个 SSL 站。
以 mod_ssl 来说,安装好后, httpd.conf 设定举例如下:
......
## mod_ssl.c: mod_ssl 基本设定
Listen 443
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl.crl
SSLSessionCache dbm:/var/log/apache/ssl_scache
SSLSessionCacheTimeout 300
SSLPassPhraseDialog builtin
SSLMutex file:/var/log/apache/ssl_mutex
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
SSLLog /var/log/apache/ssl_engine_log
SSLLogLevel info
SSLCipherSuite ALL:!ADH:!EXP56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile /etc/ssl/certs/myhost.crt
SSLCertificateKeyFile /etc/ssl/private/myhost.key
SSLEngine on
......
设好后,检查看 httpd.conf 有没有设错:
httpd -t
要是没有问题,重开 httpd , SSL 网站就开跑了。
POP3
POP3 可以跑两种方式:传统用 POP3S(995) 埠专跑 SSL ,或是用 TLS ,在原来的 POP3(110) 埠上,加上 STARTTLS 的功能。
POP3 的 TLS 指令是 STLS 。
Qpopper
要安装 Qpopper ,请参考 Qpopper 的说明文件。
Qpopper 可以做 POP3S(995) ,也可以在 POP3(110) 上做 TLS 。然而,一个 Qpopper 只能开一个 TCP 埠,用一种方式跑。如果要同时做 POP3S(995) 和 POP3(110)/TLS ,要跑两份 Qpopper,各自用不同的设定档。
设定 /etc/qpopper.conf 如下:
# qpopper.conf: Qpopper POP3(110)/TLS 的设定档
set clear-text-password = always
set statistics = true
set tls-support = stls
set tls-private-key-file= /etc/ssl/private/myhost.key
set tls-server-cert-file= /etc/ssl/certs/myhost.crt
设定 /etc/qpopper-s.conf 如下:
# qpopper-s.conf: Qpopper POP3S(995) 的设定档
set clear-text-password = tls
set statistics = true
set tls-support = alternate-port
set tls-private-key-file= /etc/ssl/private/myhost.key
set tls-server-cert-file= /etc/ssl/certs/myhost.crt
然后用 root 的权限,分别执行:
popper -f /etc/qpopper.conf
popper 995 -f /etc/qpopper-s.conf
这样就可以了。查看:
ps ax | grep popper
你会看到有两个 popper ,用不同的参数在跑。查看:
netstat -ap | grep popper
你会看到两个 popper ,分别在 POP3(110) 和 POP3S(995) 两个 TCP 埠上。
SMTP
SMTP 也可以跑两种方式:旧式的做法,是另开一个 SMTPS(465) 埠,来专跑 SSL 。新的做法则用 TLS ,在原来的 SMTP(25) 埠上,加上 STARTTLS 的功能。 TLS 用同一个连接埠,相容性比较高,为邮件伺服器间收发信的相容性起见,请尽量采用 TLS 。[17]
SMTP 的 TLS 指令是 STARTTLS 。
Sendmail
Sendmail 可以在编译时,加入 SMTPS 和 TLS 的支援,不过 SMTPS 是属於 FFR (for future release) 尚未正式发表的功能,在所有 Sendmail 的说明文件中,都找不到 SMTPS 的说明,只有 TLS 的说明。
Sendmail 送信时,只会在原来的 SMTP(25) 埠上,试 STARTTLS 指令。对方要是不支援 TLS 就算了,用原来不加密的方法寄信,不会去试对方的 SMTPS(465) 埠。
为让邮件顺利流通,不要掉信, Sendmail 送信时,能加密就加密,不会查核对方的凭证。更何况,在 TLS 下,查核对方的凭证,也没什么意义。
要设定 Sendmail 使用 SSL ,编译 Sendmail 时,要在 devtools/Site/site.config.m4 档,加入下列这几行:
# STARTTLS - 加入 SSL/TLS 功能
APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS')
APPENDDEF(`conf_sendmail_LIBS', `-lssl -lcrypto')
# SMTP SSL - 加入 SMTPS 功能
APPENDDEF(`conf_sendmail_ENVDEF', `-D_FFR_SMTP_SSL')
编译、安装:
# 编译 Sendmail
./Build
# 安装 Sendmail
make install
接下来要设定 Sendmail 的设定档 /etc/mail/sendmail.cf 。如果你是用 m4 来做设定档,在 m4 档 config.mc 中加入下列几行:
dnl Sendmail SMTPS/STARTTLS SSL 设定
define(`confCACERT_PATH', `/etc/ssl/certs')
define(`confCACERT', `/etc/ssl/certs/myrootca.crt')
define(`confSERVER_CERT', `/etc/ssl/certs/myhost.crt')
define(`confSERVER_KEY', `/etc/ssl/private/myhost.key')
define(`confCLIENT_CERT', `/etc/ssl/certs/myhost.crt')
define(`confCLIENT_KEY', `/etc/ssl/private/myhost.key')
DAEMON_OPTIONS(`Name=MTA')dnl
DAEMON_OPTIONS(`Port=465, Name=MTASSL, M=s')dnl
重做设定档:
m4 m4/cf.m4 config.mc > config.cf
cp -f config.cf /etc/mail/sendmail.cf
然后重开 Sendmail 。这样 Sendmail 就可以开始做 SMTPS/TLS SSL 了。查看:
netstat -ap | grep sendmail
你会看到同一个 sendmail ,跑在 SMTP(25) 和 SMTPS(465) 两个[18] TCP 埠上。
不过设定还没结束。
Sendmail 自 8.12.1 版以后,为加强安全性,将伺服器和使用者程式分开。伺服器程式因为要跑在低於 1024 的 SMTP(25) 埠,还是要由 root 来启动,以 root 的权限来执行。使用者程式则不再 setuid root ,改成 setgid smmsp[19] ,用 smmsp 群组的权限执行,再用 SMTP 连线到伺服器程式发信。
Sendmail 伺服器程式因为有 root 的权限,要读 Private Key 不是问题。可是, Sendmail 使用者程式现在没有了 root 的权限,发信的时候,就读不到我们伺服器的 Private Key 了。怎么办?
我们不要让 Sendmail setuid-root ,也不要开放伺服器 Private Key 的权限。我们可以另外做一组只有 smmsp 群组读得到的凭证,给 Sendmail 的使用者程式专用:
# 设定目录
mkdir -p /etc/mail/private
chgrp smmsp /etc/mail/private
chmod o-rwx /etc/mail/private
mkdir -p /etc/mail/certs
# 制作 RSA Private Key
openssl genrsa -out /etc/mail/private/myhost-msp.key 2048
chgrp smmsp /etc/mail/private/myhost-msp.key
chmod o-rwx /etc/mail/private/myhost-msp.key
# 填写凭证申请书
openssl req -new -key /etc/mail/private/myhost-msp.key -out /tmp/myhost-msp.req
# 签发凭证
openssl x509 -req -days 3650 -sha1 -extfile /etc/ssl/openssl.cnf -extensions v3_req -CA /etc/ssl/certs/myrootca.crt -CAkey /etc/ssl/private/myrootca.key -CAserial /etc/ssl/myrootca.srl -CAcreateserial -in /tmp/myhost-msp.req -out /etc/mail/certs/myhost-msp.crt
# 删除凭证申请书
rm -f /tmp/myhost-msp.req
然后设定 m4 档 submic.mc 如下:
......
dnl Sendmail STARTTLS SSL/TLS support
define(`confCACERT_PATH', `/etc/ssl/certs')
define(`confCACERT', `/etc/ssl/certs/myrootca.crt')
define(`confCLIENT_CERT', `/etc/mail/certs/myhost-msp.crt')
define(`confCLIENT_KEY', `/etc/mail/private/myhost-msp.key')
define(`confDONT_BLAME_SENDMAIL', `GroupReadableKeyFile')
......
重做设定档:
m4 m4/cf.m4 submit.mc > submit.cf
cp -f submit.cf /etc/mail/submit.cf
这样就可以了。这不是设定 Sendmail 伺服器程式,不用重开 Sendmail 。 ^_*' 你可以寄一封信给自己,然后看看系统邮件记录 maillog ,有没有成功使用 SSL 。
......
Sep 14 04:19:24 rinse sendmail[12093]: STARTTLS=client, relay=localhost.localdom
ain., version=TLSv1/SSLv3, verify=OK, cipher=EDH-RSA-DES-CBC3-SHA, bits=168/168
......
设定作业系统
有些作业系统,设有系统公用的凭证库,把认得的凭证、认证中心放在一起。我们把我们自制的认证中心,加进系统公用的凭证库,使用这个凭证库的程式,就可以查得到了。
MS-WINDOWS
MS-WINDOWS 设有共用的凭证库。从 [控制台] 进去,里面有 [网际网路选项] (或 [Internet 选项] )。在上面点两下,会打开一个[网际网路 内容] (或 [Internet 内容] )的视窗。在 [内容] 那一页里,中间有一区 [凭证] ,里面有一个 [凭证(C)...] 的按钮。按一下那个按钮,会打开一个视窗,标题是 [凭证] 。这里就是 MS-WINDOWS 管理凭证的地方。[20]
要加进我们的最高层认证中心,将我们的最高层认证中心 myrootca.crt 复制到 WINDOWS 上。点两下打开 myrootca.crt ,会跳出一个 [凭证] 的视窗,里面会列出凭证的内容。按下面的 [安装凭证]按钮,会跑出一个 [凭证管理员汇入精灵] 。一直按 [下一步] ,就会加进去了。
我所知道,会使用系统凭证库的 WINDOWS 程式,有 Internet Exporer 、 Outlook Express 、 Outlook 、 Symantec pcAnywhere 。只要把我们自制的认证中心加进来,这些程式都可以用得到。
设定浏览器
Mozilla 与 Netscape 6 以后的版本
Mozilla 与 Netscape 6 以后的版本,有一个浏览器和邮件程式共用的凭证库。从工具列上的 [编辑(E)] 、 [个人功能设定(E)] 进去后,会跳出 [功能设定] 的视窗。展开视窗左边的 [个人及安全设定] ,点选里面的 [认证] ,右边的标题会切换成 [认证] ,中间会有一个 [管理认证...] 的按钮。按下按钮,会再跳出一个 [认证管理员] 的视窗。这里就是 Mozilla 与 Netscape 管理凭证的地方。[21][22]
要加进我们的最高层认证中心,将我们的最高层认证中心 myrootca.crt 放到网站上,用 Mozilla/Netscape 从 web 连到该网址后,会出现一个 [下载认证中] 的视窗。在 [信认此认证以识别网站] 、 [信认此认证以识别邮件用户] 、 [信认此认证以识别软体制造商] 三个选项上都打勾,然后按 [确定] ,就会加进去了。
如果你用的是 MS-WINDOWS 下的 Mozilla/Netscape ,你也可以把最高层认证中心复制到 WINDOWS 上,网址列直接打上档案路径,也可以把它加进去。
在 Mozilla/Netscape 浏览器加进来的认证中心,也会用在 Mozilla 信件或 Netscape Mail & Newsgroups 里,来查核凭证。
Internet Explorer
Internet Explorer 使用 WINDOWS 系统的凭证库,你只要把认证中心加进系统的凭证库就可以了。详情请参考「设定 MS-WINDOWS」。
Opera
Opera 截至目前为止 (6.05) ,只支援 RSA ,不支援 DSA 。因此,只能汇入 RSA 认证中心,不能汇入 DSA 认证中心。
打开 Opera ,从工具列上的 [档案(F)] 、 [功能设定(R)...] 进去后,会打开 [功能设定] 的视窗。在视窗左边的选单中,选最下面的 [安全性] 时,右上角会出现 [认证机构(A)...] 的按钮。按下按钮,会再打开 [认证机构] 的视窗。按一下右上角的 [汇入(I)...] 按钮,找到我们的最高层认证中心,按 [开启] ,就会加进去了。
Lynx
Lynx 截至目前为止 (2.8.4) ,不会检查伺服器的 SSL 凭证。
设定电子邮件程式
Mozilla 与 Netscape 6 以后的版本
要设定使用 SSL 收信,启动 Mozilla 信件与 News 或 Netscape Mail & Newsgroups 后,由工具列上的 [编辑(E)] 、 [信件与 News 帐号设定(M)...] 按下去,会打开一个 [信件与 News 帐号设定] 的视窗。在左边选择你要设定的帐号下的 [伺服器设定] 。视窗右边的 [伺服器名称:] 中,要填上 POP3 邮件伺服器的完整名称。在右下方 [伺服器设定] 里的 [使用 SSL 安全连线] 选项上打勾,然后按 [确定] 。这样就会用 SSL 收信了。
要设定使用 SSL 寄信,启动 Mozilla 信件与 News 或 Netscape Mail & Newsgroups 后,由工具列上的 [编辑(E)] 、 [信件与 News 帐号设定(M)...] 按下去,会打开一个 [信件与 News 帐号设定] 的视窗。在左边选择 [SMTP 外寄邮件伺服器] ,右边标题会变成 [SMTP 外送邮件伺服器设定] 。右边中间有一个 [使用 SSL 安全连线] ,选 [若可以时] 。然后按 [确定] 。这样就会用 SSL 寄信了。
凭证查核的部份,Mozilla 信件与 News 或 Netscape Mail & Newsgroups 使用 Mozilla 或 Netscape 6 的凭证库,你只要把认证中心加进 Mozilla 或 Netscape 6 就可以了。详情请参考Mozilla 与 Netscape 6 的设定。
Netscape 4 及更早的版本
Netscape 4 及更早的版本不支援 SSL 。
Outlook Express 6
要设定使用 SSL 收信,启动 Outlook Express 后,由工具列上的 [工具(T)] 、 [帐户(A)...] 按下去,会打开一个 [网际网路帐户] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [内送邮件 - POP3(I):] 中,要填上 POP3 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [内送邮件 - POP3(I):] 下面的 [这个伺服器需要安全连线 - SSL(C)] 的选项上打勾。然后按 [确定] 、 [关闭] 。这样就会用 SSL 收信了。
要设定使用 SSL 寄信,启动 Outlook Express 后,由工具列上的 [工具(T)] 、 [帐户(A)...] 按下去,会打开一个 [网际网路帐户] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [外寄邮件 - SMTP(U):] 中,要填上 SMTP 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [外寄邮件 - SMTP(O):] 下面的 [这个伺服器需要安全连线 - SSL(Q)] 的选项上打勾,并把上面 [外寄邮件 - SMTP(O):] 的连接埠号码改为 465 。然后按 [确定] 、 [关闭] 。这样就会用 SSL 寄信了。
凭证查核的部份, Outlook Express 6 使用 WINDOWS 系统的凭证库,你只要把认证中心加进系统的凭证库就可以了。详情请参考「设定 MS-WINDOWS」。
Outlook Express 5.5
要设定使用 SSL 收信,启动 Outlook Express 后,由工具列上的 [工具(T)] 、 [帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [内送邮件 - POP3(I):] 中,要填上 POP3 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [内送邮件 - POP3(I):] 下面的 [这个伺服器需要安全连线 - SSL(C)] 的选项上打勾。然后按 [确定] 、 [关闭] 。这样就会用 SSL 收信了。
要设定使用 SSL 寄信,启动 Outlook Express 后,由工具列上的 [工具(T)] 、 [帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [外寄邮件 - SMTP(U):] 中,要填上 SMTP 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [外寄邮件 - SMTP(O):] 下面的 [这个伺服器需要安全连线 - SSL(Q)] 的选项上打勾,并把上面 [外寄邮件 - SMTP(O):] 的连接埠号码改为 465 。然后按 [确定] 、 [关闭] 。这样就会用 SSL 寄信了。
凭证查核的部份, Outlook Express 5.5 使用 WINDOWS 系统的凭证库,你只要把认证中心加进系统的凭证库就可以了。详情请参考「设定 MS-WINDOWS」。
Outlook Express 4 或 5
要设定使用 SSL 收信,启动 Outlook Express 后,由工具列上的 [工具(T)] 、 [帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [内送邮件 - POP3(I):] 中,要填上 POP3 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [内送邮件 - POP3(I):] 下面的 [这个伺服器需要安全连线 - SSL(C)] 的选项上打勾。然后按 [确定] 、 [结束] 。这样就会用 SSL 收信了。
要设定使用 SSL 寄信,启动 Outlook Express 后,由工具列上的 [工具(T)] 、 [帐号(A)...] 按下去,会打开一个 [Internet 帐号] 的视窗。在视窗左边选择要设定的帐号,然后按下右边的 [内容(P)] 按钮,会打开另一个 [某某某 内容] 的视窗。按一下上方的 [伺服器] ,翻到 [伺服器] 那一页。在 [外寄邮件 - SMTP(U):] 中,要填上 SMTP 邮件伺服器的完整名称。再按一下上方的[进阶] ,翻到 [进阶] 那一页。在 [外寄邮件 - SMTP(O):] 下面的 [这个伺服器需要安全连线 - SSL(Q)] 的选项上打勾,并把上面 [外寄邮件 - SMTP(O):] 的连接埠号码改为 465 。然后按 [确定] 、 [关闭] 。这样就会用 SSL 寄信了。
Outlook Express 4 与 5 不会检查伺服器的 SSL 凭证。
Eudora 5.1 以后的版本
Eudora 的 SSL 设计不是很好。
Eudora 5.1 以后有一个 [Certificate Infomation Manager] 凭证管理员,可以管理 Eudora 的凭证。可是很奇怪,没有办法直接进入 [Certificate Infomation Manager][23] ,要先用 SSL 收一次信,才能进入 [Certificate Infomation Manager] 。[24]
收信的时候, Eudora 会用 STARTTLS 试探看能不能用 SSL 收信,如果可以的话就切换成 SSL ,不然就继续用普通的 POP3 收信,所以不用特别设定收信的方式。不过这样反而会造成困扰:如果切换成 SSL 以后, Eudora 却查不到对方的凭证,反而会演变成凭证无效,停止收信。这时候,原本 POP3 正常收的信,伺服器加上 SSL 后, Eudora 突然不能收信,会造成使用者很大的困扰。这是 Eudora 另一个不良的设计。
请注意: OpenSSL 预设是做 PEM 格式的凭证,所以先前我们做的都是 PEM 格式的凭证。但 Eudora 只能汇入 DER 凭证格式。 PEM 只是把 DER 用 Base64 编码,以方便在网路上传送,放在网页上或用 E-mail 寄。我们可以用 OpenSSL 把 PEM 转 DER :
# 将最高层认证中心转成 DER 档
openssl x509 -in myrootca.crt -outform der -out myrootca-der.crt
要设定使用 SSL 收信,启动 Eudora 后,由工具列上的 [Tools] 、 [Options...] 按下去,会打开一个 [Options] 的视窗。在左边的 [Category] 中选择 [Checking Mail] 。视窗右边的 [Mail Server:] 中,要填上 POP3 邮件伺服器的完整名称。右下方有一个 [Secure Sockets when Receiving:] 的选单,选 [If available, STARTTLS] 后,按 [OK] 。这样就会用 SSL 收信了。
要设定使用 SSL 寄信,启动 Eudora 后,由工具列上的 [Tools] 、 [Options...] 按下去,会打开一个 [Options] 的视窗。在左边的 [Category] 中选择 [Sending Mail] 。视窗右边的 [Mail Server:] 中,要填上 SMTP 邮件伺服器的完整名称。右下方有一个 [Secure Sockets when Receiving:] 的选单,选 [If available, STARTTLS] 后,按 [OK] 。这样就会用 SSL 寄信了。
要加入我们的认证中心,要先收一次信。视窗下面会显示 [SSL Negotiation Failed: Certificate Error: Cert Chain not trusted. ...] 的错误讯息。依前述方式回到 [Tools] 、 [Options...] 、 [Category] 、 [Checking Mail] 、 [Secure Sockets when Receiving:] 后,按一下 [Last SSL Info] ,以开启 [Eudora SSL Connection Infomation Manager] 的视窗,显示刚刚收到的凭证内容。按一下下面的 [Certificate Infomation Manger] 按钮,会再跳出一个 [Certificate Infomation Manger] 的视窗。按一下右下角的 [Import Certificate] ,找到我们的最高层认证中心的 DER 档 myrootca-der.crt ,按 [开启] ,就会加进去了。[25]
Becky!
Becky! 因为 SSL 版权费用的问题,作者已经公开宣布不会支援 SSL 。不过我们可以利用 Stunnel SSL 包装程式,透过 SSL 连线来收发信。详情请参考「设定其她不支援 SSL/TLS 的程式」。
Opera 邮件
要设定使用 SSL 收信,打开 Opera ,从工具列上的 [档案(F)] 、 [功能设定(R)...] 进去后,会打开 [功能设定] 的视窗。在视窗左边的选单中,选 [电子邮件] 时,右边会出现 [使用 Opera 的帐号(O)] 的选单。选择要设定的帐号,然后按旁边的 [更改(P)...] ,会跳出一个 [邮件帐号设定] 的视窗。在上面的 [伺服器] 上按一下,切换到伺服器那一页,在 [内收邮件] 里 [采用 TLS 安全性协定] 的地方打勾,按 [确定] 、 [确定] 。这样就会用 SSL 收信了。
要设定使用 SSL 寄信,打开 Opera ,从工具列上的 [档案(F)] 、 [功能设定(R)...] 进去后,会打开 [功能设定] 的视窗。在视窗左边的选单中,选 [电子邮件] 时,右边会出现 [使用 Opera 的帐号(O)] 的选单。选择要设定的帐号,然后按旁边的 [更改(P)...] ,会跳出一个 [邮件帐号设定] 的视窗。在上面的 [伺服器] 上按一下,切换到伺服器那一页,在 [外寄邮件] 里 [采用 TLS 安全性协定] 的地方打勾,按 [确定] 、 [确定] 。这样就会用 SSL 寄信了。
凭证查核的部份, Opera 邮件使用 Opera 的凭证库,你只要把认证中心加进 Opera 就可以了。详情请参考 Opera 的设定。
设定其她不支援 SSL/TLS 的程式
「我的程式不支援 SSL/TLS ,怎么办?」
没有关系。我们可以用 SSL 包装程式,先和伺服器建立 SSL 连线,再将程式送的指令,透过这个 SSL 连线转送给伺服器,并将伺服器在 SSL 连线中的回应,转送回来。这样一来,即使程式本身不懂 SSL ,也可以透过这个 SSL 连线,来加密收送的资料。以下,我们介绍 SSL 包装程式。
Stunnel
Stunnel 的网站在 http://www.stunnel.org/ ,可以从网站上下载。在 WINDOWS 下,是很简单好用的 SSL 包装程式。 WINDOWS 下的简易使用方式说明如下:
从网站 http://www.stunnel.org/ 上下载 stunnel-x.xx.exe 、 libssl32.dll 和 libeay32.dll 。
把 libssl32.dll 和 libeay32.dll 存到 C:\WINDOWS\SYSTEM (WINDOWS 98/ME) 或 C:\WINNT\SYSTEM32 (WINDOWS NT/2000/XP) 下。
在 C:\Program Files 下新增一个 Stunnel 的目录,把刚刚下载的 stunnel-x.xx.exe 存进这里。
在 C:\Program Files\Stunnel 中新增一个档案 stunnel.conf ,内容举例如下:
client = yes
[pop3s]
accept = localhost:50110
connect = my.mail.server:995
[smtps]
accept = localhost:50025
connect = my.mail.server:465
启动 C:\Program Files\Stunnel\stunnel-x.xx.exe 。它会缩到桌面下方工具列的最右边,变成一个小图示。这时如果开启 [MS-DOS 模式] 或 [命令提示字元] ,打:
netstat -an
会看到类似:
TCP127.0.0.1:500250.0.0.0:0 LISTENING
TCP127.0.0.1:501100.0.0.0:0 LISTENING
的两行。按两下 Stunnel 在工具列右边的小图示,会显示 Stunnel 的使用记录。
启动程式,修改程式的设定,将原来 SMTP 连到 my.mail.server 连接埠 25 的地方,改连到 localhost 连接埠 50025 ;原来 POP3 连到 my.mail.server 连接埠 110 的地方,改连到 localhost 连接埠 50110 。
收、发信。
这样应该就可以了,原本不会 SSL 的程式,现在可以透过 Stunnel 使用 SSL 连线了。
这只是 Stunnel 的基本功能。 Stunnel 还有很多强大的功能,不但可以转送 POP3 、 SMTP 、 IMAP 、 NNTP 、 LDAP …… 等各种通讯协定,也可以将 SSL 连线,转送给不会 SSL 的伺服器程式。这样即使反过来,伺服器程式本身不会 SSL ,使用者也可以使用 SSL 加密连线。详细的做法,请下载 Stunnel 的原始程式码,参照内附的完整操作说明。
不过 Stunnel 有一个很大的限制:因为 Stunnel 只负责先建立好 SSL 连线,并不了解通讯协定本身的指令语法,所以无法用 STARTTLS 指令建立 TLS 连线,只能用传统的方式,一开始就建立全程的 SSL 连线。
SSL/X.509 简介
X.509 的金字塔制度
SSL 采用的是 X.509 ,由上而下金字塔式的凭证制度。
在 X.509 中,每一个合格的凭证上,都会有一个签名。最下层的凭证上,会有一个认证中心 (CA) 的签名,表示这个认证中心 (CA) 检查过,确认所有者资料无误。中间的认证中心 (CA) 上,也会有管辖它的最高层认证中心 (Root CA) 的签名,表示最高层认证中心授权给它,可以签发别人的凭证。只有最高层认证中心上,因为它已经是最大,没有再上层可以给它签名了,所以只好自己签自己,凭证上的签名是自己签的。
程式自己会认得几家可靠的认证中心 (CA) ,碰到 SSL 网站时,虽然不认得伺服器的凭证 (Certificate) ,但只要那个凭证上,有自己认得的认证中心 (CA) 签名保证过,那个凭证就没有问题。
当程式碰到合格的 SSL 凭证
但如果那个伺服器凭证上,没有自己认得的认证中心 (CA) 签名保证过,伺服器凭证就有可能有问题,会出现凭证无效的警告。
当程式碰到有问题的 SSL 凭证
凭证无效的警告
本文第一步讨论的是如何自制最高层认证中心 (Root CA) 。因为这是我们自己的认证中心,程式不认得,所以第二步签发的凭证 (Certificate) 上的签名,程式自然也不认得,一定会出现凭证无效的警告。
当程式碰到我们自制的认证中心
若不想看到这个警告,就要先让程式认得我们自己的认证中心 (CA) 。这时,第二步签发的凭证 (Certificate) ,程式认得上面认证中心 (CA) 的签名,就不会再出现凭证无效的警告。
把我们自己的认证中心加上去
详细做法,请参考「设定作业系统」、「设定浏览器」与「设定电子邮件程式」各节。
请注意:这个方法,因为要在程式上,手动加入自己的认证中心 (CA) ,所以只有自己内部用的网站,使用者和程式数目都有限,可以自己一个一个去设认证中心 (CA) 的情况下,方才可行。若要用在公开的网站上,因为上网者来自各个不同的地方,你也都不认识,没有办法在她们的电脑上,都加进自己的认证中心,就没有办法了。这一点受限於 X.509 的规定,爱莫能助。若真的很在意 SSL 凭证无效警告的问题,又需要在公开的网站使用 SSL ,请向各家签证公司申请,年费大概几万元台币。
资料?什么资料?
「等等,刚刚图中的最后一个步骤,『没问题,这是给你的资料』。使用者还没有填什么资料啊!程式怎么可以自己乱给对方资料呢?到底给了什么资料?程式会不会自己给对方 E-mail 、信用卡号码、身份证字号、密码?」
程式传给对方的,是接下来通信时,对称式加解密用的 Key 。
Public/Private Key 的不对称加解密法 (Asymmetric Encryption) ,可以把 Public Key 告诉全世界, Private Key 自己秘密保管好,要传资料给你的话,只要用你的 Public Key 加密,全世界就只有你的 Private Key 才解得开。这种不对称加解密法虽然很安全,但是加解密的速度很慢。反过来说,传统的对称式加解密法 (Symmetric Encryption) ,虽然加解密速度快多了,但是双方都要握有同一个 Key ,把 Key 传给对方途中,会有被拦截监听的危险。
SSL 采用两阶段式的作法:第一阶段,先用 Public/Private Key 不对称加解密法,传给对方「接下来传真正资料时,对称式加解密法要用的 Key 」。第二阶段,再用这个对称式加解密的 Key ,来传原本要传的资料。真正传资料时用的,其实是对称式加解密法。这个传资料用的对称 Key 是用乱数取的,再用 Public/Private Key 法传给对方,每一次连线时都不一样。用这种两阶段式的作法, Key 是用不对称加解密法传给对方的,不用担心中途被栏截,也能够享受合理的加解密速度。
所以 SSL 就安全了罗?
「所以,只要对方 SSL 网站的凭证合格,上面有可靠的认证中心 (CA) 签名,把我的信用卡资料传过去就安全罗?」
不对。
仔细看看前段「 SSL/X.509 简介 」,就会注意到, SSL/X.509 规定中,认证中心 (CA) 的签名所保证的,只有「这个 Public Key 凭证的确是属於这家公司的这个伺服器」而已。也就是说,它只保证「你送的信用卡号码会确确实实交到这家公司的这个伺服器手中,不怕被任何人中途拦截监听」。但这并不代表「这家公司是优良企业,收到你的信用卡资料后,不会滥用,不会侧录下来,不会多刷两笔,不会转手把资料卖给别家公司」 ,也不代表「这家公司的伺服器安全防护做得很好,不会被人入侵,不会被人偷偷安装侧录上网资料的程式」。
没错, SSL 只能保证收到的 Public Key 凭证不是伪造的,但不能保证这家公司本身没有问题。就算这家公司本身没有问题,也不能保证这家公司内部会不会成为别人入侵、窃取资料的目标。
「那怎么办?怎么样才能算安全?才能放心把资料传过去?」
就像在实体世界,跟不认识的商店买东西时,一定会保持戒心一样,在网路上和任何网站交易,也一定要保持戒心,除了要考虑你平常信不信任这个网站外,也要考虑你传过去的资料重不重要。举例来说,留言板、讨论区、网路投票等等,不是很私人的资料,可以放心传过去没问题;但如果是真实姓名、手机号码、家里电话、信用卡号码, E-mail 等等,就只能传给自己信任的网站了。
什么是数位签名?
数位签名是用 Private Key ,针对某一段资料,用 Digest Hash 演算法(如 SHA1 )做出来的一段 Digest 摘要码。只要原来的资料有所不同,演算出来的 Digest 摘要码就会跟著变动。用 Private Key 做出来的 Digest 摘要码,可以用它的 Public Key 来检查。只要用它的 Public Key ,检查 Digest 摘要码和那一段资料符不符合,就可以知道资料有没有中途被窜改过,是不是这个 Private Key 当初签的那一段资料。
这个性质很像合约中,在整份合约上大大签一个名一样,人家认得你签名的笔迹,日后只要合约有任何涂改,一认便知。所以我们把它叫做数位签名。
因为数位签名可以用来检查资料有没有被窜改,所以我们把它用在凭证上,认证中心检查过 Public Key 的所有人,和 Key 上记载的所有人资料相符后,用认证中心自己的 Private Key ,在这些资料上面做个数位签名,表示证明。日后收到这个 Public Key 的人,只要检查上面认证中心的签名,就可以知道这个 Key ,和它上面所载的所有人资料相不相符,是不是真的是这家公司的 Key 。也就知道,连上的这个伺服器,是不是真的是这家公司的伺服器了。
什么是凭证?
凭证的原文是 Certificate ,是附上所有人 (owner) 的资料(公司名称、伺服器名称、个人真实姓名、连络 E-mail 、通讯地址等资料),后面加上数位签名的 Public Key 。凭证上会附有几个数位签名,代表这些签名的人,确认过这个 Public Key 的所有人,和凭证上所载的资料相符,没有假造。
在 X.509 中,最下层每一个合格的凭证 (Certificate) 上,会有一个认证中心 (CA) 的签名,表示这个认证中心 (CA) 检查过,确认凭证上的所有者资料无误。当程式碰到没见过的凭证时,只要检查凭证上认证中心 (CA) 的签名无误,即代表这个认证中心 (CA) 查核过这个凭证 (Certificate) ,凭证上的资料无误。
什么是认证中心?
认证中心的原文是 CA ,是 Certificate Authority 的缩写,在微软繁体中文 WINDOWS 上译成「凭证授权」,「凭证授权」完全是逐字翻译,意思不通,不用。认证中心是 X.509 的一环。认证中心也是一种凭证,上面附有认证中心本身的资料,但不是用来加解密,而是用来签发凭证,证明凭证所有人和凭证上所载的资料无误。请参见「SSL/X.509 简介」的附图。
每一个合格的认证中心 (CA) (微软繁体中文 WINDOWS 上译成「中继凭证授权」,意思不通)上,会有一个管辖它的最高层认证中心 (Root CA) 的签名,表示最高层认证中心授权给它,可以签发别人的凭证。当程式碰到没见过的凭证,凭证上签名的认证中心 (CA) 也没见过时,只要检查认证中心上附的最高层认证中心 (Root CA) 的签名无误,即代表这个最高层认证中心 (Root CA) ,认为这个认证中心 (CA) 的凭证签发过程很仔细,检查资料很详实,所以授权给它,准许它可以签发凭证 (Certificate) 。所以这个认证中心 (CA) 签发的凭证 (Certificate) ,凭证上的资料也没有问题。
什么是最高层认证中心?
最高层认证中心的原文是 Root CA ,在微软繁体中文 WINDOWS 上译成「根目录凭证授权」。「根目录」只是照 Root 这个字逐字翻译,意思不通,不用。最高层认证中心是 X.509 的一环。最高层认证中心也是认证中心 (CA) ,和一般认证中心的差别在於,它不会直接用来签发凭证,而是授权给一些中间的认证中心,让这些中间的认证中心来签发凭证。请参见「SSL/X.509 简介」的附图。
最高层认证中心,因为已经是最大,没有再上层可以给它签名了,所以凭证上的是自己的签名,不是别人的签名。因为最高层认证中心没有再上面的签名了,没有人可以保证最高层认证中心本身有没有问题,没有办法再往上检查,所以程式只能事先就认得一些可靠的最高层认证中心,事先就知道一些可靠的最高层认证中心的 Public Key 。
最高层认证中心只能由一些著名、可靠的公司来担任,因为没有办法再往上查验。如果程式被加进一些不可靠的最高层认证中心,接下来碰到它签下来的凭证,都会有问题,整个程式的安全都会被破坏。所以在 X.509 下, SSL 程式一定要好好保护最高层认证中心,一定要再三确认,不可以随便让人手动加进最高层认证中心。
如何填写凭证申请书
如果你不知道该如何填写凭证申请书,请参考以下范例:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:TW
State or Province Name (full name) [Some-State]:Taiwan
Locality Name (eg, city) []:Taipei City
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Tavern IMACAT's
Organizational Unit Name (eg, section) []:Owner
Common Name (eg, YOUR name) []:Tavern IMACAT's
Email Address []:imacat@mail.imacat.idv.tw
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
所有资料都要填英文 (ASCII 字集) 。 X.509 凭证只接受英文 ASCII 字集的字。
Country Name 一定要是大写的双字母国码,台湾是 TW ,台湾以外的地方,请参考 ISO-3166 的标准双字母国码。
State Name 是国名或省名,不可以填国码。台湾填 Taiwan 即可。
Locality Name 是地名,填所在地县市名即可。
Organization Name 是组织单位名称,填公司行号,或学校局处的名称。
Organizational Unit Name 是部门名称,填公司部门名称,或学校局处的单位名称。
Common Name 是凭证的名称。若是最上层凭证机构,请填上前面填的组织单位名称,后面可以加上 RSA/2048 ,以便日后辨认凭证的性质。若是伺服器凭证,请填上伺服器的全名 (www.abc.com) 。若是 E-mail 凭证,请填上你的 E-mail 。
E-mail Address 是申请单位的连络信箱,请填上你的联络用 E-mail 。
A challenge password 是申请书的密码。不过申请书不用设密码,所以不填。
An optional company name 是凭证代办公司的名称,也不用填。
X.509 凭证制度的检讨
X.509 凭证制度,是靠事先认得一些可靠的最高层认证中心,再一层一层签发下来的金字塔型结构。这样的制度,很像信用卡制度或身份证制度:
这样的金字塔结构,有好有坏。
好处在於,在无限宽广的网际网路上,我们根本不知道会碰到什么样的网站,所以根本也无从查认每一个收到的 Public Key 有没有问题,是不是真的是这家公司的网站,我是不是真的是跟这家公司打交道。在 X.509 下,只要我们预先认得几家可靠的最高层认证中心就好了。碰到不认识的 Public Key 时,只要一层一层往上追溯,如果最后追溯得到一个我们认得的可靠的最高层认证中心,那这个 Public Key 就没有问题了。这样的做法,简化了无限宽广的网际网路上,确认彼此身份的困难性。
缺点则在於,因为 X.509 是金字塔结构,最高层认证中心 (Root CA) 手中握有整个网际网路信任关系的关键,权力太大了。庞大的权力,伴随著的是庞大的利益。曾经跟认证中心打过交道(如 VeriSign 、 HiTrust 网际威信、Taica 台湾网路认证等)的人都知道,申请签发 SSL 凭证非常贵,一年年费要好几万,普通人或中小企业,需要 SSL 网站加密的时候,根本就负担不起。而因为金字塔顶层的最高层认证中心,是垄断事业,数目很少,不会有什么竞争,所以大型的最高层认证中心姿态都很高,年费一直降不下来。但若不靠这些最高层认证中心,自己来发证,程式没有内建我们自制的认证中心,连到 SSL 站上,一定会出现警告。小组织里内部自用的 SSL 伺服器还没有问题,我们可以自己加入自制的认证中心,但大型公开的伺服器(像公司网站)上,不可能要不认识的上网者信任我们的认证中心,把我们的认证中心加进去,这时候资料的安全,就会亮起红灯了。到头来,我们还是得回过头去,求这些大型的认证中心,乖乖缴一年好几万的年费。
这真的没有办法吗?
答案是否定的。即使是 X.509 的金字塔结构,至少就有两条路:第一条路是像信用卡制度一样。信用卡制度也是金字塔结构,顶层的信用卡集团也是垄断事业,数目很少,可是信用卡的年费只有几千块钱。有竞争就会降价,但没有竞争,并不代表价格一定降不下来。价格其实还是卡在认证中心如何定价,信用卡制度就是一例。第二是像身份证一样,由政府出面经营,以政府的信用担保、审核,把它变成免费的公用事业,让大家有钱没钱,都可以来用安全的网站交易。
不过,仔细想想,我们是不是一定要用 X.509 这种金字塔制度,任这些顶层的认证中心宰割,予取予求呢?
其实凭证有好几种。有一种叫做 PGP ,是采用「信任网 (Web of Trust) 」的模式,建立信任关系。 PGP 的信任网就像人际关系网一样:我认得你,你认得她,所以我只要请你来认她就好了。
PGP 的信任网
在 PGP 信任网模式下,我们不需要一个最高层认证中心,给每个人核发凭证,才能取得 Public Key 的安全性。我们只要信任我们自己的 Public Key 凭证,用自己的凭证去签认识的 Public Key 的凭证,别人也用他们自己的凭证,去签他们认识的人的凭证,往外一层一层扩散出去,互相信任。碰到不认得的凭证时,只要能够从他凭证上的签名中,回溯到可信任的人的凭证身上,就可以了。其实事情本来就是这样。我们为什么要向别人缴一年好几万的年费,还要别人签名,才能信任自己的凭证呢?
不过,不合理的是, SSL 规定,要用 X.509 。
其她 SSL/X.509 凭证的做法
在本文中,我们做了两个凭证:一个是 Root CA 最上层认证中心,一个是用这个最高层认证中心签发的凭证。
其实完整的话,应该要做三层(参考:「SSL/X.509 简介」中的附图):最高层认证中心 (Root CA) ,中间的认证中心 (CA) ,最后才签发下面的凭证。可是我不会做中间的认证中心, ^^; 完整的三层挺复杂的。而且,最高层认证中心 (Root CA) 只是「不会」用来直接签凭证,而不是「不能」用来直接签凭证,最高层认证中心 (Root CA) 签的凭证,一样有效。更何况,我们通常都只有几台伺服器,只需要几个凭证就好,不需要授权好几个中间的认证中心,来让它们签凭证。所以我们就省略了中间的认证中心,直接用最高层认证中心 (Root CA) 来签发凭证 (Certificate) 。
其实还有两个不那么麻烦的做法。 Apache mod_ssl 有随附一个「印度蛇油公司 (Snake Oil) 」的最高层认证中心 (Root CA) ,内有印度蛇油 (Snake Oil CA) 的 Private Key ,可以直接用印度蛇油认证中心 (Snake Oil CA) 的名义来签发凭证。只要在编译 apache 时, make 以后打 make certificate ,就会自动用印度蛇油认证中心,签发 Apache 网站所需的伺服器凭证了。可是,基於安全上的理由,你只能够用这张签出来的网站凭证,绝对不可以把印度蛇油认证中心 (Snake Oil CA) ,加到程式认得的认证中心中。因为印度蛇油的 Private Key 是随著 Apache mod_ssl 公开散布的,任何人只要下载 Apache mod_ssl ,里面就会有印度蛇油的 Private Key ,就可以用印度蛇油的名义来签凭证,自称为某某公司。印度蛇油的可靠度是零,绝对不要加进程式中。(所以才叫做印度蛇油 Snake Oil ,骗人的。)
另一个方法,是只做一个最高层认证中心 (Root CA) ,直接用这个最高层认证中心,来当伺服器的凭证。因为最高层认证中心 (Root CA) 本身,也是一个凭证,所以当然也可以用,一样有效。这时候,最高层认证中心的所有人名称,就要用伺服器的名称 (www.abc.com) ,而不是单位的名称 (ABC Corporation.) 。这个方法,适合只有一个伺服器,只需要一个凭证,而且不在乎凭证名称的人。用 Windows NT/2000 的 Certificate Server 凭证伺服器,可以做出这种凭证。但如果有好几台伺服器,每个凭证都要分别去加到每台电脑上,这个方法就不大方便了。
注释
FHS 是指 Filesystem Hierarchy Standard 档案系统阶层标准,是一个 Unix 下,目录及档案存放位置的标准规定,以方便系统管理员管理,方便不同程式间互相搭配整合。目前大多数 Linux 版本(如 Debian 、 Red Hat 、 Mandrake 等)都已支援 FHS 。更进一步的资料请参考 FHS 的网站 http://www.pathname.com/fhs/ 。 (回正文)
Opera 截至目前为止 (6.05) ,只支援 RSA ,不支援 DSA 。 (回正文)
在 Mandrake 下装 RPM 时,请改用:
mv /usr/lib/ssl/openssl.cnf /etc/ssl
ln -s /etc/ssl/openssl.cnf /usr/lib/ssl/openssl.cnf
(回正文)
这是 bash 或 zsh 的指令。 csh 或 tcsh 下,请改用:
setenv OPENSSL_CONF "/etc/ssl/openssl.cnf"
(回正文)
这样以后登入的时候,都能够自动设定 OPENSSL_CONF 。这是用 bash 登入的情形,若用 csh 或 tcsh 登入,请改用:
echo "# OpenSSL 设定档的位置" >> ~/.cshrc
echo "setenv OPENSSL_CONF \"/etc/ssl/openssl.cnf\"" >> ~/.cshrc
若用 zsh 登入,请改用:
echo "# OpenSSL 设定档的位置" >> ~/.zshenv
echo "export OPENSSL_CONF=\"/etc/ssl/openssl.cnf\"" >> ~/.zshenv
(回正文)
(感谢网中人 (netman) 提供)若你安装的是 Red Hat 的 openssl RPM ,在这里会出一点问题。 Red Hat 的 openssl 做 rand 指令,配合 -out 参数时,参数解析会出错,无法执行。目前我还没有看到网路上有人提过这件事。解决方法之一,是自己编译、安装 OpenSSL 。这其实很简单。在 Linux 上,步骤如下:
./config shared --prefix=/usr --openssldir=/usr/share/ssl
make
make install
在其她作业系统 (*BSD/UNIX) 上,步骤如下:
./config --prefix=/usr --openssldir=/usr/share/ssl
make
make install
如果不想自己编译、安装 OpenSSL ,另一个解决方法,由网中人提供,则是避开 -out 参数,改用输出重导向:
openssl rand 1024 > /etc/ssl/private/.rand
Mandrake 和 Debian 的 openssl 套件没有这个问题。 (回正文)
若要做成 DSA Key,请改用:
# 制作 DSA 参数档
openssl dsaparam -out /tmp/dsaparam 2048
# 制作 DSA Private Key
openssl gendsa -out /etc/ssl/private/myrootca.key /tmp/dsaparam
chmod og-rwx /etc/ssl/private/myrootca.key
# 删除 DSA 参数档
rm -f /tmp/dsaparam
因为 DSA 取乱数参数要取很久,所以 OpenSSL 不直接做 DSA Key ,而把取出来的 DSA 参数存档,再用参数档来做 DSA Key ,做下一组 Key 时就可以用同一个参数档,以节省时间。不过这里我们只做一组 Key ,所以参数档用过就可以删了。 (回正文)
若你的最高层认证中心,放在另一台伺服器上,请将 /tmp/myhost.req 复制到那台伺服器上的 /tmp/myhost.req ,登入那台伺服器上,再继续进行。 (回正文:root/使用者)
如果你原来是在另一台伺服器做这组 Public/Private Key 的,把 /etc/ssl/certs/myhost.crt 复制到原来的伺服器上的 /etc/ssl/certs/myhost.crt ,就可以用了。记得要回到原来的伺服器上,把原来伺服器上的凭证申请书 /tmp/myhost.req 也删掉。
rm -f /tmp/myhost.req
(回正文)
在 Mandrake 下装 RPM 时,请改用:
cp /usr/lib/ssl/openssl.cnf ~/etc/ssl
(回正文)
这是 bash 和 zsh 的指令。 csh 或 tcsh 下,请改用:
setenv OPENSSL_CONF "$HOME/etc/ssl/openssl.cnf"
(回正文)
这样以后登入的时候,都能够自动设定 OPENSSL_CONF 。这是用 bash 登入的情形,若用 csh 或 tcsh 登入,请改用:
echo "# OpenSSL 设定档的位置" >> ~/.cshrc
echo "setenv OPENSSL_CONF \"$HOME/etc/ssl/openssl.cnf\"" >> ~/.cshrc
若用 zsh 登入,请改用:
echo "# OpenSSL 设定档的位置" >> ~/.zshenv
echo "export OPENSSL_CONF=\"$HOME/etc/ssl/openssl.cnf\"" >> ~/.zshenv
(回正文)
(感谢网中人 (netman) 提供)若你安装的是 Red Hat 的 openssl RPM ,在这里会出一点问题。 Red Hat 的 openssl 做 rand 指令,配合 -out 参数时,参数解析会出错,无法执行。目前我还没有看到网路上有人提过这件事。解决方法之一,是自己编译、安装 OpenSSL 。这其实很简单。在 Linux 上,步骤如下:
./config shared --prefix=/usr --openssldir=/usr/share/ssl
make
make install
在其她作业系统 (*BSD/UNIX) 上,步骤如下:
./config --prefix=/usr --openssldir=/usr/share/ssl
make
make install
如果不想自己编译、安装 OpenSSL ,另一个解决方法,由网中人提供,则是避开 -out 参数,改用输出重导向:
openssl rand 1024 > ~/etc/ssl/private/.rand
Mandrake 和 Debian 的 openssl 套件没有这个问题。 (回正文)
若要做成 DSA Key,请改用:
# 制作 DSA 参数档
openssl dsaparam -out ~/tmp/dsaparam 2048
# 制作 DSA Private Key
openssl gendsa -out ~/etc/ssl/private/myrootca.key ~/tmp/dsaparam
chmod og-rwx ~/etc/ssl/private/myrootca.key
# 删除 DSA 参数档
rm -f ~/tmp/dsaparam
因为 DSA 取乱数参数要取很久,所以 OpenSSL 不直接做 DSA Key ,而把取出来的 DSA 参数存档,再用参数档来做 DSA Key ,做下一组 Key 时就可以用同一个参数档,以节省时间。不过这里我们只做一组 Key ,所以参数档用过就可以删了。 (回正文)
若你的最高层认证中心,是由 root 管理,请接到 root 的第三步骤。 (回正文)
如果你原来是在另一台伺服器做这组 Public/Private Key 的,把 ~/etc/ssl/certs/myhost.crt 复制到原来的伺服器上的 ~/etc/ssl/certs/myhost.crt,就可以用了。记得要回到原来的伺服器上,把原来伺服器上的凭证申请书 /tmp/myhost.req 也删掉。
rm -f /tmp/myhost.req
(回正文)
不过微软的 Outlook Express 很笨,不支援相容性高的 TLS 新标准,只能跑旧式的 SMTPS 。若你要设定给 Outlook Express 用 SSL 寄信,就一定要在编译时加上 SMTPS 的支援。(回正文)
其实你会看到三个连接埠: SMTP(25) 、 SMTPS(465) 和 submission(587) 。 submission(587) 是给邮件程式寄信专用的,和 SMTP(25) 一样可以做 TLS 。 submission(587) 不需特别设定,为简化讨论起见,省略之。(回正文)
若你在意系统安全,不想多开不必要的帐号的话,这里的 smmsp 可以改成 mail ,用 mail 帐号。我强烈建议这个做法。开太多不必要的帐号,增加不必要的系统权限,也是安全漏洞的来源之一。本来就没有什么程式在用 mail 帐号, mail 是闲置的系统帐号之一,不如好好利用这个现有的系统资源。更何况, Sendmail 建议的 smmsp 群组的 GID 25 ,和 Debian floppy 群组的 GID 冲突。这是系统安全的题外话,和 SSL 无关。(回正文)
这里 MS-WINDOWS 把「最高层认证中心 (Root CA) 」译成「根目录凭证授权」,把「认证中心 (CA) 」译成「凭证授权」或「中继凭证授权」,都是逐字翻译的结果,完全不知所云,翻译之大忌,戒之。(回正文)
到 Mozilla 1.1 版为止, Mozilla 把「凭证 (Certificate) 」译成「认证」,把「认证中心 (CA) 」译成「查证」,也是有问题的译法,且不符目前的通译。我已跟 Mozilla 中文化的作者林弘德反映过这个问题,他承诺於 1.0.1 版后修正。(回正文)
实际储存的地方,在 Mozilla 使用者设定档目录下的 cert7.db ,格式是 Berkeley DB 。(回正文)
我还没找到直接开启 [Certificate Infomation Manager] 的方法。如果有人知道,烦请告诉我。 (回正文)
实际储存的地方,公用的认证中心在 Eudora 程式目录下的 rootcerts.p7b ,个人的认证中心在 Eudora 信箱目录下的 usercerts.p7b ,格式是标准凭证格式 DER 的 PKCS#7 档。(回正文)
要先失败一次,才能去设定,其实挺蠢的。另一个「比较不那么愚蠢的方法」,就是直接去改 usercerts.p7b 。 usercerts.p7b 是标准凭证格式 PKCS#7 档,可以用 OpenSSL 处理:
# 备份原档案
mv usercerts.p7b usercerts-orig.p7b
# 把 DER 的 PKCS#7 档,拆成一张一张的 PEM 凭证清单
openssl pkcs7 -print_certs -inform der -in usercerts-orig.p7b -out certslist.pem
# 把我们的认证中心加进来
cat /etc/ssl/certs/myrootca.crt >> certslist.pem
# 将一张一张的 PEM 凭证清单,组合成 PEM 的 PKCS#7 档
openssl crl2pkcs7 -nocrl -certfile certslist.pem > usercerts.pem
# 将 PEM 转为 DER
openssl pkcs7 -in usercerts.pem -outform der -out usercerts.p7b
# 删掉多余的档案
rm -f certslist.pem usercerts.pem
这样就把我们的认证中心加进 usercerts.p7b 了。不要直接去改公用的认证中心 rootcerts.p7b ,这个档案留给 Eudora 自己去维护。(回正文)
参考资料
SSL: Netscape Security Documentation, Introduction to SSL, How SSL Works, SSL Protocol v3.0
X.509: RFC 3280, RFC 2459 (旧版)
OpenSSL: OpenSSL, openssl(1), x509(1), req(1), ca(1)
PGP: GnuPG, PGPi, PGP, Introduction to Cryptography ( PDF 档, PGP 的原作者 Phil Zimmermann 作), Phil Zimmermann
FHS: http://www.pathname.com/fhs/
TLS 1.0: RFC 2246
Apache: http://www.apache.org/, Apache-SSL, mod_ssl
Qpopper: http://www.eudora.com/qpopper/
Sendmail: http://www.sendmail.org/
Stunnel: http://www.stunnel.org/