{"id":13801496,"url":"https://github.com/jacklinquan/micropython-cryptocfb","last_synced_at":"2025-06-10T18:13:19.823Z","repository":{"id":57441475,"uuid":"462599466","full_name":"jacklinquan/micropython-cryptocfb","owner":"jacklinquan","description":"A Python module to encrypt and decrypt data with AES-128 CFB mode.","archived":false,"fork":false,"pushed_at":"2022-04-28T06:55:52.000Z","size":9,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-07T23:27:00.860Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jacklinquan.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":null,"security":null,"support":null}},"created_at":"2022-02-23T05:49:36.000Z","updated_at":"2025-02-15T16:29:53.000Z","dependencies_parsed_at":"2022-09-06T02:40:19.090Z","dependency_job_id":null,"html_url":"https://github.com/jacklinquan/micropython-cryptocfb","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/jacklinquan%2Fmicropython-cryptocfb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacklinquan%2Fmicropython-cryptocfb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacklinquan%2Fmicropython-cryptocfb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacklinquan%2Fmicropython-cryptocfb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jacklinquan","download_url":"https://codeload.github.com/jacklinquan/micropython-cryptocfb/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacklinquan%2Fmicropython-cryptocfb/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259123923,"owners_count":22808876,"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-04T00:01:23.475Z","updated_at":"2025-06-10T18:13:19.795Z","avatar_url":"https://github.com/jacklinquan.png","language":"Python","readme":"# micropython-cryptocfb\n[![PayPal Donate][paypal_img]][paypal_link]\n[![PyPI version][pypi_img]][pypi_link]\n[![Downloads][downloads_img]][downloads_link]\n\n  [paypal_img]: https://github.com/jacklinquan/images/blob/master/paypal_donate_badge.svg\n  [paypal_link]: https://www.paypal.me/jacklinquan\n  [pypi_img]: https://badge.fury.io/py/micropython-cryptocfb.svg\n  [pypi_link]: https://badge.fury.io/py/micropython-cryptocfb\n  [downloads_img]: https://pepy.tech/badge/micropython-cryptocfb\n  [downloads_link]: https://pepy.tech/project/micropython-cryptocfb\n\nA Python module to encrypt and decrypt data with AES-128 CFB mode.\n\nThis module works under MicroPython and it is tested with MicroPython V1.18.\n\nFor a compatible CPython version, please find [Python package cryptocfb](https://github.com/jacklinquan/cryptocfb).\n\nFor a compatible C version, please find [Python package cryptocfb_C_implementation](https://github.com/jacklinquan/cryptocfb_C_implementation).\n\n## Installation\n``` Python\n\u003e\u003e\u003e import upip\n\u003e\u003e\u003e upip.install('micropython-cryptocfb')\n```\nAlternatively just copy cryptocfb.py to the MicroPython device.\n\n## Usage\n``` python\n\u003e\u003e\u003e from cryptocfb import CryptoCFB\n\u003e\u003e\u003e\n\u003e\u003e\u003e key = b'0123456789abcdef'\n\u003e\u003e\u003e iv = bytes(reversed(key))\n\u003e\u003e\u003e cfb = CryptoCFB(key, iv)\n\u003e\u003e\u003e\n\u003e\u003e\u003e plain = b'This is a long message that needs to be encrypted.'\n\u003e\u003e\u003e cipher = cfb.encrypt(plain)\n\u003e\u003e\u003e cipher\nbytearray(b\"_#\\xbf\\x02\\xd6\\x19\\x0c)\\xd9\\x18\\xaf\\xb9\\xa4{JP\\xf6j\\xa3\\xb2\\xb2\\xc6b\\x9f\\xae\\x82\\xa5\\xd4\\xaeen\\xde\\x12\\x16\\xfb\\xf6\\x079\\x83\\xd2\\xbdC\\'\\x93\\x9e\\xc3\\xeb\\xc7\\x03\\x82\")\n\u003e\u003e\u003e len(plain)\n50\n\u003e\u003e\u003e len(cipher)\n50\n\u003e\u003e\u003e cfb.reset_vector()\n\u003e\u003e\u003e\n\u003e\u003e\u003e cfb.decrypt(cipher)\nbytearray(b'This is a long message that needs to be encrypted.')\n\u003e\u003e\u003e cfb.reset_vector()\n\u003e\u003e\u003e\n\u003e\u003e\u003e ba = bytearray(plain)\n\u003e\u003e\u003e ba1 = ba[0:16]\n\u003e\u003e\u003e ba2 = ba[16:32]\n\u003e\u003e\u003e ba3 = ba[32:48]\n\u003e\u003e\u003e ba4 = ba[48:64]\n\u003e\u003e\u003e cfb.crypt_inplace(ba1)\nbytearray(b'_#\\xbf\\x02\\xd6\\x19\\x0c)\\xd9\\x18\\xaf\\xb9\\xa4{JP')\n\u003e\u003e\u003e cfb.crypt_inplace(ba2)\nbytearray(b'\\xf6j\\xa3\\xb2\\xb2\\xc6b\\x9f\\xae\\x82\\xa5\\xd4\\xaeen\\xde')\n\u003e\u003e\u003e cfb.crypt_inplace(ba3)\nbytearray(b\"\\x12\\x16\\xfb\\xf6\\x079\\x83\\xd2\\xbdC\\'\\x93\\x9e\\xc3\\xeb\\xc7\")\n\u003e\u003e\u003e cfb.crypt_inplace(ba4)\nbytearray(b'\\x03\\x82')\n\u003e\u003e\u003e cfb.reset_vector()\n\u003e\u003e\u003e\n\u003e\u003e\u003e cfb.crypt_inplace(ba1, False)\nbytearray(b'This is a long m')\n\u003e\u003e\u003e cfb.crypt_inplace(ba2, False)\nbytearray(b'essage that need')\n\u003e\u003e\u003e cfb.crypt_inplace(ba3, False)\nbytearray(b's to be encrypte')\n\u003e\u003e\u003e cfb.crypt_inplace(ba4, False)\nbytearray(b'd.')\n\u003e\u003e\u003e cfb.reset_vector()\n\u003e\u003e\u003e\n\u003e\u003e\u003e ba\nbytearray(b'This is a long message that needs to be encrypted.')\n\u003e\u003e\u003e cfb.crypt_inplace(ba)\nbytearray(b\"_#\\xbf\\x02\\xd6\\x19\\x0c)\\xd9\\x18\\xaf\\xb9\\xa4{JP\\xf6j\\xa3\\xb2\\xb2\\xc6b\\x9f\\xae\\x82\\xa5\\xd4\\xaeen\\xde\\x12\\x16\\xfb\\xf6\\x079\\x83\\xd2\\xbdC\\'\\x93\\x9e\\xc3\\xeb\\xc7\\x03\\x82\")\n\u003e\u003e\u003e len(ba)\n50\n\u003e\u003e\u003e ba.extend(bytearray(14))\n\u003e\u003e\u003e ba\nbytearray(b\"_#\\xbf\\x02\\xd6\\x19\\x0c)\\xd9\\x18\\xaf\\xb9\\xa4{JP\\xf6j\\xa3\\xb2\\xb2\\xc6b\\x9f\\xae\\x82\\xa5\\xd4\\xaeen\\xde\\x12\\x16\\xfb\\xf6\\x079\\x83\\xd2\\xbdC\\'\\x93\\x9e\\xc3\\xeb\\xc7\\x03\\x82\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\")\n\u003e\u003e\u003e cfb.reset_vector()\n\u003e\u003e\u003e\n\u003e\u003e\u003e cfb.crypt_inplace(ba, False)\nbytearray(b'This is a long message that needs to be encrypted.d\\xd5\\x99vk\\x08\\x1c\\x82\\xf0_\\xb8\\x8aw\\x85')\n\u003e\u003e\u003e cfb.reset_vector()\n```\n\n## AES-128 8-bit CFB mode\nThe 8-bit CFB mode is less efficient than the default (128-bit) CFB mode.\nBut its advantage is it can encrypt or decrypt data byte by byte.\nSo it is easy to implement data stream encryption or decryption with it.\n\n``` python\n\u003e\u003e\u003e from cryptocfb import CryptoCFB\n\u003e\u003e\u003e\n\u003e\u003e\u003e key = b'0123456789abcdef'\n\u003e\u003e\u003e iv = bytes(reversed(key))\n\u003e\u003e\u003e cfb1 = CryptoCFB(key, iv, 8)\n\u003e\u003e\u003e cfb2 = CryptoCFB(key, iv, 8)\n\u003e\u003e\u003e\n\u003e\u003e\u003e plain = b'This is a long message that needs to be encrypted.'\n\u003e\u003e\u003e cipher = bytearray()\n\u003e\u003e\u003e decrypted_plain = bytearray()\n\u003e\u003e\u003e\n\u003e\u003e\u003e for i in range(len(plain)):\n...     cb = cfb1.encrypt(plain[i : i + 1])\n...     cipher.extend(cb)\n...     db = cfb2.decrypt(cb)\n...     decrypted_plain.extend(db)\n...\n\u003e\u003e\u003e cipher\nbytearray(b'_\\xf7+\\xf1`4\\x88\\x88\\x88\\xba\\xfb\\x87\\xe0_Lc\\xbf\\xc9AM\\x95\\xf3\\x8dR\\x1b\u003e~\\x91\\x00\\x9a\\x1f\\t\\x99$\\x02\\xfbC\\x810_J\\x89\\x9a\\x81\u003eZ\\xe6\\x9f^H')\n\u003e\u003e\u003e decrypted_plain\nbytearray(b'This is a long message that needs to be encrypted.')\n```\n\nDuring transmission, if any encrypted data byte is corrupted, the result decrypted data will be corrupted as well.\nBy the nature of CFB mode, the communication will recover by it self after several garbage bytes (17 bytes in the case below).\nThis self-recovery behaviour makes it suitable for serial communication where data corruption could happen.\n\n``` python\n\u003e\u003e\u003e from cryptocfb import CryptoCFB\n\u003e\u003e\u003e\n\u003e\u003e\u003e key = b'0123456789abcdef'\n\u003e\u003e\u003e iv = bytes(reversed(key))\n\u003e\u003e\u003e cfb1 = CryptoCFB(key, iv, 8)\n\u003e\u003e\u003e cfb2 = CryptoCFB(key, iv, 8)\n\u003e\u003e\u003e\n\u003e\u003e\u003e plain = b'This is a long message that needs to be encrypted.'\n\u003e\u003e\u003e cipher = bytearray()\n\u003e\u003e\u003e decrypted_plain = bytearray()\n\u003e\u003e\u003e\n\u003e\u003e\u003e for i in range(len(plain)):\n...     cb = cfb1.encrypt(plain[i : i + 1])\n...     if i == 10:\n...         cb[0] ^= 0x01\n...     cipher.extend(cb)\n...     db = cfb2.decrypt(cb)\n...     decrypted_plain.extend(db)\n...\n\u003e\u003e\u003e cipher\nbytearray(b'_\\xf7+\\xf1`4\\x88\\x88\\x88\\xba\\xfa\\x87\\xe0_Lc\\xbf\\xc9AM\\x95\\xf3\\x8dR\\x1b\u003e~\\x91\\x00\\x9a\\x1f\\t\\x99$\\x02\\xfbC\\x810_J\\x89\\x9a\\x81\u003eZ\\xe6\\x9f^H')\n\u003e\u003e\u003e decrypted_plain\nbytearray(b'This is a m\\x12\\xa2;\\xf5\\xdb\\xbd\\x10\\xa0\\xc2\\xbd\\xa2\\xa4\\x05V\\xc2\\xdd needs to be encrypted.')\n```\n","funding_links":["https://www.paypal.me/jacklinquan"],"categories":["Libraries"],"sub_categories":["Communications"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacklinquan%2Fmicropython-cryptocfb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjacklinquan%2Fmicropython-cryptocfb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacklinquan%2Fmicropython-cryptocfb/lists"}