How can I get the public key of a webpage like verisign , etc. using HTTPS protocol?
-
3If I understand your question right then, you can click on the https protocol sign in chrome or firefox (on the left corner of the address bar), there you can see a pop showing detail about the certificate including its public key.– Jor-elJun 15, 2012 at 18:43
-
@Jor-el, I'm assuming from the openssl tag that the question is about doing this with OpenSSL. Perhaps the question could be clarified.– BrunoJun 15, 2012 at 20:06
-
An HTTPS page does not have a publickey; only a server has a publickey, and certificate for it, as explained in the answers. That is at least one domainname, and sometimes more than one. Different pages can't have different keys/certs, because the server must provide its cert (and the client accept it) before the client informs the server what page is requested -- if any; HTTP[S] allows requests that don't access any page at all.– dave_thompson_085Oct 18, 2019 at 4:24
3 Answers
This command will show you the certificate (use -showcerts
as an extra parameter if you want to see the full chain):
openssl s_client -connect the.host.name:443
This will get the certificate and print out the public key:
openssl s_client -connect the.host.name:443 | openssl x509 -pubkey -noout
If you want to dig further, this question might be of interest.
-
When running this on CentOS 7 with OpenSSL 1.0.2k, the command doesn't exit automatically after printing the key.– zymhanApr 10, 2020 at 19:17
-
In google chrome, go to the https web page (say https://mail.google.com), click on the lock next to the URL, then click on "certificate information", click on the "Details" tab, and then find "Subject Public Key Info", which for mail.google.com
says Subject Public Key Algorithm: "PKCS #1 RSA Encryption" and Subject's Public Key:
Modulus (1024 bits):
AF 39 15 98 68 E4 92 FE 4F 4F F1 BB FF 0D 2E B0
FE 25 AA BD 68 04 67 27 EA 6C 43 4C A7 6D CB C8
8F 7E 81 EE 87 26 25 10 12 54 33 9E AA 3D 9B 8F
8E 92 B3 4B 01 E3 F9 4A 29 C3 0F FD AC B7 D3 4C
97 29 3F 69 55 CF 70 83 04 AF 2E 04 6E 74 D6 0F
17 09 FE 9E 20 24 24 E3 C7 68 9C AC 11 BD 92 E4
B2 1B 09 F2 02 32 BB 55 1B 2D 16 5F 30 12 23 E2
4C 4A 8D C2 DA 3F E1 B8 BF F7 3A B1 86 BE F0 C5
Public Exponent (24 bits):
01 00 01
This corresponds to the decimal numbers N=123045765072979014913511278179231402316770142733119510397469126703890433473616878571037576880489731114142173557070569117331013682110047985574967516701153320350820086344743718518661070276817382223900929884490765709232088941906671668904441902033030813416432622693650320785674286428555963210887699747381872357573
and exponent=65537
used in RSA.
In Python 3, SSLSocket.getpeercert can be used to obtain the peer certificate, which in turn can be parsed by any DER certificate parser:
import ssl, socket
from asn1crypto import pem, x509
hostname = 'www.sjoerdlangkemper.nl'
ctx = ssl.create_default_context()
s = ctx.wrap_socket(socket.socket(), server_hostname=hostname)
s.connect((hostname, 443))
der = s.getpeercert(binary_form=True)
cert = x509.Certificate.load(der)
pubkey = cert.public_key.unwrap()
print(pubkey)
The variable pubkey
is now a RSAPublicKey
if the connection used RSA. You can get the modulus like this:
print(pubkey["modulus"].native)
Or convert it to a PEM public key like this:
print(pem.armor("PUBLIC KEY", pubkey.contents).decode("ASCII"))