{"id":13827042,"url":"https://github.com/skeeto/pgp-poisoner","last_synced_at":"2025-07-10T18:35:12.317Z","repository":{"id":66813685,"uuid":"201387280","full_name":"skeeto/pgp-poisoner","owner":"skeeto","description":"PGP key poisoner","archived":false,"fork":false,"pushed_at":"2020-01-19T18:17:46.000Z","size":5,"stargazers_count":36,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-13T16:55:46.890Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skeeto.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}},"created_at":"2019-08-09T04:08:07.000Z","updated_at":"2023-10-14T02:32:24.000Z","dependencies_parsed_at":"2023-02-27T20:15:28.770Z","dependency_job_id":null,"html_url":"https://github.com/skeeto/pgp-poisoner","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/skeeto/pgp-poisoner","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skeeto%2Fpgp-poisoner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skeeto%2Fpgp-poisoner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skeeto%2Fpgp-poisoner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skeeto%2Fpgp-poisoner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skeeto","download_url":"https://codeload.github.com/skeeto/pgp-poisoner/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skeeto%2Fpgp-poisoner/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264631212,"owners_count":23640941,"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-08-04T09:01:49.030Z","updated_at":"2025-07-10T18:35:12.273Z","avatar_url":"https://github.com/skeeto.png","language":"Go","funding_links":[],"categories":["\u003ca id=\"295e14c39bf33cd5136be8ced9383746\"\u003e\u003c/a\u003e工具","Go"],"sub_categories":["\u003ca id=\"3bd67ee9f322e2c85854991c85ed6da0\"\u003e\u003c/a\u003e投毒\u0026\u0026Poisoning"],"readme":"# PGP Key Poisoner\n\nThis tool poisons PGP keys by attaching thousands, or more, valid but\nuseless signatures. When these signatures are uploaded to a keyserver,\nthe [targeted key becomes unusable][info]. The current, popular OpenPGP\nimplementations are not robust against such attacks.\n\n## Usage\n\nAll inputs must be in binary form, not ASCII-armored. All outputs are\nalso in binary form. The target key is fed to standard input, and the\npoisoned form is written to standard output. Only the first user ID on\nthe input is poisoned.\n\n```\nusage: pgp-poisoner [-k FILE] [-n INT] \u003ctarget.pgp \u003epoisoned.pgp\n  -h         print this help message\n  -k FILE    signing secret keys output file [keys.pgp]\n  -n INT     number of signatures to append [65536]\n```\n\nEach signature is valid, and all of the signing secret keys are saved to\n`keys.pgp` (configured via `-k`). In addition to the poisoned key, these\nkeys could also be uploaded to keyservers to further harden the attack.\nThe keys and signatures are given various random creation dates and\nnames so that they cannot easily be filtered out.\n\nThe tool generates around 6,500 new signatures per second, so you can\ncreate a million junk signatures in just a few minutes.\n\n### Poisoning a test key\n\nWant to see what a poisoned key looks like when imported to GnuPG? This\nwill attach 200,000 junk signatures to a locally-generated key. I chose\nrsa4096, but the kind of key doesn't actually matter.\n\n    $ mkdir gen\n    $ gpg --homedir gen --batch --passphrase '' --quick-gen-key foo rsa4096\n    $ gpg --homedir gen --export \u003eclean.pgp\n    $ pgp-poisoner -n200000 \u003cclean.pgp \u003epoison.pgp\n\nAfter a few seconds you will now have two outputs: the poisoned key,\n`poison.pgp` (23MB), and all the secret keys used to create the\nsignatures, `keys.pgp` (40MB). Try importing the poisoned key onto a\ntemporary keyring:\n\n    $ mkdir tmp\n    $ gpg --homedir tmp --import poison.pgp\n\nAs of GnuPG 2.2.17, this last command will lock up for about 15 minutes,\nthen ultimately fail to import the key after printing bogus information\nabout it. Trying to `--recv-key` this key from a keyserver would have\nsimilar results, making the key unusable.\n\n## Why?\n\nFirst and foremost, this tool creates configurable test inputs for\nOpenPGP implementations. My initial motivation was observing how various\nimplementations handle these inputs.\n\nFurther, this attack has been known for years, and in 2019 it's been\nused against real keys on keyservers. This tool is nothing new and does\nnot create any new capabilities. It's merely proof that such attacks are\n*very* easy to pull off. **It doesn't take a nation-state actor to break\nthe PGP ecosystem, just one person and couple evenings studying RFC\n4880**. This system is not robust.\n\nAs far as keyserver weaknesses go, key poisoning attacks are really just\nscratching the surface. For example, did you know other people can bind\nyour subkeys to their primary key? Even when (if?) this fire is put out,\nmore will likely follow.\n\nThis tool does not handle the final step of uploading the poisoned key\nto a keyserver, and there are a couple minor technical challenges\ninvolved in doing so successfully, probably beyond the reach of script\nkiddies. As shown, GnuPG chokes on poisoned keys — which is why the\nattack works so well — so it's not just a simple matter of importing the\npoisoned key and using `--send-keys.` I'm not interested in actually\ndoing this step, so I will not solve these issues.\n\n\n[info]: https://gist.github.com/rjhansen/67ab921ffb4084c865b3618d6955275f\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskeeto%2Fpgp-poisoner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskeeto%2Fpgp-poisoner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskeeto%2Fpgp-poisoner/lists"}