{"id":18420295,"url":"https://github.com/secdev/sshpki","last_synced_at":"2025-07-12T07:04:57.114Z","repository":{"id":109509520,"uuid":"327921141","full_name":"secdev/sshpki","owner":"secdev","description":null,"archived":false,"fork":false,"pushed_at":"2021-01-08T14:17:09.000Z","size":45,"stargazers_count":3,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-14T19:38:13.229Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/secdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-01-08T14:11:50.000Z","updated_at":"2024-07-12T11:00:37.000Z","dependencies_parsed_at":"2023-04-12T23:46:54.158Z","dependency_job_id":null,"html_url":"https://github.com/secdev/sshpki","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/secdev/sshpki","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secdev%2Fsshpki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secdev%2Fsshpki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secdev%2Fsshpki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secdev%2Fsshpki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/secdev","download_url":"https://codeload.github.com/secdev/sshpki/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secdev%2Fsshpki/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264952352,"owners_count":23688060,"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":[],"created_at":"2024-11-06T04:21:02.335Z","updated_at":"2025-07-12T07:04:57.094Z","avatar_url":"https://github.com/secdev.png","language":"Python","readme":"# SSH PKI\n\n## What is sshpki ?\n\nsshpki is a small tool wrapping ssh-keygen to help manage ssh\ncertificate authorities, ssh certificates and key revocation lists.\n\nIt can create and keep track of host and user CA, all generated public\nkeys and associated certificates, their state (valid, expired,\nrevoked), enrolled yubikeys, etc.\n\n\nThis is still alpha software:\n- some features are missing (complete yubikey support, paper backup\n  export, commands on parameters, etc.)\n- it is possible to instroduce inconsistencies in the database if an\n  operation is stopped before it is finished (with Ctrl-C for\n  instance)\n\n## Session example\n\n### Running sshpki\n\nFirst, we create the database file:\n\n```\n$ ./sshpki.py -f /tmp/mypki -C\nSSH PKI name: mypki\n$\n```\n\nThen we can use it\n\n```\n$ ./sshpki.py -f /tmp/mypki\nmypki\u003e help\n\nDocumented commands (type help \u003ctopic\u003e):\n========================================\nhelp  shell\n\nUndocumented commands:\n======================\nEOF  ca  certs  keys  profiles  python  yubikey\n```\n\n\n### CA command\n\n```\nmypki\u003e ca\nmypki/CA\u003e create foo\nIs this a [H]ost CA or a [U]ser CA ? (h/u) u\nGenerating public/private rsa key pair.\nYour identification has been saved in /dev/shm/tmpr2FFwu/foo.\nYour public key has been saved in /dev/shm/tmpr2FFwu/foo.pub.\nThe key fingerprint is:\nSHA256:ozXd+MUM8E5yHnvcZsaa886qwfkFOQ+DkxVzkPJYI5Q foo\nThe key's randomart image is:\n+---[RSA 4096]----+\n|          ....+o.|\n|           oE ++ |\n|          . **.. |\n|         . O.@.+ |\n|        S o O % *|\n|       o o o = % |\n|      .     = + o|\n|             o = |\n|            ..oo+|\n+----[SHA256]-----+\nPlease export secret key to yubikey/file/paper backup. It will then be deleted\nmypki/CA/foo/export\u003e file /tmp/foo\nEnter new passphrase (empty for no passphrase): \nEnter same passphrase again: \nYour identification has been saved with the new passphrase.\nmypki/CA/foo/export\u003e \nSecret key has been exported. It is going to be deleted. Last chance to do another export. Delete? ? (y/n) y\nmypki/CA\u003e create bar\nIs this a [H]ost CA or a [U]ser CA ? (h/u) h\nGenerating public/private rsa key pair.\nYour identification has been saved in /dev/shm/tmpr2FFwu/bar.\nYour public key has been saved in /dev/shm/tmpr2FFwu/bar.pub.\nThe key fingerprint is:\nSHA256:9QYGpxC+ijvuq2oEcQaMaV3UUbchOVzrQYgxl4IOF2A bar\nThe key's randomart image is:\n+---[RSA 4096]----+\n|+o.E++*=B+*=     |\n|+o+o + =oX+ +    |\n|.+  + . o =+     |\n|.    . . o.o.    |\n|.     . S  .o    |\n| . . .     .     |\n|. . .            |\n| ...             |\n|=+=o             |\n+----[SHA256]-----+\nPlease export secret key to yubikey/file/paper backup. It will then be deleted\nmypki/CA/bar/export\u003e \nSecret key has not been exported. Are you sure you want to delete it? ? (y/n) y\nmypki/CA\u003e ls\nfoo                              active USER signed  0 keys\nbar                              active HOST signed  0 keys\nmypki/CA\u003e use foo\nmypki/CA/foo\u003e create k1\nEnter cert name: k1_0\nGenerating public/private rsa key pair.\nYour identification has been saved in /dev/shm/tmpr2FFwu/k1.\nYour public key has been saved in /dev/shm/tmpr2FFwu/k1.pub.\nThe key fingerprint is:\nSHA256:xisJnRIE4dcYQp9yGbaWUleP9a9KWTm749UMDNEB9xA k1\nThe key's randomart image is:\n+---[RSA 2048]----+\n| .=o* ... . ooEo |\n| . * @   + . o.o |\n|  + % . . . o   .|\n|   * o o     =   |\n|    o o S   + +  |\n|     o o . o + + |\n|      o . o o . o|\n|       . . ..o   |\n|          ..o.   |\n+----[SHA256]-----+\nPlease export secret key to yubikey/file/paper backup. It will then be deleted\nmypki/CA/foo/k1/export\u003e \nSecret key has not been exported. Are you sure you want to delete it? ? (y/n) y\nChoose profile:\n 0. Create a new profile\nprofile:  ? (0) 0\nmypki/CA/foo/profiles\u003e create nolimit\nName: nolimit\nPrincipals: \nForce command: \nEnforce source addresses: \nPermit agent forwarding ? (y/n) y\nPermit port forwarding ? (y/n) y\nPermit X11 forwarding ? (y/n) y\nPermit PTY allocation ? (y/n) y\nPermit user ~/.ssh/rc file ? (y/n) y\nvalidity interval\n    empty or \u003cend\u003e or \u003cstart\u003e:\u003cend\u003e ; \u003cstart\u003e or \u003cend\u003e being\n    - YYYYMMDD\n    - YYYYMMDDHHMMSS\n    - [+-]([0-9]+[wdhms]){1,}):\n\nmypki/CA/foo/profiles\u003e create 90days\nName: 90days\nPrincipals: root\nForce command: \nEnforce source addresses: 1.2.3.4\nPermit agent forwarding ? (y/n) y\nPermit port forwarding ? (y/n) y\nPermit X11 forwarding ? (y/n) y\nPermit PTY allocation ? (y/n) y\nPermit user ~/.ssh/rc file ? (y/n) y\nvalidity interval\n    empty or \u003cend\u003e or \u003cstart\u003e:\u003cend\u003e ; \u003cstart\u003e or \u003cend\u003e being\n    - YYYYMMDD\n    - YYYYMMDDHHMMSS\n    - [+-]([0-9]+[wdhms]){1,}):\n+90d\nmypki/CA/foo/profiles\u003e ls\nnolimit                        no limits\n90days                         principals=root, source_address=1.2.3.4, validity=+90d\nmypki/CA/foo/profiles\u003e \nChoose profile:\n 0. Create a new profile\n 1. nolimit              no limits\n 2. 90days               principals=root, source_address=1.2.3.4, validity=+90d\nprofile:  ? (0/1/2) 1\nWhere is the private CA key ?\n 0. Enter a file path\n 1. file /tmp/foo\nprivate key source:  ? (0/1) 1\nSigned user key /dev/shm/tmpr2FFwu/tmpnH4fX7-cert.pub: id \"k1_0\" serial 0 valid forever\nmypki/CA/foo\u003e ls\nk1                             ACTIVE  2048 bits:\n  -\u003e certificate k1_0         0 no limits \nmypki/CA/foo\u003e create k2\nEnter cert name: k2_1\nGenerating public/private rsa key pair.\nYour identification has been saved in /dev/shm/tmpr2FFwu/k2.\nYour public key has been saved in /dev/shm/tmpr2FFwu/k2.pub.\nThe key fingerprint is:\nSHA256:cMFDsUjaWOi5qGfqbW70bXnHx+KuEL7XqO/eD8x2Hd4 k2\nThe key's randomart image is:\n+---[RSA 2048]----+\n|     .oo+.       |\n|    .* .oo       |\n|   .o.+ o.       |\n|    o  o         |\n|   . . .S      . |\n|  ... . . o   o o|\n| .. . .o. +=.. oE|\n|. +o . +o+o=oo   |\n|o=+o  .oB==++.   |\n+----[SHA256]-----+\nPlease export secret key to yubikey/file/paper backup. It will then be deleted\nmypki/CA/foo/k2/export\u003e \nSecret key has not been exported. Are you sure you want to delete it? ? (y/n) y\nChoose profile:\n 0. Create a new profile\n 1. nolimit              no limits\n 2. 90days               principals=root, source_address=1.2.3.4, validity=+90d\nprofile:  ? (0/1/2) 2\nWhere is the private CA key ?\n 0. Enter a file path\n 1. file /tmp/foo\nprivate key source:  ? (0/1) 1\nSigned user key /dev/shm/tmpr2FFwu/tmpyIZtl_-cert.pub: id \"k2_1\" serial 1 for root valid from 2018-06-15T03:12:00 to 2018-09-13T03:13:46\nmypki/CA/foo\u003e ls\nk1                             ACTIVE  2048 bits:\n  -\u003e certificate k1_0         0 no limits \nk2                             ACTIVE  2048 bits:\n  -\u003e certificate k2_1         1 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:12:00 2018 to Thu Sep 13 03:13:46 2018\nmypki/CA/foo\u003e resign k2\nWhere is the private CA key ?\n 0. Enter a file path\n 1. file /tmp/foo\nprivate key source:  ? (0/1) 1\nSigned user key /dev/shm/tmpr2FFwu/tmplfOigc-cert.pub: id \"k2_2\" serial 2 for root valid from 2018-06-15T03:13:00 to 2018-09-13T03:13:59\nmypki/CA/foo\u003e ls\nk1                             ACTIVE  2048 bits:\n  -\u003e certificate k1_0         0 no limits \nk2                             ACTIVE  2048 bits:\n  -\u003e certificate k2_1         1 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:12:00 2018 to Thu Sep 13 03:13:46 2018\n  -\u003e certificate k2_2         2 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:13:00 2018 to Thu Sep 13 03:13:59 2018\nmypki/CA/foo\u003e show\ncert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCmFjufXD7XBKT3nhJctIRenfrBsTquMCLvc6V3AkJazEyb9isOUfa1ntKUhwwnVg36jGnTYBQsPCISPvl/K56lBRUruIP2f8mcGFRiN2huFq/2r7NXWMX0PB2lnC+rRXuCSTrVyZLEm0l/uabG+v38yz1Tq2M8A768JEcdXhsqe6+NNvYcr24p1ksU7C/SWfTzi4NZIfkz1xguWmcsTkyVYu3DNhKO/XgbyspJ753swV9KXw++Pq9bcyxuhDzGDp42J/pbWE3DcKyhRMGJUR7AX0EOZNK1lo4KpWoyH2h+ZTqXfkjH4oWv2IFhOwjtDTfvS/5NQl23HLb+LlkDZtGAAQuyDV7QnTE+n0mg/mvnbRyRpmfze+CnieNfcNJA+p34asyUrz+nJ6r0tqk+8W2aU+Zqa49Hg6lNkQYg+aV5sJQ0MLGeqJZKlsqB95YDYb3cgM8Q/pmy4/Z9Bg6qy06LRTtfbOubvKTvEROoFcmEvQbAdiDX3rwwy8rRpxIxT0XUd03uy/NymSkHixa+JSmLYaaUjntlHmapEKvXh2HzBZ342/Cg29DSut0Ht9CRU/9KHEqJrno/1l7+LA1moqxIqx2X/ipExMWSYGu1zNjdtMluv7OaQFFYOFb3C1JroXYyeG9FBgGNq8d7UDL5DDgN3SpimdTPIBI37LD+pSzkQ== foo\n\nmypki/CA/foo\u003e show_cert k1_0\nssh-rsa-cert-v01@openssh.com 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 k1\n\nmypki/CA/foo\u003e show_key k1\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDgnhWmd9nUahXYwUg/d4by0L4ynxXl/AepzDcfBvWaBCwAC7cLYE2lXlM5BZ/Sfx+9W+b/1QssLmx73Od7wH1wRPQl5zCdqLijShpYdQeLDggO3MQeOGlA/Gs9imF2PwUGbqnu5rtJcb2rd6exXrHjozutF+P+7tzfK6B5ZkwpqeQPOk59+ZM3qdNzHFV24unfgZB8xG9NXFZxxh2DbGJVaQ5N8+BohFixaICdpeQDYbsORH84MzZVAt45waWsy5UkCK0vdLFp+Go4XpF4TBullED1rA/kOvsbMH8bZ5GaxJ+dYWTI2Z+3P3CKrGxJLBZh7/plUvhk1LEN2SE50yQ/ k1\n\nmypki/CA/foo\u003e export\nexport      export_krl  \nmypki/CA/foo\u003e export_krl /tmp/krl\nmypki/CA/foo\u003e !hd /tmp/krl\n00000000  53 53 48 4b 52 4c 0a 00  00 00 00 01 00 00 00 00  |SSHKRL..........|\n00000010  00 00 00 00 00 00 00 00  5b 23 12 71 00 00 00 00  |........[#.q....|\n00000020  00 00 00 00 00 00 00 00  00 00 00 00              |............|\n0000002c\nmypki/CA/foo\u003e revoke k2\nAre you sure you want to revoke key [k2] ? (y/n) y\nRevoking from /dev/shm/tmpr2FFwu/tmpvPnH2t\nRevoking from /dev/shm/tmpr2FFwu/tmp9I1Tzz\nmypki/CA/foo\u003e ls\nk1                             ACTIVE  2048 bits:\n  -\u003e certificate k1_0         0 no limits \nk2                             REVOKED 2048 bits:\n  -\u003e certificate k2_1         1 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:12:00 2018 to Thu Sep 13 03:13:46 2018\n  -\u003e certificate k2_2         2 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:13:00 2018 to Thu Sep 13 03:13:59 2018\nmypki/CA/foo\u003e export_krl /tmp/krl\nmypki/CA/foo\u003e !hd /tmp/krl\n00000000  53 53 48 4b 52 4c 0a 00  00 00 00 01 00 00 00 00  |SSHKRL..........|\n00000010  00 00 00 00 00 00 00 00  5b 23 13 19 00 00 00 00  |........[#......|\n00000020  00 00 00 00 00 00 00 00  00 00 00 00 03 00 00 00  |................|\n00000030  18 00 00 00 14 ba dd 3e  dd 5f 92 53 86 ff 3b 1c  |.......\u003e._.S..;.|\n00000040  e2 51 d9 4e b7 da 2e 3c  4c                       |.Q.N...\u003cL|\n00000049\n```\n### Other commands\n\n```\nmypki\u003e keys\nmypki/keys\u003e ls\nfoo                            CA   ACTIVE   4096 bits  \nbar                            CA   ACTIVE   4096 bits  \nk1                             user ACTIVE   2048 bits  signed by [foo]\nk2                             user REVOKED  2048 bits  signed by [foo]\nmypki/keys\u003e \nmypki\u003e certs\nmypki/certs\u003e ls\nk1_0                 key=k1                   foo             0 no limits \nk2_1                 key=k2                   foo             1 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:12:00 2018 to Thu Sep 13 03:13:46 2018\nk2_2                 key=k2                   foo             2 principals=root, source_address=1.2.3.4, validity=+90d from Fri Jun 15 03:13:00 2018 to Thu Sep 13 03:13:59 2018\nmypki/certs\u003e \nmypki\u003e \nEOF       ca        certs     help      keys      profiles  python    shell     yubikey   \nmypki\u003e profiles\nmypki/profiles\u003e ls\nnolimit                        no limits\n90days                         principals=root, source_address=1.2.3.4, validity=+90d\nmypki/profiles\u003e \nmypki\u003e yubikey\nmypki/yubikey\u003e l\n*** Unknown syntax: l\nmypki/yubikey\u003e ls\nmypki/yubikey\u003e \nEOF     del     enroll  help    ls      python  shell   status  \nmypki/yubikey\u003e enroll\nEnter yubikey owner: bob\nThis operation will erase all material on yubikey [3361077]. Continue ? (y/n) y\nSet mode to CCID. Please unplug and replug the yubikey and press enter.\nResetting material\nSuccessfully reset the application.\nSuccessfully set new management key.\nA new management key has been set\nPUK and PIN must be between 6 and 8 digits\nEnter new puk: \nVerifying - Enter new puk: \nSuccessfully changed the puk code.\nEnter new pin: \nVerifying - Enter new pin: \nSuccessfully changed the pin code.\nmypki/yubikey\u003e ls\n3361077    owned by bob        not used\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecdev%2Fsshpki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecdev%2Fsshpki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecdev%2Fsshpki/lists"}