{"id":15395494,"url":"https://github.com/stef/gpk","last_synced_at":"2025-04-16T00:11:00.666Z","repository":{"id":4849873,"uuid":"6004280","full_name":"stef/gpk","owner":"stef","description":"automatically generate pgp keys","archived":false,"fork":false,"pushed_at":"2014-01-15T23:44:28.000Z","size":150,"stargazers_count":10,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T03:11:15.504Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"leafo/lessphp","license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stef.png","metadata":{"files":{"readme":"README.genkeyid.org","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}},"created_at":"2012-09-28T23:21:41.000Z","updated_at":"2023-09-08T16:35:32.000Z","dependencies_parsed_at":"2022-09-18T06:47:41.346Z","dependency_job_id":null,"html_url":"https://github.com/stef/gpk","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stef%2Fgpk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stef%2Fgpk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stef%2Fgpk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stef%2Fgpk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stef","download_url":"https://codeload.github.com/stef/gpk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249173086,"owners_count":21224483,"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-10-01T15:28:31.851Z","updated_at":"2025-04-16T00:11:00.648Z","avatar_url":"https://github.com/stef.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"* genkeyid\n\nA tool that helps you bruteforce arbitrary PGP keyids by modifying the\ntimestamp field so that the packet hashes to a given keyid.\n\nSince this is a bruteforce attack on the hash algorithm to produce a\ncertain pattern in the hash we can increase our chances when we look\nfor multiple patterns. If the goal is not one specific keyid, but the\ngoal is to generate one of many keyids, then you can prepare a list of\nmultiple variations that would be acceptable, which increases your\nchances considerably to find a good keyid with a plausible date.\n\n* genkeyid.py\n\ngenkeyid.py takes a file containing a single public key and starts to\nemit all possible keyids by incrementing the Public Key Creation Time\n32bit integer from 0 upwards, recalculating the resulting hash. You\nthen have to filter this list of keyids, is it is a lot of data.\n\nA basic invocation of genkeyid would look like this:\n\n#+BEGIN_SRC sh\npython ./genkeyid.py keyring.pub 2\u003esnapshots | grep --color -i -f keycandidates | tee fps\n#+END_SRC\n\nWhere keyring.pub is either a keyring with only one public key, or\nyour exported public key. The regular expressions per line in\nkeycandidates serve as filters (see example later), as genkeyid prints\nout all possible keyids, and that is rather a lot of data, so you only\nstore your \"hits\" in the file \"fps\".\n\ngenkeyid emits snapshot ids to standard error, so you can always\nresume it from some intermediate position by supplying the 32 bit\ninteger as the second parameter after the public key in genkeyid.py\nruns to resume or skip processing (see an example in genid.sh).\n\n* setfp.py\nWhen this exhaustive bruteforce is finished after a few hours on a 3\nyear old laptop, you will have a list with potential keyids with\nvarious dates that complement the hash to the specific keyid. You\nchoose the integer from row two and use setfp.py to patch your key\nlike this:\n\n#+BEGIN_SRC sh\npython ./setfp.py \u003csecret key\u003e \u003cpublic key\u003e \u003cseconds since 1970/01/01\u003e\"\n#+END_SRC\n\nBe aware that patching the keys only works with unencrypted private\nkeys, so you should probably do this 2nd patching step only on a clean\noffline system, that you afterwards shred, if you care about good key\nhygene.\n\n* genid.sh\nThere's also genid.sh which tries to automatically generate a new key\nmatching a given keyid. There's a few optimisations that burn much\nmore entropy but generate quite recent keys:\n\n#+BEGIN_SRC sh\nksh -x ./genid.sh test \"^DEADBEEF \"\n#+END_SRC\n\nnotice the format of the regex, it is anchored at the start of the\nline, and depends on matching up to the first space, as the format\nthat genkeyid produces and which is grepped looks like this:\n\n#+BEGIN_SRC sh\n690f3700 1357248344 50 e5 f7 58 2013-01-03 22:25:44\n#+END_SRC\n\nOf course you could as mentioned earlier also look for more keyids\nwith more complex regular expressions.\n\nSo when you're done, you could do (presuming you have the binary\npgpdump installed):\n\n#+BEGIN_EXAMPLE\ndiff -urw \u003c(pgpdump test/pubring.pgp) \u003c(pgpdump test/pubring.pgp-new)\n--- /proc/self/fd/11    2013-04-04 00:36:23.307190845 +0200\n+++ /proc/self/fd/12    2013-04-04 00:36:23.307190845 +0200\n@@ -1,6 +1,6 @@\n Old: Public Key Packet(tag 6)(141 bytes)\n        Ver 4 - new\n-       Public key creation time - Thu Apr  4 00:32:22 CEST 2013\n+       Public key creation time - Fri Jan  4 15:06:30 CET 2013\n        Pub alg - RSA Encrypt or Sign(pub 1)\n        RSA n(1024 bits) - ...\n        RSA e(17 bits) - ...\n@@ -36,7 +36,7 @@\n        Hashed Sub: key server preferences(sub 23)(1 bytes)\n                Flag - No-modify\n        Sub: issuer key ID(sub 16)(8 bytes)\n-               Key ID - 0xD39531EF87CB6015\n-       Hash left 2 bytes - a2 5b\n-       RSA m^d mod n(1022 bits) - ...\n+               Key ID - 0xEDB069BE93FB0000\n+       Hash left 2 bytes - 7c b8\n+       RSA m^d mod n(1024 bits) - ...\n                -\u003e PKCS-1\n#+END_EXAMPLE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstef%2Fgpk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstef%2Fgpk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstef%2Fgpk/lists"}