背景之前利用笨重的Java写过内网访问程序(SSL双向认证系统),今天才发现curl等命令对SSL都有良好的支持。
故记录相关点滴。
创建CA根证书
#创建ca私钥
openssl genrsa -out ca.key
#创建证书请求文件(Certificate Secure Request)
openssl req -new -key ca.key -out ca.csr
#创建CA根证书
openssl x509 -req -days 3650 -in ca.csr -signkey ca.key -out ca.crt
创建服务器证书
#创建服务器私钥
openssl genrsa -out server.key
#创建服务器证书请求文件
openssl req -new -key server.key -out server.csr
#创建服务器证书
openssl ca -in server.csr -cert ca.crt -keyfile ca.key -out server.crt
PFX证书转换
#pfx格式证书导出成pem格式证书
openssl pkcs12 -in jinli.pfx -nodes -out jinli.pem
#导出私钥
openssl rsa -in jinli.pem -out jinli.key
#导出证书,公钥
openssl x509 -in jinli.pem -out jinli.crt
curl访问HTTPS命令
curl -E jinli.pem:${password} --cacert ca.crt https://www.cn.alibaba-inc.com/
curl --cacert gmail.pem https://mail.google.com/mail
curl --cert jinli.crt --key jinli.key --cacert ca.crt https://www.cn.alibaba-inc.com/
参数解释:
--cacert <file> CA certificate to verify peer against (SSL)
--capath <directory> CA directory to verify peer against (SSL)
-E/--cert <cert[:passwd]> Client certificate file and password (SSL)
--cert-type <type> Certificate file type (DER/PEM/ENG) (SSL)
--key <key> Private key file name (SSL/SSH)
--key-type <type> Private key file type (DER/PEM/ENG) (SSL)
python访问HTTPS代码
from httplib import HTTPSConnection
con = HTTPSConnection('www.cn.alibaba-inc.com', cert_file='jinli.pem')
con.connect()
con.request('GET', '/xxx')
res = con.getresponse()
print res.status
print res.read()
res.close()
con.close()
python查看证书信息代码
from OpenSSL import crypto
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, open('cert_file').read())
print x509.get_issuer()
pkcs = crypto.load_pkcs12(open(pkcs_file).read(),passphrase)
print pkcs.get_certificate().get_issuer()
HTTPSConnection不理解的地方
def wrap_socket(sock, keyfile=None, certfile=None,
server_side=False, cert_reqs=CERT_NONE,
ssl_version=PROTOCOL_SSLv23, ca_certs=None,
do_handshake_on_connect=True,
suppress_ragged_eofs=True, ciphers=None):
return SSLSocket(sock, keyfile=keyfile, certfile=certfile,
server_side=server_side, cert_reqs=cert_reqs,
ssl_version=ssl_version, ca_certs=ca_certs,
do_handshake_on_connect=do_handshake_on_connect,
suppress_ragged_eofs=suppress_ragged_eofs,
ciphers=ciphers)
ssl wrap的函数是支持ca_certs参数的,但是HTTPSConnection不支持ca_certs参数
class HTTPSConnection(HTTPConnection):
"This class allows communication via SSL."
default_port = HTTPS_PORT
def __init__(self, host, port=None, key_file=None, cert_file=None,
strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
source_address=None):
HTTPConnection.__init__(self, host, port, strict, timeout,
source_address)
self.key_file = key_file
self.cert_file = cert_file
def connect(self):
"Connect to a host on a given (SSL) port."
sock = socket.create_connection((self.host, self.port),
self.timeout, self.source_address)
if self._tunnel_host:
self.sock = sock
self._tunnel()
self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file)