当提供 SSL 密钥时,Pycurl SSL 会话 ID 不起作用
Pycurl SSL Session ID not working, when provided with SSL keys
默认情况下 libcurl(和 pycurl)支持 ssl 连接重用,这意味着对于发送后续 HTTPS 请求的情况,第二个将使用 SSL 会话 ID 并避免完全握手。 (基本上 pycurl.SSL_SESSIONID_CACHE
是 True
)。
当我测试它时:
import pycurl
c = pycurl.Curl()
c.setopt(c.URL, 'https://myserver:443/X')
c.setopt(c.COOKIEFILE, '')
c.setopt(c.VERBOSE, True)
c.perform()
c.setopt(c.FRESH_CONNECT, 1)
c.setopt(c.URL, 'https://myserver:443/Y')
c.perform()
我可以看到 pycurl 将会话 ID 用于第二个连接。但是,一旦我添加了客户端密钥和 CA 信息(用于相互身份验证),它就会停止工作。意思是,客户端协商了一个新的 SSL 密钥,这是不可取的。
import pycurl
c = pycurl.Curl()
c.setopt(c.URL, 'https://myserver:443/X')
c.setopt(c.COOKIEFILE, '')
c.setopt(c.VERBOSE, True)
c.setopt(pycurl.SSL_VERIFYHOST, 2)
c.setopt(c.SSLCERTTYPE, "PEM")
c.setopt(c.SSLKEYTYPE, "PEM")
client_cert = "ssl_keys/client/client_crt.pem"
ca_cert = "ssl_keys/ca/ca_crt.pem"
client_key = "ssl_keys/client/client_pr.pem"
c.setopt(c.SSLCERT, client_cert)
c.setopt(c.SSLKEY, client_key)
c.setopt(c.CAINFO, ca_cert)
c.perform()
c.setopt(c.SSL_SESSIONID_CACHE, True) # that doesn't matter really
c.setopt(c.FRESH_CONNECT, 1)
c.setopt(c.URL, 'https://myserver:443/Y')
c.perform()
有什么想法吗?
当客户端证书用于安全目的时,curl 会禁用 "SSL session resumption"。有关详细信息,请参阅 2016 年 8 月的 TLS session resumption client cert bypass 安全公告。
此功能可以即使使用客户端证书也能正常工作,但没有人努力编写代码以安全地完成此操作。我认为用例足够小,可以采取更简单的方法:为客户端证书禁用它。
默认情况下 libcurl(和 pycurl)支持 ssl 连接重用,这意味着对于发送后续 HTTPS 请求的情况,第二个将使用 SSL 会话 ID 并避免完全握手。 (基本上 pycurl.SSL_SESSIONID_CACHE
是 True
)。
当我测试它时:
import pycurl
c = pycurl.Curl()
c.setopt(c.URL, 'https://myserver:443/X')
c.setopt(c.COOKIEFILE, '')
c.setopt(c.VERBOSE, True)
c.perform()
c.setopt(c.FRESH_CONNECT, 1)
c.setopt(c.URL, 'https://myserver:443/Y')
c.perform()
我可以看到 pycurl 将会话 ID 用于第二个连接。但是,一旦我添加了客户端密钥和 CA 信息(用于相互身份验证),它就会停止工作。意思是,客户端协商了一个新的 SSL 密钥,这是不可取的。
import pycurl
c = pycurl.Curl()
c.setopt(c.URL, 'https://myserver:443/X')
c.setopt(c.COOKIEFILE, '')
c.setopt(c.VERBOSE, True)
c.setopt(pycurl.SSL_VERIFYHOST, 2)
c.setopt(c.SSLCERTTYPE, "PEM")
c.setopt(c.SSLKEYTYPE, "PEM")
client_cert = "ssl_keys/client/client_crt.pem"
ca_cert = "ssl_keys/ca/ca_crt.pem"
client_key = "ssl_keys/client/client_pr.pem"
c.setopt(c.SSLCERT, client_cert)
c.setopt(c.SSLKEY, client_key)
c.setopt(c.CAINFO, ca_cert)
c.perform()
c.setopt(c.SSL_SESSIONID_CACHE, True) # that doesn't matter really
c.setopt(c.FRESH_CONNECT, 1)
c.setopt(c.URL, 'https://myserver:443/Y')
c.perform()
有什么想法吗?
当客户端证书用于安全目的时,curl 会禁用 "SSL session resumption"。有关详细信息,请参阅 2016 年 8 月的 TLS session resumption client cert bypass 安全公告。
此功能可以即使使用客户端证书也能正常工作,但没有人努力编写代码以安全地完成此操作。我认为用例足够小,可以采取更简单的方法:为客户端证书禁用它。