{"id":17169142,"url":"https://github.com/rnag/cert-hero","last_synced_at":"2025-06-25T21:34:16.953Z","repository":{"id":200470240,"uuid":"705824822","full_name":"rnag/cert-hero","owner":"rnag","description":"Python Stand-alone Library to Download the SSL Certificate for Any Host™","archived":false,"fork":false,"pushed_at":"2023-11-06T20:11:37.000Z","size":213,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-13T16:05:29.084Z","etag":null,"topics":["asn","asn1crypto","cert","certificate","python","python-ssl","python3","ssl","ssl-cert","ssl-certificates"],"latest_commit_sha":null,"homepage":"https://cert-hero.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rnag.png","metadata":{"files":{"readme":"README.rst","changelog":"HISTORY.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-10-16T19:02:05.000Z","updated_at":"2023-11-09T04:06:53.000Z","dependencies_parsed_at":"2023-10-25T18:40:48.766Z","dependency_job_id":null,"html_url":"https://github.com/rnag/cert-hero","commit_stats":null,"previous_names":["rnag/cert-hero"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fcert-hero","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fcert-hero/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fcert-hero/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rnag%2Fcert-hero/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rnag","download_url":"https://codeload.github.com/rnag/cert-hero/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741198,"owners_count":21154253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asn","asn1crypto","cert","certificate","python","python-ssl","python3","ssl","ssl-cert","ssl-certificates"],"created_at":"2024-10-14T23:25:10.848Z","updated_at":"2025-04-13T16:05:41.178Z","avatar_url":"https://github.com/rnag.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"=========\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™*\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 -\u003e \\n{cert!r}')\n\n    cert_hero.set_expired(cert)\n    print(f'Validity -\u003e\\n{cert[\"Validity\"]}')\n\n*Output (Sample)*\n\n.. code::\n\n    Cert is Valid Till: 2023-10-28\n    Cert -\u003e\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 -\u003e\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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnag%2Fcert-hero","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frnag%2Fcert-hero","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frnag%2Fcert-hero/lists"}