{"id":13991883,"url":"https://github.com/wwwtyro/cryptico","last_synced_at":"2025-09-28T21:30:54.002Z","repository":{"id":4108797,"uuid":"5218476","full_name":"wwwtyro/cryptico","owner":"wwwtyro","description":"An easy-to-use encryption system utilizing RSA and AES for javascript.","archived":true,"fork":false,"pushed_at":"2021-01-18T16:57:56.000Z","size":4664,"stargazers_count":1180,"open_issues_count":34,"forks_count":344,"subscribers_count":72,"default_branch":"master","last_synced_at":"2025-01-13T12:12:11.355Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://wwwtyro.github.com/cryptico","language":"JavaScript","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/wwwtyro.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}},"created_at":"2012-07-28T23:14:29.000Z","updated_at":"2024-12-22T15:06:43.000Z","dependencies_parsed_at":"2022-08-28T14:50:26.416Z","dependency_job_id":null,"html_url":"https://github.com/wwwtyro/cryptico","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/wwwtyro%2Fcryptico","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwtyro%2Fcryptico/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwtyro%2Fcryptico/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwwtyro%2Fcryptico/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wwwtyro","download_url":"https://codeload.github.com/wwwtyro/cryptico/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234563140,"owners_count":18853060,"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-09T14:01:39.206Z","updated_at":"2025-09-28T21:30:53.334Z","avatar_url":"https://github.com/wwwtyro.png","language":"JavaScript","funding_links":[],"categories":["Frameworks and Libs","JavaScript"],"sub_categories":["JavaScript"],"readme":"# cryptico\n\n## Overview\n\n### Generating an RSA key pair \u0026 public key string\n\nSam wants to send Matt an encrypted message.  In order to do this, he first needs Matt's public key string.  A public key pair can be generated for Matt like this:\n\n```javascript\n// The passphrase used to repeatably generate this RSA key.\nvar PassPhrase = \"The Moon is a Harsh Mistress.\"; \n\n// The length of the RSA key, in bits.\nvar Bits = 1024; \n\nvar MattsRSAkey = cryptico.generateRSAKey(PassPhrase, Bits);\n```\n\nMatt's public key string can then be generated like this:\n\n```javascript\nvar MattsPublicKeyString = cryptico.publicKeyString(MattsRSAkey);       \n```\n\nand looks like this:\n        \n    uXjrkGqe5WuS7zsTg6Z9DuS8cXLFz38ue+xrFzxrcQJCXtVccCoUFP2qH/AQ\n    4qMvxxvqkSYBpRm1R5a4/NdQ5ei8sE8gfZEq7dlcR+gOSv3nnS4/CX1n5Z5m\n    8bvFPF0lSZnYQ23xlyjXTaNacmV0IuZbqWd4j9LfdAKq5dvDaoE=\n\n### Encrypting a message\n\nMatt emails Sam his public key string.  Now Sam can encrypt a message for Matt:\n\n```javascript\nvar PlainText = \"Matt, I need you to help me with my Starcraft strategy.\";\n\nvar EncryptionResult = cryptico.encrypt(PlainText, MattsPublicKeyString);\n```\n\n`EncryptionResult.cipher` is the encrypted message, and looks like this:\n\n    OOHoAlfm6Viyl7afkUVRoYQv24AfdLnxaay5GjcqpxvEK+dph5kUFZEZIFKo\n    vVoHoZbtUMekSbMqHQr3wNNpvcNWr4E3DgNLfMZQA1pCAUVmPjNM1ZQmrkKY\n    HPKvkhmVKaBiYAJGoO/YiFfKnaylLpKOYJZctkZc4wflZcEEqqg=?cJPt71I\n    HcU5c2LgqGXQKcx2BaAbm25Q2Ku94c933LX5MObL9qbTJEVEv29U0C3gIqcd\n    qwMV6nl33GtHjyRdHx5fZcon21glUKIbE9P71NwQ=\n\n### Decrypting a message\n    \nSam sends his encrypted message to Matt. The message can be decrypted like this:\n    \n```javascript\nvar CipherText = \"OOHoAlfm6Viyl7afkUVRoYQv24AfdLnxaay5GjcqpxvEK+dph5kUFZEZIFKo \\\n                  vVoHoZbtUMekSbMqHQr3wNNpvcNWr4E3DgNLfMZQA1pCAUVmPjNM1ZQmrkKY \\\n                  HPKvkhmVKaBiYAJGoO/YiFfKnaylLpKOYJZctkZc4wflZcEEqqg=?cJPt71I \\\n                  HcU5c2LgqGXQKcx2BaAbm25Q2Ku94c933LX5MObL9qbTJEVEv29U0C3gIqcd \\\n                  qwMV6nl33GtHjyRdHx5fZcon21glUKIbE9P71NwQ=\";\n\nvar DecryptionResult = cryptico.decrypt(CipherText, MattsRSAkey);\n```\n\nThe decrypted message is in `DecryptionResult.plaintext`.\n\n### Signatures \u0026 Public Key IDs\n    \nIf Sam's RSA key is provided to the `cryptico.encrypt` function, the message will be signed by him:\n    \n```javascript\nvar PassPhrase = \"There Ain't No Such Thing As A Free Lunch.\"; \n\nvar SamsRSAkey = cryptico.generateRSAKey(PassPhrase, 1024);\n\nvar PlainText = \"Matt, I need you to help me with my Starcraft strategy.\";\n\nvar EncryptionResult = cryptico.encrypt(PlainText, MattsPublicKeyString, SamsRSAkey);\n```\n\nThe public key associated with the signature can be used by Matt to make sure that it was sent by Sam, but there are a lot of characters to examine in the key - it would be easy to make a mistake.  Instead, the public key string associated with the signature can be processed like this:\n    \n```javascript\nvar PublicKeyID = cryptico.publicKeyID(EncryptionResult.publickey);\n```\n\nand `PublicKeyID` would look something like this:\n    \n    d0bffb0c422dfa3d3d8502040b915248\n\nThis shorter key ID can be used to uniquely identify Sam's public key more easily if it must be done manually.  Moreover, this key ID can be used by Sam or Matt to make sure they have typed their own passphrases correctly.\n    \n# API Documentation\n\n## RSA Keys\n\n    cryptico.generateRSAKey(passphrase, bitlength)\n\nGenerates an RSAKey object from a password and bitlength.\n\n`passphrase`: string from which the RSA key is generated.\n\n`bitlength`: integer, length of the RSA key (512, 1024, 2048, 4096, 8192).\n\nReturns an `RSAKey` object.\n\n    cryptico.publicKeyString(rsakey)\n\nReturns the public key portion of an RSAKey object in ascii-armored\nstring form, which allows it to be used on websites and in text files\nwithout fear of corrupting the public key.\n\n`rsakey`: An `RSAKey` object.\n\nReturns an ascii-armored public key string.\n    \n    cryptico.publicKeyID(publicKeyString)\n\nReturns an MD5 sum of a `publicKeyString` for easier identification.\n\n`publicKeyString`: a public key in ascii-armored string form, as generated by the `cryptico.publicKeyString` function.\n\nReturns an MD5 sum of the public key string.   \n\n## Encryption\n\n    cryptico.encrypt(plaintext, publicKeyString, signingKey)\n\nEncrypts a string with the provided public key. Optionally signs the encrypted string with an RSAKey object.\n\n`plaintext`: the string to be encrypted.\n    \n`publicKeyString`: The public key string of the recipient.\n    \n`signingKey`: the `RSAKey` object of the sender.\n    \nReturns: `status`, `cipher`\n\n`status`: \"success\" if encryption succeeded, \"failure\" if it failed.\n    \n`cipher`: An ascii-armored encrypted message string, optionally signed.\n\n## Decryption\n\n    cryptico.decrypt(ciphertext, key)\n\nDecrypts an encrypted message with the recipient's RSAKey and verifies the signature, if any.\n\n`ciphertext`: The encrypted message to be decrypted.\n    \n`key`: The `RSAKey` object of the recipient.\n\nReturns: `status`, `plaintext`, `signature`, `publicKeyString`\n\n`status`: \"success\" if decryption succeeded, \"failure\" if it failed. **Does not reflect the status of the signature verification.**\n\n`plaintext`: The decrypted message.\n    \n`signature`: \"unsigned\" if there was no signature, \"verified\" if it is signed and valid, **\"forged\" if the signature fails verification**.\n\n`publicKeyString`: public key string of the signature (presumably the sender). **Returned even if the signature appears to be forged**.\n\n# Encryption Technical Documentation\n\n## Key generation\n\nA hash is generated of the user's passphrase using the SHA256 algorithm found at \u003ca href=\"http://www.webtoolkit.info/javascript-sha256.html\"\u003ewebtoolkit.info\u003c/a\u003e. This hash is used to seed \u003ca href=\"http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html\"\u003eDavid Bau's seedable random number generator\u003c/a\u003e. A (seeded) random RSA key is generated with \u003ca href=\"http://www-cs-students.stanford.edu/~tjw/jsbn/\"\u003eTom Wu's RSA key generator\u003c/a\u003e with 3 as a hard-coded public exponent.\n\n## Encryption\n\nA 32-byte AES key is generated with \u003ca href=\"http://www-cs-students.stanford.edu/~tjw/jsbn/\"\u003eTom Wu's random number generator\u003c/a\u003e. The plaintext message is converted to a byte string and padded with zeros to 16 bytes round.  An initialization vector is created with \u003ca href=\"http://www-cs-students.stanford.edu/~tjw/jsbn/\"\u003eTom Wu's random number generator\u003c/a\u003e. The AES key is expanded and the plaintext message is encrypted with the Cipher-block chaining mode using the \u003ca href=\"http://point-at-infinity.org/jsaes/\"\u003ejsaes\u003c/a\u003e library. The AES key is encrypted with the recipient's public key using \u003ca href=\"http://www-cs-students.stanford.edu/~tjw/jsbn/\"\u003eTom Wu's RSA encryption library\u003c/a\u003e.\n\nThe encrypted AES key and encrypted message are ascii-armored and concatenated with the \"?\" character as a delimiter.  As an example, here is the result of the phrase \"Matt, I need you to help me with my Starcraft strategy.\" encrypted with\nthe passphrase \"The Moon is a Harsh Mistress.\" used to generate the 1024-bit public key:\n\n    EuvU2Ov3gpgM9B1I3VzEgxaAVO/Iy85NARUFZb/h+HrOP72degP0L1fWiHO3\n    RDm5+kWRaV6oZsn91juJ0L+hrP6BDwlIza9x9DBMEsg3PnOHJENG63RXbu0q\n    PZd2xDJY70i44sufNqHZ0mui9OdNIeE8FvzEOzMtFGCqDx1Z48s=?K3lOtQC\n    2w+emoR4W3yvAaslSzTj/ZZIkOu3MNTW8y/OX0OxTKfpsaI6zX6XYrM0MpPr\n    uw7on1N6VUMpNQO8KUVYl4clquaibKs0marXPFH4=\n\n## Signing\n\nWhen signing the encrypted message, two more pieces of information are attached to the cipher text.  The first is the ascii-armored RSA public key of the sender. The second piece of information concatenated with the cipher text is\nthe signature itself, which is generated with the \u003ca href=\"http://www9.atwiki.jp/kurushima/pub/jsrsa/\"\u003ersa-sign extension by Kenji Urushima\u003c/a\u003e, along with the SHA256 algorithm found at \u003ca href=\"http://www.webtoolkit.info/javascript-sha256.html\"\u003ewebtoolkit.info\u003c/a\u003e. These two pieces of code are also used when verifying the signature.\n\nThe signature is concatenated with the public key with the string\n`::52cee64bb3a38f6403386519a39ac91c::` used as the delimiter between the\nplaintext, the public key of the sender, and the signature:\n\n    plaintext\n    ::52cee64bb3a38f6403386519a39ac91c::\n    public key of sender\n    ::52cee64bb3a38f6403386519a39ac91c::\n    signature\n\nThis concatenated block is then encrypted with CBC AES and concatenated with the\nencrypted AES key to form the complete encrypted message.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwwwtyro%2Fcryptico","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwwwtyro%2Fcryptico","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwwwtyro%2Fcryptico/lists"}