CURL
请求 HTTPS 网站,一般为单向认证,流程图如下:
单向认证步骤1
CURLOPT_SSLVERSION
指定要使用的 SSL 版本(一般无需设置,让 Curl 决定)
步骤3
CURLOPT_CAINFO
/CURLOPT_CAPATH
校验服务端证书合法性所使用的本地 CA 证书,(一般不设置,内用内置证书)
CURLOPT_SSL_VERIFYPEER
是否校验服务端的证书合法性,默认: true
CURLOPT_SSL_VERIFYHOST
若服务端证书合法,是否验证域名与证书是否匹配。 默认: true
CURLOPT_SSL_VERIFYSTATUS
若服务端证书校验通过,是否校验证书状态(会向证书服务商发出请求,检查证书是否被吊销)默认: false
步骤4
CURLOPT_SSL_CIPHER_LIST
设置SSL的加密算法列表,(一般无需设置,让 Curl 决定)
步骤7
CURLOPT_RANDOM_FILE
用来生成 SSL 随机数种子的文件名,(一般不设置,Curl 自行决定)
其他
CURLOPT_SSL_OPTIONS
SSL 验证行为:一般保持默认,可 参见
CURLOPT_CERTINFO
是否收集通信过程中的证书信息,需要CURLOPT_VERBOSE=1
(开启 debug , 收集信息)
以上为客户端校验服务端的流程,有些时候,服务端也要校验客户端,比如一些支付接口,需要认证才能请求 API。此时,客户端也需要提供证书,进行双向认证,所有单向认证的参数仍然有效,额外增加了客户端提供证书的步骤。
双向认证步骤 4 、步骤 9:客户端提供证书和公钥:
CURLOPT_SSLCERT
客户端证书路径,该证书可以同时包含公钥,比如 PEM 证书就可以合二为一
CURLOPT_SSLCERTTYPE
证书类型,支持 "PEM"(默认值)、"DER"和"ENG"
若证书不包含公钥,则需要单独提供。(证书和公钥一般为相同格式,但也可以不同)
CURLOPT_SSLKEY
私钥的文件路径
CURLOPT_SSLKEYTYPE
私钥的文件类型,支持 "PEM"(默认值)、"DER"和"ENG"
CURLOPT_KEYPASSWD
公钥如果需要密码,可通过该选项进行设置
CURLOPT_SSLCERTPASSWD
/CURLOPT_SSLKEYPASSWD
提一下这两个选项,已不建议(弃用),原本:
CURLOPT_SSLCERTPASSWD
对应二合一CURLOPT_SSLCERT
的密码CURLOPT_SSLKEYPASSWD
对应单独CURLOPT_SSLKEY
密码
但实际上二者都是指公钥密码,现在建议使用CURLOPT_SSLKEY
直接设置
CURLOPT_SSLENGINE
/CURLOPT_SSLENGINE_DEFAULT
私钥的加密引擎 / 非对称加密操作的变量。这两个参数用的较少,需要使用通过引擎构建的 Openssl 库,通常无需理会,当你需要用到的时候,自然就会明白。
最后,以上都是针对 HTTP 请求的。Curl 还支持 SSH 、SFTP、SCP 协议,对应的也有相关配置,如:
CURLOPT_SSH_HOST_PUBLIC_KEY_MD5
SSH 远程主机公钥(public key) 的 MD5 校验值,用于验证远程主机公钥证书
CURLOPT_SSH_PUBLIC_KEYFILE
SSH 客户端公钥文件路径,默认使用$HOME/.ssh/id_dsa.pub
CURLOPT_SSH_PRIVATE_KEYFILE
SSH 客户端私钥文件路径,默认使用$HOME/.ssh/id_dsa
CURLOPT_KEYPASSWD
SSH 客户端私钥密码,在旧版本的 Curl 中,没有CURLOPT_SSLCERTTYPE
和CURLOPT_SSLKEYPASSWD
选项,也是使用该选项设置的。很有可能为了兼容,该值仍作为这两个值的 fallback
CURLOPT_SSH_AUTH_TYPES
SFTP 和 SCP 所需的身份验证类型
SSL 上下文
以上是使用 CURL 时,与 SSL 相关的配置,还有一些是直接使用 openssl 来进行操作,以 php ssl 上下文选项 举例
作为客户端
使用 stream-socket-client 创建 SSL 客户端,在配置上下文选项时
对应 CURL 章节中步骤 3
cafile
/capath
校验服务端证书合法性所使用的本地 CA 证书,(一般不设置,内用内置证书)
verify_peer
是否校验服务端的证书合法性,默认: true
verify_peer_name
若服务端证书合法,是否验证域名与证书是否匹配。 默认: true
peer_name
证书内包含域名信息,一般校验时,对比证书内域名与所请求域名。但可以通过该值直接指定
allow_self_signed
服务端的证书一般为 CA 证书下发的二级证书,是否允许服务端自制的证书(非 CA 二级证书)
对应 CURL 章节中步骤 4、9(仅支持 PEM 证书)
local_cert
客户端证书路径,该证书可以同时包含公钥
local_pk
若证书不包含公钥,单独提供公钥
passphrase
二合一证书或单独公钥的密码
作为服务端
使用 stream-socket-server 创建 SSL 服务端端,在配置上下文选项时
cafile
/capath
服务端 CA 证书,(一般不设置,内用内置证书)
local_cert
服务端证书,一般为从 CA 机构注册得到的二级证书
local_pk
若证书不包含公钥,单独提供公钥
passphrase
二合一证书或单独公钥的密码
若服务端需要 SSL 双向认证,即客户端在请求时也要提供证书(该证书也由服务端生成,分发给用户)
verify_peer
设置为 true 开启校验,即客户端需提供证书
verify_peer_name
是否要验证客户端证书的域名一致性
peer_name
验证域名一致性时,要求客户端证书的域名与该设置值匹配(一般会自动获取,但也可手动设置)
证书生成
若是客户端需要证书,一般由服务端提供。若是服务端需要证书,通常在 CA 机构注册获得。但有时候只是为了测试,或者部署私有 CA,使用私有证书,有必要了解一下证书的制作。
对于 Windows,如果安装了 Git,就无需再次安装 openssl 了, 可直接使用 C:\Progra~1\Git\usr\bin\openssl
命令行方式
一、制作一级 CA 证书
生成私钥 CA.key
#创建私钥 (建议设置密码)
openssl genrsa -des3 -out CA.key 2048
生成如下
Generating RSA private key, 2048 bit long modulus
.............................................+++
................................+++
e is 65537 (0x010001)
<注:输入两次 CA Key 的密码>
Enter pass phrase for Ca.key:123456
Verifying - Enter pass phrase for CA.key:123456
由 KEY 生成证书 CA.crt
# 1 年有效期
openssl req -x509 -new -nodes -key CA.key -sha256 -days 360 -out CA.crt
流程如下
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]:CN
State or Province Name (full name) [Some-State]:HaiNan
Locality Name (eg, city) []:WenChang
Organization Name (eg, company) [Internet Widgits Pty Ltd]:CNASA Inc
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:CNASA root CA
Email Address []:admin@cnasa.cn
一级 CA 证书制作完毕,该 CA.crt 将作为客户端请求使用的 CA 证书。若是希望用户通过浏览器访问该 CA 证书下发的二级证书网站,需要用户将 CA.crt 添加到系统信任证书中。
二、制作二级 SSL 证书
假如你的 CA 获得了操作系统认证,内置在操作系统内了,你就成了一个 CA 签发机构了,可以卖证书了,通过下面的方式签发证书发放给网站主
创建 SSL 证书 KEY
# 这里简单起见,使用无密码 key,若需要给 key 设置密码,参考上面 CA.key
openssl genrsa -out localhost.key 2048
输出信息
Generating RSA private key, 2048 bit long modulus
...............+++
..............................................................................+++
e is 65537 (0x010001)
由 KEY 创建 SSL 证书 CSR
openssl req -new -key localhost.key -out localhost.csr
输入相关信息
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]:CN
State or Province Name (full name) [Some-State]:HaiNan
Locality Name (eg, city) []:WenChang
Organization Name (eg, company) [Internet Widgits Pty Ltd]:CNASA Inc
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:CNASA root CA
Email Address []:admin@cnasa.cn
Please enter the following 'extra' attributes
to be sent with your certificate request
<注:以下两项一般无需输入,回车即可>
A challenge password []:<Enter>
An optional company name []:<Enter>
challenge password:这个不是证书密码(证书没有密码,证书公钥 KEY 才有密码),CA 机构的网站一般有管理证书的操作界面,该密码通常为 CA 机构自用,在进行一些敏感操作(如删除证书,修改 KEY 密码),需要证书管理员提供该 challenge password
以提高安全性
创建域名附加配置文件,新建文件cert.ext
输入如下内容保存
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
IP.2 = 127.0.0.1
DNS.3 = test.com
DNS.4 = *.test.com
使用上面准备好的文件,由步骤一创建的 CA 签发 SSL 证书
# ssl证书有效期10年
openssl x509 -req -in localhost.csr -out localhost.crt -days 3650 \
-CAcreateserial -CA CA.crt -CAkey CA.key \
-CAserial serial -extfile cert.ext
此步骤需要输入 CA 私钥的密码
....
Getting CA Private Key
<输入 CA.key 密码回车>
Enter pass phrase for CA.key:
OK,到这里为止, SSL 证书制作完毕,使用自制的 CA 和 SSL 证书可以配置到服务端,网站就可以开启 HTTPS 了(客户端需要使用该 CA 证书进行访问 )
若网站需要开启 双向 SSL 认证,就需要给客户端也提供一个 SSL 证书,只需要重复上面 [制作二级 SSL 证书] 的步骤,生成的证书 和 key(密码可选)就可以分发给用户了。
编程方式
通过 PHP 举例,创建 CA 证书 / SSL 证书都可以通过以下步骤完成
- openssl_pkey_new(创建 key)
- openssl-csr-new(创建 CSR)
- openssl-csr-sign(由 KEY 签署 CSR)
- openssl-x509-export(创建 CA)
网友评论