{"id":17225216,"url":"https://github.com/kurtbrose/pyjks","last_synced_at":"2025-04-04T11:09:21.696Z","repository":{"id":10057045,"uuid":"12107006","full_name":"kurtbrose/pyjks","owner":"kurtbrose","description":"a pure python Java KeyStore file parser, including private key decryption","archived":false,"fork":false,"pushed_at":"2024-02-19T08:01:38.000Z","size":419,"stargazers_count":132,"open_issues_count":27,"forks_count":35,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-02T02:54:25.186Z","etag":null,"topics":["cryptography","jceks","jks","keystore","pyasn1","python","security","ssl"],"latest_commit_sha":null,"homepage":null,"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/kurtbrose.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-08-14T11:13:59.000Z","updated_at":"2025-03-31T09:16:04.000Z","dependencies_parsed_at":"2024-06-18T15:26:12.919Z","dependency_job_id":"7797c8eb-d5b0-4ed9-af11-c887f4edbe65","html_url":"https://github.com/kurtbrose/pyjks","commit_stats":{"total_commits":178,"total_committers":15,"mean_commits":"11.866666666666667","dds":0.5056179775280899,"last_synced_commit":"0a046e54337a0c271ef5f7fdd9aa79c5ad350486"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kurtbrose%2Fpyjks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kurtbrose%2Fpyjks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kurtbrose%2Fpyjks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kurtbrose%2Fpyjks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kurtbrose","download_url":"https://codeload.github.com/kurtbrose/pyjks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247166144,"owners_count":20894652,"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":["cryptography","jceks","jks","keystore","pyasn1","python","security","ssl"],"created_at":"2024-10-15T04:13:00.759Z","updated_at":"2025-04-04T11:09:21.674Z","avatar_url":"https://github.com/kurtbrose.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"pyjks\n=====\n\n\u003ca href=\"https://pyjks.readthedocs.io/en/latest/\"\u003e\u003cimg src=\"https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pypi.python.org/pypi/pyjks\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/pyjks.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"http://calver.org\"\u003e\u003cimg src=\"https://img.shields.io/badge/calver-YY.MINOR.MICRO-22bfda.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/kurtbrose/pyjks/blob/master/CHANGELOG.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/CHANGELOG-UPDATED-b84ad6.svg\"\u003e\u003c/a\u003e\n\nA pure python Java KeyStore file parser, including private/secret key decryption.\nCan read JKS, JCEKS, BKS and UBER (BouncyCastle) key stores.\n\nThe best way to utilize a certificate stored in a jks file up to this point has been\nto use the java keytool command to transform to pkcs12, and then openssl to transform to pem.\n\nThis is better:\n -  no security concerns in passwords going into command line arguments, or unencrypted files being left around\n -  no dependency on a JVM\n\n## Requirements:\n\n * Python 2.6+ or Python 3.3+\n * pyasn1 0.3.5+\n * pyasn1_modules 0.0.8+\n * javaobj-py3 0.1.4+\n * pycryptodomex, if you need to read JCEKS, BKS or UBER keystores\n * twofish, if you need to read UBER keystores\n\n## Usage examples:\n\nReading a JKS or JCEKS keystore and dumping out its contents in the PEM format:\n```python\nfrom __future__ import print_function\nimport sys, base64, textwrap\nimport jks\n\ndef print_pem(der_bytes, type):\n    print(\"-----BEGIN %s-----\" % type)\n    print(\"\\r\\n\".join(textwrap.wrap(base64.b64encode(der_bytes).decode('ascii'), 64)))\n    print(\"-----END %s-----\" % type)\n\nks = jks.KeyStore.load(\"keystore.jks\", \"XXXXXXXX\")\n# if any of the keys in the store use a password that is not the same as the store password:\n# ks.entries[\"key1\"].decrypt(\"key_password\")\n\nfor alias, pk in ks.private_keys.items():\n    print(\"Private key: %s\" % pk.alias)\n    if pk.algorithm_oid == jks.util.RSA_ENCRYPTION_OID:\n        print_pem(pk.pkey, \"RSA PRIVATE KEY\")\n    else:\n        print_pem(pk.pkey_pkcs8, \"PRIVATE KEY\")\n\n    for c in pk.cert_chain:\n        print_pem(c[1], \"CERTIFICATE\")\n    print()\n\nfor alias, c in ks.certs.items():\n    print(\"Certificate: %s\" % c.alias)\n    print_pem(c.cert, \"CERTIFICATE\")\n    print()\n\nfor alias, sk in ks.secret_keys.items():\n    print(\"Secret key: %s\" % sk.alias)\n    print(\"  Algorithm: %s\" % sk.algorithm)\n    print(\"  Key size: %d bits\" % sk.key_size)\n    print(\"  Key: %s\" % \"\".join(\"{:02x}\".format(b) for b in bytearray(sk.key)))\n\tprint()\n```\n\n\nTransforming an encrypted JKS/JCEKS file into an OpenSSL context:\n```python\nimport OpenSSL\nimport jks\n\n_ASN1 = OpenSSL.crypto.FILETYPE_ASN1\n\ndef jksfile2context(jks_file, passphrase, key_alias, key_password=None):\n    keystore = jks.KeyStore.load(jks_file, passphrase)\n    pk_entry = keystore.private_keys[key_alias]\n    # if the key could not be decrypted using the store password, decrypt with a custom password now\n    if not pk_entry.is_decrypted():\n        pk_entry.decrypt(key_password)\n\n    pkey = OpenSSL.crypto.load_privatekey(_ASN1, pk_entry.pkey)\n    public_cert = OpenSSL.crypto.load_certificate(_ASN1, pk_entry.cert_chain[0][1])\n    trusted_certs = [OpenSSL.crypto.load_certificate(_ASN1, cert.cert) for alias, cert in keystore.certs]\n\n    ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)\n    ctx.use_privatekey(pkey)\n    ctx.use_certificate(public_cert)\n    ctx.check_privatekey() # want to know ASAP if there is a problem\n    cert_store = ctx.get_cert_store()\n    for cert in trusted_certs:\n        cert_store.add_cert(cert)\n    return ctx\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkurtbrose%2Fpyjks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkurtbrose%2Fpyjks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkurtbrose%2Fpyjks/lists"}