=========
Cert Hero
=========
.. image:: https://img.shields.io/pypi/v/cert-hero.svg
:target: https://pypi.org/project/cert-hero
.. image:: https://img.shields.io/pypi/pyversions/cert-hero.svg
:target: https://pypi.org/project/cert-hero
.. image:: https://github.com/rnag/cert-hero/actions/workflows/dev.yml/badge.svg
:target: https://github.com/rnag/cert-hero/actions/workflows/dev.yml
.. image:: https://readthedocs.org/projects/cert-hero/badge/?version=latest
:target: https://cert-hero.readthedocs.io/en/latest/?version=latest
:alt: Documentation Status
.. image:: https://pyup.io/repos/github/rnag/cert-hero/shield.svg
:target: https://pyup.io/repos/github/rnag/cert-hero/
:alt: Updates
Python Stand-alone Library to Download the SSL Certificate for *Any Hostâ„¢*
* Documentation: https://cert-hero.readthedocs.io.
-------------------
**Why Use?**
* This library *always* returns the SSL certificate, if a server has one. This works for expired
and `self-signed certificate`_, whereas the builtin ``ssl`` library returns an empty ``dict`` if verification fails
for any reason (source_).
* The *only* dependency is `asn1crypto`_ (with over 300 stars on GitHub), which is ~94% more lightweight and robust
than a solution with `pyOpenSSL`_ (chart_).
* If a host *redirects* to another URL, this info is captured in ``Location`` and ``Status``.
* Convenience methods such as ``__repr__()`` to make output more human-readable.
**Core Exports**
* `cert_please`_ - Retrieve the SSL certificate for a given hostname.
* `certs_please`_ - Retrieve (concurrently) the SSL certificate(s) for a list of hostnames.
* `set_expired`_ - Helper function to check (at runtime) if a cert is expired or not.
.. _chart: https://raw.githubusercontent.com/rnag/cert-hero/main/images/SizeComparison.png
.. _ssl: https://docs.python.org/3/library/ssl.html
.. _asn1crypto: https://pypi.org/project/asn1crypto
.. _pyOpenSSL: https://pypi.org/project/pyOpenSSL/
.. _source: https://stackoverflow.com/a/74349032/10237506
.. _self-signed certificate: https://stackoverflow.com/a/68889470/10237506
.. _`cert_please`: https://cert-hero.readthedocs.io/en/latest/cert_hero.html#cert_hero.cert_please
.. _`certs_please`: https://cert-hero.readthedocs.io/en/latest/cert_hero.html#cert_hero.certs_please
.. _`set_expired`: https://cert-hero.readthedocs.io/en/latest/cert_hero.html#cert_hero.set_expired
Install
-------
.. code-block:: console
$ pip install cert-hero
Usage
-----
Fetch the SSL certificate for a **host** with ``cert_please()``:
.. code:: python3
import cert_hero
cert = cert_hero.cert_please('google.com')
print('Cert is Valid Till:', cert.not_after_date.isoformat())
# To get the output as a JSON string, use `str(cert)` or remove `!r` from below
print(f'Cert -> \n{cert!r}')
cert_hero.set_expired(cert)
print(f'Validity ->\n{cert["Validity"]}')
*Output (Sample)*
.. code::
Cert is Valid Till: 2023-10-28
Cert ->
CertHero(
{
"Cert Status": "SUCCESS",
"Serial": "753DD6FF20CB1B4510CB4C1EA27DA2EB",
"Subject Name": {
"Common Name": "*.google.com"
},
"Issuer Name": {
"Country": "US",
"State/Province": "California",
"Organization": "Zscaler Inc.",
"Organization Unit": "Zscaler Inc.",
"Common Name": "Zscaler Intermediate Root CA (zscalerthree.net) (t) "
},
"Validity": {
"Not After": "2023-10-28",
"Not Before": "2023-10-14"
},
"Wildcard": true,
"Signature Algorithm": "SHA256WITHRSA",
"Key Algorithm": "RSA-2048",
"Subject Alt Names": [
"*.google.com",
"*.appengine.google.com",
"youtu.be",
"*.youtube.com",
...
],
"Location": "https://www.google.com/",
"Status": 301
}
)
Validity ->
{'Not After': '2023-10-28', 'Not Before': '2023-10-14', 'Expired': False}
Fetch (concurrently) the SSL certificates for **multiple hosts** with ``certs_please()``:
.. code:: python3
import cert_hero
host_to_cert = cert_hero.certs_please(['google.com', 'cnn.com', 'www.yahoo.co.in', 'youtu.be'])
cert_hero.set_expired(host_to_cert)
for host, cert in host_to_cert.items():
print(f'=== {host.center(17)} ===')
# To get the output as a JSON string, use `str(cert)` or remove `!r` from below
print(f'{cert!r}')
print()
*Output (Sample)*
.. code::
=== google.com ===
CertHero(
{
"Cert Status": "SUCCESS",
"Serial": "753DD6FF20CB1B4510CB4C1EA27DA2EB",
"Subject Name": {
"Common Name": "*.google.com"
},
...
}
)
=== cnn.com ===
CertHero(
{
"Cert Status": "SUCCESS",
"Serial": "7F2F3E5C350554D71A6784CCFE6E8315",
"Subject Name": {
"Common Name": "cnn.com"
},
...
}
)
=== www.yahoo.co.in ===
CertHero(
{
"Cert Status": "SUCCESS",
"Serial": "7D7FD7B7C2EE7146B4D4E43E36908B72",
"Subject Name": {
"Common Name": "src1.yahoo.com"
},
...
}
)
=== youtu.be ===
CertHero(
{
"Cert Status": "SUCCESS",
"Serial": "753DD6FF20CB1B4510CB4C1EA27DA2EB",
"Subject Name": {
"Common Name": "*.google.com"
},
...
}
)
Usage as a CLI
--------------
After the installation step you can use cert-hero just typing ``ch`` in your terminal window.
The ``ch`` command allows you to retrieve the SSL certificate(s) for one or more given host.
For example::
ch google.com cnn.com
You can get help about the main command using::
ch --help
Rationale
---------
The builtin Python module ``ssl`` can be used to retrieve a certificate from a server via ``getpeercert``,
but it'll work only if the certificate of interest can be successfully verified (source_).
If, for any reason, verification fails, like, for example, with expired or a `self-signed certificate`_,
we'll get ``ssl.SSLCertVerificationError`` instead of the requested info.
We can work around this by asking for the certificate in the binary form:
.. code-block:: python3
getpeercert(binary_form=True)
But now we have to convert it, and thus we can use a third party ``asn1crypto`` module, instead of
the (bulkier) ``cryptography`` module.
Credits
-------
This package was created with Cookiecutter_ and the `rnag/cookiecutter-pypackage`_ project template.
.. _Cookiecutter: https://github.com/cookiecutter/cookiecutter
.. _`rnag/cookiecutter-pypackage`: https://github.com/rnag/cookiecutter-pypackage
Raw data
{
"_id": null,
"home_page": "https://github.com/rnag/cert-hero",
"name": "cert-hero",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "cert-hero,cert,ssl,certificate,host cert",
"author": "Ritvik Nag",
"author_email": "rv.kvetch@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/2d/bb/91b114e4e8684b94ef0408496be97ea9ce1f3fabbaf5e9d4606deff48794/cert-hero-0.3.0.tar.gz",
"platform": null,
"description": "=========\nCert Hero\n=========\n\n\n.. image:: https://img.shields.io/pypi/v/cert-hero.svg\n :target: https://pypi.org/project/cert-hero\n\n.. image:: https://img.shields.io/pypi/pyversions/cert-hero.svg\n :target: https://pypi.org/project/cert-hero\n\n.. image:: https://github.com/rnag/cert-hero/actions/workflows/dev.yml/badge.svg\n :target: https://github.com/rnag/cert-hero/actions/workflows/dev.yml\n\n.. image:: https://readthedocs.org/projects/cert-hero/badge/?version=latest\n :target: https://cert-hero.readthedocs.io/en/latest/?version=latest\n :alt: Documentation Status\n\n.. image:: https://pyup.io/repos/github/rnag/cert-hero/shield.svg\n :target: https://pyup.io/repos/github/rnag/cert-hero/\n :alt: Updates\n\n\nPython Stand-alone Library to Download the SSL Certificate for *Any Host\u2122*\n\n* Documentation: https://cert-hero.readthedocs.io.\n\n-------------------\n\n**Why Use?**\n\n* This library *always* returns the SSL certificate, if a server has one. This works for expired\n and `self-signed certificate`_, whereas the builtin ``ssl`` library returns an empty ``dict`` if verification fails\n for any reason (source_).\n\n* The *only* dependency is `asn1crypto`_ (with over 300 stars on GitHub), which is ~94% more lightweight and robust\n than a solution with `pyOpenSSL`_ (chart_).\n\n* If a host *redirects* to another URL, this info is captured in ``Location`` and ``Status``.\n\n* Convenience methods such as ``__repr__()`` to make output more human-readable.\n\n**Core Exports**\n\n* `cert_please`_ - Retrieve the SSL certificate for a given hostname.\n* `certs_please`_ - Retrieve (concurrently) the SSL certificate(s) for a list of hostnames.\n* `set_expired`_ - Helper function to check (at runtime) if a cert is expired or not.\n\n.. _chart: https://raw.githubusercontent.com/rnag/cert-hero/main/images/SizeComparison.png\n.. _ssl: https://docs.python.org/3/library/ssl.html\n.. _asn1crypto: https://pypi.org/project/asn1crypto\n.. _pyOpenSSL: https://pypi.org/project/pyOpenSSL/\n.. _source: https://stackoverflow.com/a/74349032/10237506\n.. _self-signed certificate: https://stackoverflow.com/a/68889470/10237506\n.. _`cert_please`: https://cert-hero.readthedocs.io/en/latest/cert_hero.html#cert_hero.cert_please\n.. _`certs_please`: https://cert-hero.readthedocs.io/en/latest/cert_hero.html#cert_hero.certs_please\n.. _`set_expired`: https://cert-hero.readthedocs.io/en/latest/cert_hero.html#cert_hero.set_expired\n\nInstall\n-------\n\n.. code-block:: console\n\n $ pip install cert-hero\n\nUsage\n-----\n\nFetch the SSL certificate for a **host** with ``cert_please()``:\n\n.. code:: python3\n\n import cert_hero\n\n cert = cert_hero.cert_please('google.com')\n\n print('Cert is Valid Till:', cert.not_after_date.isoformat())\n\n # To get the output as a JSON string, use `str(cert)` or remove `!r` from below\n print(f'Cert -> \\n{cert!r}')\n\n cert_hero.set_expired(cert)\n print(f'Validity ->\\n{cert[\"Validity\"]}')\n\n*Output (Sample)*\n\n.. code::\n\n Cert is Valid Till: 2023-10-28\n Cert ->\n CertHero(\n {\n \"Cert Status\": \"SUCCESS\",\n \"Serial\": \"753DD6FF20CB1B4510CB4C1EA27DA2EB\",\n \"Subject Name\": {\n \"Common Name\": \"*.google.com\"\n },\n \"Issuer Name\": {\n \"Country\": \"US\",\n \"State/Province\": \"California\",\n \"Organization\": \"Zscaler Inc.\",\n \"Organization Unit\": \"Zscaler Inc.\",\n \"Common Name\": \"Zscaler Intermediate Root CA (zscalerthree.net) (t) \"\n },\n \"Validity\": {\n \"Not After\": \"2023-10-28\",\n \"Not Before\": \"2023-10-14\"\n },\n \"Wildcard\": true,\n \"Signature Algorithm\": \"SHA256WITHRSA\",\n \"Key Algorithm\": \"RSA-2048\",\n \"Subject Alt Names\": [\n \"*.google.com\",\n \"*.appengine.google.com\",\n \"youtu.be\",\n \"*.youtube.com\",\n ...\n ],\n \"Location\": \"https://www.google.com/\",\n \"Status\": 301\n }\n )\n Validity ->\n {'Not After': '2023-10-28', 'Not Before': '2023-10-14', 'Expired': False}\n\nFetch (concurrently) the SSL certificates for **multiple hosts** with ``certs_please()``:\n\n.. code:: python3\n\n import cert_hero\n\n host_to_cert = cert_hero.certs_please(['google.com', 'cnn.com', 'www.yahoo.co.in', 'youtu.be'])\n cert_hero.set_expired(host_to_cert)\n\n for host, cert in host_to_cert.items():\n print(f'=== {host.center(17)} ===')\n # To get the output as a JSON string, use `str(cert)` or remove `!r` from below\n print(f'{cert!r}')\n print()\n\n*Output (Sample)*\n\n.. code::\n\n === google.com ===\n CertHero(\n {\n \"Cert Status\": \"SUCCESS\",\n \"Serial\": \"753DD6FF20CB1B4510CB4C1EA27DA2EB\",\n \"Subject Name\": {\n \"Common Name\": \"*.google.com\"\n },\n ...\n }\n )\n\n === cnn.com ===\n CertHero(\n {\n \"Cert Status\": \"SUCCESS\",\n \"Serial\": \"7F2F3E5C350554D71A6784CCFE6E8315\",\n \"Subject Name\": {\n \"Common Name\": \"cnn.com\"\n },\n ...\n }\n )\n\n === www.yahoo.co.in ===\n CertHero(\n {\n \"Cert Status\": \"SUCCESS\",\n \"Serial\": \"7D7FD7B7C2EE7146B4D4E43E36908B72\",\n \"Subject Name\": {\n \"Common Name\": \"src1.yahoo.com\"\n },\n ...\n }\n )\n\n === youtu.be ===\n CertHero(\n {\n \"Cert Status\": \"SUCCESS\",\n \"Serial\": \"753DD6FF20CB1B4510CB4C1EA27DA2EB\",\n \"Subject Name\": {\n \"Common Name\": \"*.google.com\"\n },\n ...\n }\n )\n\nUsage as a CLI\n--------------\n\nAfter the installation step you can use cert-hero just typing ``ch`` in your terminal window.\n\nThe ``ch`` command allows you to retrieve the SSL certificate(s) for one or more given host.\n\nFor example::\n\n ch google.com cnn.com\n\nYou can get help about the main command using::\n\n ch --help\n\nRationale\n---------\n\nThe builtin Python module ``ssl`` can be used to retrieve a certificate from a server via ``getpeercert``,\nbut it'll work only if the certificate of interest can be successfully verified (source_).\n\nIf, for any reason, verification fails, like, for example, with expired or a `self-signed certificate`_,\nwe'll get ``ssl.SSLCertVerificationError`` instead of the requested info.\n\nWe can work around this by asking for the certificate in the binary form:\n\n.. code-block:: python3\n\n getpeercert(binary_form=True)\n\nBut now we have to convert it, and thus we can use a third party ``asn1crypto`` module, instead of\nthe (bulkier) ``cryptography`` module.\n\nCredits\n-------\n\nThis package was created with Cookiecutter_ and the `rnag/cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/cookiecutter/cookiecutter\n.. _`rnag/cookiecutter-pypackage`: https://github.com/rnag/cookiecutter-pypackage\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python Stand-alone Library to Download the SSL Certificate for Any Host\u2122",
"version": "0.3.0",
"project_urls": {
"Documentation": "https://cert-hero.readthedocs.io",
"Homepage": "https://github.com/rnag/cert-hero",
"Source": "https://github.com/rnag/cert-hero"
},
"split_keywords": [
"cert-hero",
"cert",
"ssl",
"certificate",
"host cert"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "724a95732c56374b4a7471539069003367b72313ae8bec6866212e9c35c3658a",
"md5": "3d86adb2479819894f6a3c86fb7f27cb",
"sha256": "f4c3f8bea08586258a21d6aafe6e32a45fa5aa64e78b024387a1808576ff18d0"
},
"downloads": -1,
"filename": "cert_hero-0.3.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "3d86adb2479819894f6a3c86fb7f27cb",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.6",
"size": 12234,
"upload_time": "2023-10-17T16:35:37",
"upload_time_iso_8601": "2023-10-17T16:35:37.660133Z",
"url": "https://files.pythonhosted.org/packages/72/4a/95732c56374b4a7471539069003367b72313ae8bec6866212e9c35c3658a/cert_hero-0.3.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2dbb91b114e4e8684b94ef0408496be97ea9ce1f3fabbaf5e9d4606deff48794",
"md5": "94f86732906876ebf8e37d505faab5e5",
"sha256": "469ab6588448699dde34bbf1772e3560fde9cbc44c0c87ef78e4480f8b52a409"
},
"downloads": -1,
"filename": "cert-hero-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "94f86732906876ebf8e37d505faab5e5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 19062,
"upload_time": "2023-10-17T16:35:39",
"upload_time_iso_8601": "2023-10-17T16:35:39.176400Z",
"url": "https://files.pythonhosted.org/packages/2d/bb/91b114e4e8684b94ef0408496be97ea9ce1f3fabbaf5e9d4606deff48794/cert-hero-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-17 16:35:39",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rnag",
"github_project": "cert-hero",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "cert-hero"
}