【问题标题】:How to get SHA1 fingerprint of a certificate如何获取证书的 SHA1 指纹
【发布时间】:2022-01-20 05:51:31
【问题描述】:

我的目标是实现第三方网站证书的 SHA1 指纹。我可以使用openssl 命令行成功获得它,但是,当我尝试使用python代码实现它时,它并没有变得相同。使用python代码得到的SHA1指纹和openssl得到的完全不同。

openssl 步骤 -->

openssl s_client -servername token.actions.githubusercontent.com -showcerts -connect token.actions.githubusercontent.com:443

上述命令输出包含链和根证书;

Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=*.actions.githubusercontent.com
   i:/C=US/O=DigiCert Inc/CN=DigiCert TLS RSA SHA256 2020 CA1
-----BEGIN CERTIFICATE-----
MIIG9jCCBd6gAwIBAgIQCFCR4fqbkQJJbzQZsc87qzANBgkqhkiG9w0BAQsFADBP
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMSkwJwYDVQQDEyBE
aWdpQ2VydCBUTFMgUlNBIFNIQTI1NiAyMDIwIENBMTAeFw0yMjAxMTEwMDAwMDBa

将带有.crt 扩展名的链证书保存为 MaingithubOIDC.crt 并运行以下命令给出 SHA1 指纹;

❯ openssl x509 -in MaingithubOIDC.crt -fingerprint -noout
SHA1 Fingerprint=15:E2:91:08:71:81:11:E5:9B:3D:AD:31:95:46:47:E3:C3:44:A2:31

参考链接 - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html

Python 代码(版本 3.8/3.9)-->

import ssl
import socket
import hashlib
 
addr = 'token.actions.githubusercontent.com'
 
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
wrappedSocket = ssl.wrap_socket(sock)
 
try:
  wrappedSocket.connect((addr, 443))
  print (wrappedSocket)
except:
  response = False
else:
  der_cert = wrappedSocket.getpeercert(True)
  pem_cert = ssl.DER_cert_to_PEM_cert(wrappedSocket.getpeercert(True))
  print(pem_cert)
 
  #Print SHA1 Thumbprint
  thumb_sha1 = hashlib.sha1(der_cert).hexdigest()
  print("SHA1: " + thumb_sha1)

Python 代码输出; SHA1: 55a7ef500a3a99f64c99c665daaf3f07403cff3d

因此,SHA1 指纹与使用openssl 获得的指纹不匹配。我在 python 代码中遗漏了什么吗?

【问题讨论】:

    标签: python ssl openssl openid-connect


    【解决方案1】:

    问题不在于证书中的指纹计算错误,而是您获得了错误的证书。有问题的服务器是一个多域设置,它将根据 TLS 握手中给出的server_name 返回不同的证书 - 请参阅Server Name Indication

    以下代码不会提供server_name,这会导致为*.azureedge.net返回证书,而不是*.actions.githubusercontent.com,因为openssl s_client代码得到:

    wrappedSocket = ssl.wrap_socket(sock)
     
    try:
      wrappedSocket.connect((addr, 443))
    

    要解决此问题,需要提供 server_name

    ctx = ssl.create_default_context()
    wrappedSocket = ctx.wrap_socket(sock, 
      server_hostname='token.actions.githubusercontent.com')
    
    try:
      wrappedSocket.connect((addr, 443))
    

    通过此更改,预期的证书将由服务器发送,并在其上正确计算指纹。

    【讨论】:

    • 哦,我明白了。上述解决方案对我有用。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-03
    • 2015-12-17
    • 2021-10-27
    • 2015-05-11
    • 2012-08-26
    相关资源
    最近更新 更多