{"id":18383397,"url":"https://github.com/dwolla/fs2-pgp","last_synced_at":"2025-04-06T23:32:13.003Z","repository":{"id":38348315,"uuid":"306698453","full_name":"Dwolla/fs2-pgp","owner":"Dwolla","description":"fs2 pipes for encrypting and decrypting data using BouncyCastle's PGP implementation","archived":false,"fork":false,"pushed_at":"2025-03-17T08:15:04.000Z","size":333,"stargazers_count":4,"open_issues_count":6,"forks_count":3,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-03-22T09:12:07.533Z","etag":null,"topics":["bouncycastle","cats-effect","fs2","gpg","hacktoberfest","pgp"],"latest_commit_sha":null,"homepage":"https://dwolla.com","language":"Scala","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/Dwolla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-23T17:05:27.000Z","updated_at":"2025-01-29T01:20:50.000Z","dependencies_parsed_at":"2024-01-02T21:43:56.580Z","dependency_job_id":"285a2466-7672-4ade-8bb2-f1801dbf105c","html_url":"https://github.com/Dwolla/fs2-pgp","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dwolla%2Ffs2-pgp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dwolla%2Ffs2-pgp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dwolla%2Ffs2-pgp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dwolla%2Ffs2-pgp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dwolla","download_url":"https://codeload.github.com/Dwolla/fs2-pgp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247569124,"owners_count":20959758,"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":["bouncycastle","cats-effect","fs2","gpg","hacktoberfest","pgp"],"created_at":"2024-11-06T01:11:15.400Z","updated_at":"2025-04-06T23:32:10.834Z","avatar_url":"https://github.com/Dwolla.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fs2-pgp\n\nA library for encrypting and decrypting fs2 `Stream[F, Byte]` using PGP.\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eArtifact\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003cth align=\"center\"\u003eCats Effect Version\u003c/th\u003e\n\u003cth align=\"center\"\u003efs2 Version\u003c/th\u003e\n\u003cth align=\"center\"\u003eScala 2.12\u003c/th\u003e\n\u003cth align=\"center\"\u003eScala 2.13\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\"fs2-pgp\"\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eLoad PGP keys and use them to encrypt, decrypt, and armor byte streams.\u003c/td\u003e\n\u003ctd align=\"center\"\u003eCats Effect 3\u003c/td\u003e\n\u003ctd align=\"center\"\u003efs2 3.x\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cg-emoji class=\"g-emoji\" alias=\"white_check_mark\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/2705.png\"\u003e✅\u003c/g-emoji\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cg-emoji class=\"g-emoji\" alias=\"white_check_mark\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/2705.png\"\u003e✅\u003c/g-emoji\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003e\"pgp-testkit\"\u003c/code\u003e\u003c/td\u003e\n\u003ctd\u003eScalaCheck Generators and Arbitrary instances for PGP classes\u003c/td\u003e\n\u003ctd align=\"center\"\u003eCats Effect 3\u003c/td\u003e\n\u003ctd align=\"center\"\u003efs2 3.x\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cg-emoji class=\"g-emoji\" alias=\"white_check_mark\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/2705.png\"\u003e✅\u003c/g-emoji\u003e\u003c/td\u003e\n\u003ctd align=\"center\"\u003e\u003cg-emoji class=\"g-emoji\" alias=\"white_check_mark\" fallback-src=\"https://github.githubassets.com/images/icons/emoji/unicode/2705.png\"\u003e✅\u003c/g-emoji\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n## Bouncy Castle Versions\n\nBouncy Castle often releases versions that report as binary-incompatible with \nprevious versions when examined with a tool such as [MiMa](https://github.com/lightbend/mima).\nThe \"current\" version of the artifacts published by this project intend to track\nthe latest Bouncy Castle version, with previously supported versions published \nas supplemental artifacts with the supported Bouncy Castle version appended to\nthe artifact name.\n\nFor example, the latest Bouncy Castle version is `1.77`, so the latest version of\n`com.dwolla::fs2-pgp` depends on `org.bouncycastle:bcpg-jdk18on:1.77`. In addition,\nwe publish artifacts named like `com.dwolla::fs2-pgp-bcpg1.76` for each of the\npreviously supported Bouncy Castle artifacts.\n\n## Keys\n\n```scala\nimport com.dwolla.security.crypto._\nimport cats.effect._\n\nval key =\n  \"\"\"-----BEGIN PGP PUBLIC KEY BLOCK-----\n    |Version: GnuPG v1\n    |\n    |mQENBFVoyeYBCACy0S/9y/c/CpoYLL6aD3TMCV1Pe/0jcWN0ykULf9l4znYODZLr\n    |f10BGAJETj9ghrJCNXMib2ogz0wo43KVAp9o3mkg01vVyqs1rzM5jw+yCZmyGPFf\n    |GsE2lxZFMX+rS0dyq2w0FQN2IjYsELwIFeQ02GXTLyTlhY+u5wwCXo4e7AEXaEo7\n    |jl8129NA46gf6l+6lUMyFpKnunO7L4W5rCCrIizP4Fmll1adYfClSX6cztIfz4vg\n    |Fs2HuViPin5y8THodkg9cIkCfyNHivEbfBbx0xfx67BCwxFcYgF/84H8TASRhjRl\n    |4s1fZDA7rETWDJIcC+neNV/qtF0kY1ECSd3nABEBAAG0IFRlc3QgVXNlciA8ZnJl\n    |ZCt0ZXN0QGR3b2xsYS5jb20+iQE4BBMBAgAiBQJVaMnmAhsDBgsJCAcDAgYVCAIJ\n    |CgsEFgIDAQIeAQIXgAAKCRA2OYfNakCqV1bYB/9QNR5DN5J27Z4DIGoOto/PuVvs\n    |bQHZj8NLcvIZL1cUyKOg+oRICq2z4BXHAMqyouhs/GLiR5P74I9cJTSIudAvBhwi\n    |du9AcMQy+Qg3K1rUQGlNU+iamD8DFNUhLoK+Oicij0Mw4TSWBsoR3+Pg/jZ5SDUc\n    |dUsGGaBJthYoiJR8vZ6Uf9oCn+mpVhrso0zemBDud4AHKaVa+8o7VUWGa6jeyRHX\n    |RKVbHn7GGYiHZkl+qfpthcxyPHOIkZo+t8GVTItLpvVuU+X36N70+rIzXj5t8NDZ\n    |KfD3M4p6BSq6Cu6DtJOZ1F28hwaWiRoCdbPrJfW33fo1RxLB6+nLf/ttYGmhuQEN\n    |BFVoyeYBCADiZfKA98YQip/kvj5rBS2ilQDycBX7Ls2IftuwzO6Q9QSF2lDiz708\n    |zyvg0czQPZYaZkFgziZEmjbvOc7hDG+icVWRLCjCcZk4i2TXy7bGcTZmBQ31iVMJ\n    |ia7GxsJhu4ngrP15pZakAYcCwEk3QH17TdhOwvV8ixHmv9USCMJyiNnuhVAP2tY/\n    |Ef0EoCV6qAMoP3dNPT30sFI8+55Ce9yAtWQItT5q4vYOmC9Q34XtSxvpLsLzVByd\n    |rdvgXe0acjvMiTGcYBdjitawFYeLuz2s5mQAi4X1vcJqxBSBjG7X+1PiDqFFIid3\n    |+6rIQtR3ho+Xqz/ucGglKxtn6m49wMHJABEBAAGJAR8EGAECAAkFAlVoyeYCGwwA\n    |CgkQNjmHzWpAqldxFgf/SZIT1AiBAOLkqdWEObg0cU7n1YOXbj56sUeUCFxdbnl9\n    |V2paf2SaMB6EEGLTk9PN0GG3hPyDkl4O6w3mn2J46uP8ecVaNvTSxoq2OmkMmD1H\n    |/OSnF8a/jB6R1ODiAwekVuUMtAS7JiaAAcKcenG1f0XRKwQs52uavGXPgUuJbVtK\n    |bB0SyLBhvGG8YIWTXRMHoJRt/Ls4JEuYaoBYqfV2eDn4WhW1LVuXP13gXixy0RiV\n    |8rHs9aH8BAU7Dy0BBnaS3R9m8vtfdFxMI3/+1iGt0+xh/B4w++9oFE2DgyoZXUF8\n    |mbjKYhiRPKNoj6Rn/mHUGcnuPlKvKP+1X5bObpDbQQ==\n    |=TJUS\n    |-----END PGP PUBLIC KEY BLOCK-----\"\"\".stripMargin\n\nPGPKeyAlg[IO].readPublicKey(key).unsafeRunSync()\nval res0: org.bouncycastle.openpgp.PGPPublicKey = org.bouncycastle.openpgp.PGPPublicKey@1003b416\n```\n\n## Encryption\n\nRead a `PGPPublicKey` using `PGPKeyAlg[F]`, then pipe your message bytes through `CryptoAlg[F].encrypt`. \n\n```scala\nimport cats.effect._\nimport cats.syntax.all._\nimport org.typelevel.log4cats.Logger\nimport fs2._\nimport fs2.text._\nimport com.dwolla.security.crypto._\nimport org.bouncycastle.openpgp._\n\nval key: PGPPublicKey = ??? // from above\n\n(for {\n  crypto \u003c- Stream.resource(CryptoAlg[IO])\n  output \u003c- Stream.emit(\"hello world\")\n                  .through(utf8.encode)\n                  .through(crypto.encrypt(key))\n                  .through(crypto.armor())\n                  .through(utf8.decode)\n} yield output).compile.string.unsafeRunSync()\nval res1: String =\n\"-----BEGIN PGP MESSAGE-----\nVersion: BCPG v1.66\n\nhQEMAzY5h81qQKpXAQf/YTq6GtTkWlbg2DRu7r133FZaAudA149WB2BV/vsgyHkN\n…\n\"\n```\n\n## Decryption\n\nRead a `PGPPrivateKey` using `PGPKeyAlg[F]`, then pipe the encrypted message bytes through `CryptoAlg[F].decrypt`. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwolla%2Ffs2-pgp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwolla%2Ffs2-pgp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwolla%2Ffs2-pgp/lists"}