{"id":13620394,"url":"https://github.com/Mowje/node-cryptopp","last_synced_at":"2025-04-14T19:32:01.145Z","repository":{"id":10839467,"uuid":"13119111","full_name":"Mowje/node-cryptopp","owner":"Mowje","description":"Node.js static bindings to the Crypto++ library (NOT CURRENTLY MAINTAINED! USE AT YOUR OWN RISK!)","archived":false,"fork":false,"pushed_at":"2016-02-10T11:44:44.000Z","size":117,"stargazers_count":10,"open_issues_count":4,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-08T06:41:39.484Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","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/Mowje.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":"2013-09-26T10:15:57.000Z","updated_at":"2020-10-22T07:53:35.000Z","dependencies_parsed_at":"2022-08-29T11:22:18.804Z","dependency_job_id":null,"html_url":"https://github.com/Mowje/node-cryptopp","commit_stats":null,"previous_names":["batikhsouri/node-cryptopp"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mowje%2Fnode-cryptopp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mowje%2Fnode-cryptopp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mowje%2Fnode-cryptopp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Mowje%2Fnode-cryptopp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Mowje","download_url":"https://codeload.github.com/Mowje/node-cryptopp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248945985,"owners_count":21187422,"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-01T21:00:55.309Z","updated_at":"2025-04-14T19:31:59.014Z","avatar_url":"https://github.com/Mowje.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# node-cryptopp\n\n__This module is not currently maintained. It was known to have [faults](https://gist.github.com/BatikhSouri/b4b76d2f4d0cd5e532f0). It hasn't been tested with test vectors. USE AT YOUR OWN RISK!__\n\nNode.js module that statically binds and simplifies the usage of the [Crypto++](http://cryptopp.com) comprehensive cryptography library. (Written for Node.js v0.10.x)\n\nBindings for:\n* [RSA](https://en.wikipedia.org/wiki/RSA_%28algorithm%29)\n* [DSA](https://en.wikipedia.org/wiki/Digital_Signature_Algorithm)\n* [ECIES](https://en.wikipedia.org/wiki/ECIES)\n* [ECDH](https://en.wikipedia.org/wiki/ECDH)\n* [ECDSA](https://en.wikipedia.org/wiki/ECDSA)\n* Base64 and hexadecimal encoding\n\nAll the crypto methods could be used in sync/async mode\n\n## Requirements\n* [node.js](http://nodejs.org), obviously..\n* [node-gyp](https://github.com/TooTallNate/node-gyp)\n* ~~[Crypto++](http://cryptopp.com), that could be installed on Linux [rather easily](http://cryptopp.com/wiki/Linux#Distribution_Package)~~ (Not a requirement anymore. v0.2.1 is all about having Crypto++ as a submodule)\n\n## Installation\n\nOn installation, the node-cryptopp module compiles on your computer. Hence Crypto++ needs to be installed.\n\nTo install the latest version of this module, run :\n\n```shell\nnpm install git+https://github.com/Mowje/node-cryptopp.git\n```\n\nOr, alternatively :\n\n```shell\nnpm install git+ssh://git@github.com:Mowje/node-cryptopp.git\n```\n\nIf you want to use a specific version of this module (let's say v0.2.4), you should add a \"#\" character and the version number at the end of the URL given. (In our example, that makes : `npm install git+https://github.com/Mowje/node-cryptopp.git#v0.2.4`)\n\n*NOTE*: This module used to be installable from npmjs.org. I struggled to make it work with 0.2.1. So I'm giving up on npm for now and gave you this alternate way to install cryptopp.\n\n## CAUTION : Do not use node-cryptopp v0.2.3 and prior to check signatures!!!\n[Click here to see why](https://gist.github.com/BatikhSouri/b4b76d2f4d0cd5e532f0)\n\n## Use the `KeyRing` !\n\nThis feature was introduced in version 0.2.0. A friend of mine told me that \"key management\" in 0.1.x versions of node-cryptopp was totally unsafe because of javascript's memory management : you have cannot control when a keypair is ereased from memory, even though you removed all references to it. Because Node.js is a relatively new technology and it is highly probable that there are unknown exploits in it (like in any piece of software), it would be then unsafe to have private keys loaded in js code.\n\nHence, I created the `KeyRing` class, that manages keypair generation, saving, loading and clearing in addition to the cryptographic operations where the private key is needed. Also, there is no method in this class that will allow you to extract the private key.\n\nAs of now, I kept the unsafe methods from the previous versions of the module, but I **highly** recommend using the key ring.\n\nNote that I wanted to allow key encryption (ie, when saving then on disk). But it doesn't work as of now. Hence, don't use the `passphrase` parameter (or skip it with `undefined` like you'd skip any other parameter in cryptopp, as explained below).\n\n## General notes\n\n* By default, each method described could be given a callback. If no callback is given, the method's result is returned.\n* If you want to skip an optional parameter but want to define the parameter that follows it, then the skipped parameter **MUST** be set to `undefined`. Sorry if this seems to totally inconvenient\n* This library isn't well written in terms of error management (except the KeyRing class). If the app crashes or throws some strange exception, it is probably because you did something wrong (Thanks Captain Obvious) but in general it won't tell you what it is. Note that if you use a method with a callback, the errors will be thrown exactly like when you use the method without a callback (meaning: not through the callback)\n* The different ECC algorithms for which are (or will be) implemented here use standard elliptic curves, defined [here](http://www.secg.org/collateral/sec2_final.pdf). The related methods will have a \"curveName\" parameter, taken from the previously linked document, like \"secp256r1\" or \"sect233k1\". Beware, it is case-sensitive. Each party must use the same curve.\n* ECIES keypairs can be used in ECDSA and vice-versa! (as long as you use the same curve in both algorithms) [paper that proves it; look for section 4](http://eprint.iacr.org/2011/615)\n* You should not use ECDH or ECDSA on binary fields! There is a bug in the related methods that is not yet fixed. (probably in hexStr\u003c-\u003ePolynomialMod2 versions, if you are more courageous than me and want to dig in)\n* You can choose what hash function want to use in ECDSA and RSA signatures. You can choose either SHA1 (default) or SHA256. Just set the `hashName` parameter to 'sha1' or 'sha256' in the corresponding methods. Note that the default hash function for these algorithms in version prior to v0.2.0 was SHA256.\n* Keys, ciphertexts and signatures are all hex encoded. These data types should be kept \"as-is\" when passed to other methods.\n* Crypto++ doesn't do well with fuzzed values (like ciphertexts, keys or signatures). Hence, unless you do value sanitizing of some sort, it seems like a bad idea to use this module in a server to check/validate/decrypt user-provided data (for example).\n\n## Usage\n\nThe test.js script gives example usages for most implemented algorithms. So you can learn from there, in addition to learning from this page.\n\n### KeyRing\n\nBefore using the `KeyRing`, you must construct it. This is how it's done :\n\n```js\nvar cryptopp = require('cryptopp');\nvar keyRing = new cryptopp.KeyRing();\n```\n\nHere are the list of methods exposed by the `KeyRing`:\n\n* `createKeyPair(algoType, algoOptions, [filename], [passphrase], [callback])`:  \nGenerates a keypair the given algorithm. Returns the public key information object (as in the `publicKeyInfo()` method)\n\t* algoType : the name of the algorithm for which you want to create a keyPair. Possible values are \"rsa\", \"dsa\", \"ecies\", \"ecdsa\", \"ecdh\"\n\t* algoOptions : the keysize when algoType is \"rsa\" or \"dsa\", the curve name otherwise\n\t* filename : the path to the file where you want the keypair to saved. Optional parameter\n\t* passphrase : a passphrase used to encrypt the keypair (when you choose to save it). Optional parameter\n\t* callback : a callback function, that will recieve the public key information object as argument. Optional parameter\n* `decrypt(cipherText, [encoding], [callback])`  \nDecrypts the cipherText (optionally encoded)\n\t* cipherText : the ciphertext to decrypt\n\t* encoding : optional, the encoding of the ciphertext. Possible values are : 'hex', 'base64'. Defaults to 'hex'\n\t* callback : optional, receives the plaintext as a parameter\n* `sign(message, [signatureEncoding], [hashName], [callback])`  \nSigns the message with the loaded key ring.\n\t* message : the message to be signed\n\t* signatureEncoding : optional, determines the encoding that should be used for the signature. Possible values : 'hex', 'base64'. Defaults to 'hex'.\n\t* hashName : optional, name of the hash function to be used in the signing process. Possible values are 'sha1', 'sha256'. Defaults to 'sha1'.\n\t* callback : optional. Recieves the signature as a parameter if used\n* `agree(pubKey, [callback])`  \nAgrees on a shared secret and returns it (hex encoded)\n\t* pubKey : object containing the keyType, curveName and publicKey attributes for an ECDH key agreement\n\t* callback : receives the shared secret\n* `publicKeyInfo([callback])`\nReturns an object containing public key information from the currently loaded key pair. You can give a callback. The returned object has the following attributes :\n\t* keyType : a string that contains the algo type. Possible values : \"rsa\", \"dsa\", \"ecdsa\", \"ecies\", \"ecdh\"\n\t* if (keyType == \"rsa\") :\n\t\t* modulus : the RSA modulus\n\t\t* publicExponent : the RSA public exponent\n\t* if (keyType == \"dsa\") :\n\t\t* primeField : the DSA prime field\n\t\t* divider : the DSA divider\n\t\t* base : the DSA base\n\t\t* publicElement : the DSA public key\n\t* if (keyType == \"ecdsa\" || keyType == \"ecies\")\n\t\t* curveName : the standard name of the cruve used\n\t\t* publicKey.x : x coordinate of the public point\n\t\t* publicKey.y : y coordinate of the public point\n\t* if (keyType == \"ecdh\")\n\t\t* curveName : the standard name of the curve used\n\t\t* publicKey : the ECDH public key\n* `save(filename, [passphrase], [callback])`  \nSave the keypair to the given filename. DON'T USE THE PASSPHRASE! No paramter passed to the callback\n* `load(filename, [legacy], [passphrase], [callback])`  \nLoad the keypair from the given path. Legacy is a boolean, determining whether the file is in the old key file format (prior to v0.2.2) DON'T USE THE PASSPHRASE! The callback receives the public key information object\n* `clear()`  \nDeletes the keypair from memory. You **MUST** call this method once you're done working the keyring.\n\n### RSA\n\nRSA encryption and signature schemes are supported by this module. For signatures : the default hashing function used here is SHA1, but you can specify the `hashName` parameter either to \"sha1\" or \"sha256\" (other values will throw an exception)\n\nThere are 5 methods for RSA :\n\n* __rsa.generateKeyPair(keySize, [callback(keyPair)])__ : Generates a RSA keypair with the given key size (in bits). The keysize must be 1024 \u003c= Math.power(2, k) \u003c= 16384 (where k is an integer). The result of the method is an object with 3 attributes : modulus, publicExponent and privateExponent\n* __rsa.encrypt(plainText, modulus, publicExponent, [callback(cipherText)])__ : Returns the ciphertext\n* __rsa.decrypt(cipherText, modulus, privateExponent, publicExponent, [callback(plainText)])__ : Returns the plain text message\n* __rsa.sign(message, modulus, privateExponent, publicExponent, [hashName], [callback(signature)])__ : Signs the message with the given private key\n* __rsa.verify(message, signature, modulus, publicExponent, [hashName], [callback(isValid)])__ : Tells whether the signature for the given message and public key is valid or not\n\n#### Example usage\n```javascript\nvar cryptopp = require('cryptopp');\nvar rsaKeyPair = cryptopp.rsa.generateKeyPair(2048);\nvar cipher = cryptopp.rsa.encrypt('Testing RSA', rsaKeyPair.modulus, rsaKeyPair.publicExponent);\nvar plaintext = cryptopp.rsa.decrypt(cipher, rsaKeyPair.modulus, rsaKeyPair.privateExponent);\n```\n\n### DSA\n\nThere are 3 methods for DSA. Note that the hashing function used here is SHA1.\n\n* __dsa.generateKeyPair(keySize, [callback(keyPair)])__ : Generates a DSA keypair with the given key size (in bits). The result is an object with 5 attributes : primeField, divider, base, privateExponent, publicElement\n* __dsa.sign(message, primeField, divider, base, privateExponent, [callback(signature)])__ : Signs the given message using DSA with SHA1\n* __dsa.verify(message, signature, primeField, divider, base, publicElement, [callback(isValid)])__ : Verifies the signature\n\n#### Example usage\n```javascript\nvar cryptopp = require('cryptopp');\nvar dsaKeyPair = cryptopp.dsa.generateKeyPair(2048);\nvar message = 'Testing DSA';\nvar signature = cryptopp.dsa.sign(message, dsaKeyPair.primeField, dsaKeyPair.divider, dsaKeyPair.base, dsaKeyPair.privateExponent);\nvar isValid = cryptopp.dsa.verify(message, signature, dsaKeyPair.primeField, dsaKeyPair.divider, dsaKeyPair.base, dsaKeyPair.publicElement);\n```\n\n### ECIES\n\nBindings have been written for ECIES on prime and binary fields.\n\nThe methods are reachable as following cryptopp.ecies.[fieldType].[methodname]\n\nFor each of these fields, there are 3 methods available :\n\n* __ecies.[fieldType].generateKeyPair(curveName, [callback(keyPair)])__ : Returns an object containing the private key, the public key, and curve name. The private and public keys are hex encoded and should be passed in that format to other methods.\n* __ecies.[fieldType].encrypt(plainText, publicKey, curveName, [callback(cipherText)])__ : encrypts the plainText with the given publicKey on the given curve.\n* __ecies.[fieldType].decrypt(cipherText, privateKey, curveName, [callback(plainText)])__ : decrypts the cipherText with the given privateKey on the given curve.\n\n#### Example usage\n```javascript\nvar cryptopp = require('cryptopp');\nvar keyPair = cryptopp.ecies.prime.generateKeyPair(\"secp256r1\");\nvar cipher = cryptopp.ecies.prime.encrypt(\"Testing ECIES\", keyPair.publicKey, keyPair.curveName);\nvar plainText = cryptopp.ecies.prime.decrypt(cipher, keyPair.privateKey, keyPair.curveName);\n```\n\nTo use ECIES on binary fields, just replace in the code above \"prime\" by \"binary\" and the curve name by a \"binary curve\" one.\n\n### ECDSA\n\nBindings have been written for ECDSA for prime and prime fields. However, as mentioned before in the \"General notes\" there is a bug somewhere in the binary field version in the signing method.\n\nYou can choose which hashing function you want to use by setting the `hashName` parameter either to \"sha1\" or \"sha256\" (other values will throw an exception). The ECDSA methods are reachable in a manner similar to ECIES. Here are ECDSA's methods :\n\n* __ecdsa.[fieldType].generateKeyPair(curveName, [callback(keyPair)])__ : Returns an object containing the private key, the public key and the curve name.\n* __ecdsa.[fieldType].sign(message, privateKey, curveName, [hashName], [callback(signature)])__ : Returns the signature for the given message\n* __ecdsa.[fieldType].verify(message, signature, publicKey, curveName, [hashName], [callback(isValid)])__ : A boolean is returned by this method; true when the signature is valid, false when it isn't.\n\n#### Example usage\n```javascript\nvar cryptopp = require('cryptopp');\nvar keyPair = cryptopp.ecdsa.prime.generateKeyPair(\"secp256r1\");\nvar message = \"Testing ECDSA\";\nvar signature = cryptopp.ecdsa.prime.sign(message, keyPair.privateKey, keyPair.curveName);\nvar isValid = cryptopp.ecdsa.prime.verify(message, signature, keyPair.publicKey, keyPair.curveName);\n```\n\n### ECDH\n\nBinding have been written for ECDH for both type of fields. However, the binary version don't always give the same secret in the \"agree\" method.\n\nThere are only 2 methods per field :\n\n* __ecdh.[fieldType].generateKeyPair(curveName, [callback(keyPair)])__ : The result is an object with 3 attributes : curveName, privateKey, publicKey\n* __ecdh.[fieldType].agree(yourPrivateKey, yourCounterpartsPublicKey, curveName, [callback(secret)])__ : Returns the common secret.\n\n#### Example usage\n```javascript\nvar cryptopp = require('cryptopp');\nvar ecdhKeyPair1 = cryptopp.ecdh.prime.generateKeyPair('secp256r1');\nvar ecdhKeyPair2 = cryptopp.ecdh.prime.generateKeyPair('secp256r1');\nvar secret1 = cryptopp.ecdh.prime.agree(ecdhKeyPair1.privateKey, ecdhKeyPair2.publicKey, ecdhKeyPair1.curveName);\nvar secret2 = cryptopp.ecdh.prime.agree(ecdhKeyPair2.privateKey, ecdhKeyPair1.publicKey, ecdhKeyPair2.curveName);\n```\n\n### Random bytes generation\n\nI found it useful to have a method that gives you random bytes, using the a generator from Crypto++ rather than ```Math.random()``` or whatever\n\n__cryptopp.randomBytes(length, [encoding])__ :  \n* length : number of bytes to be generated\n* encoding : optional, possible values are 'hex' for hexadecimal and 'base64' for Base64 encoding. Defaults to 'hex'.\n\n### Hex and Base64 encodings\n\nAlthough there are already ways to encode/decode to hex/base64 in Node.js, I wrote bindings to the implementations in Crypto++\n\n* __hex.encode(text)__ : Encode the text to hexadecimal\n* __hex.decode(encoded)__ : Decode the hex encoded text\n\n* __base64.encode(text)__ : Encode the text to Base64\n* __base64.decode(encoded)__ : Decode the Base64 encoded text\n\n## Keypair file format\n\nHere is how a keypair file is built. Note that every number is in written in big endian. Note that the format has changed slightly as of v0.2.2 to homogenize it [node-sodium](https://github.com/Mowje/node-sodium.git)'s format and to ease the integration of both modules into [node-hpka](https://github.com/Mowje/node-hpka.git). For reference, here is the [old key file format](https://github.com/Mowje/node-cryptopp/tree/master/OldKeyFileFormat.md).\n\n* algoType : a byte; 0x00 for ECDSA, 0x01 for RSA, 0x02 for DSA, 0x03 for ECDH, 0x04 for ECIES\n* if keyType is ECDSA or ECIES\n\t* curveID : a byte, corresponding to the curve used\n\t* publicKeyX.length : length of the x coordinate of the public point (2 bytes, unsigned integer)\n\t* publicKeyX : x coordinate of the public point\n\t* publicKeyY.length : length of the y coordinate of the public point (2 bytes, unsigned integer)\n\t* publicKeyY : y coordinate of the public point\n\t* privateKey.length : length of the private key (2 bytes, unsigned integer)\n\t* privateKey\n* if keyType is RSA\n\t* modulus.length : length of the RSA modulus (2 bytes, unsigned integer)\n\t* modulus : RSA modulus\n\t* publicExponent.length : length of the public exponent (2 bytes, unsigned integer)\n\t* publicExponent : RSA public exponent (or public key)\n\t* privateExponent.length : length of the private exponent (2 bytes, unsigned integer)\n\t* privateExponent : RSA private exponent (or private key)\n* if keyType is DSA\n\t* primeField.length : length of the prime field used by the DSA key pair (2 bytes, unsigned integer)\n\t* primeField\n\t* divider.length : length of the divider (2 bytes, unsigned integer)\n\t* divider\n\t* base.length : length of the base (2 bytes, unsigned integer)\n\t* base : DSA base\n\t* publicElement.length : length of the DSA public key (2 bytes, unsigned integer)\n\t* publicElement : DSA public key\n\t* privateExponent.length : length of the DSA private exponent (2 bytes, unsigned integer)\n\t* privateExponent : DSA private exponent (ie, the private key)\n* if keyType is ECDH\n\t* curveID : a byte, corresponding to the curve used\n\t* publicKey.length : length of the ECDH public key (2 bytes, unsigned integer)\n\t* publicKey : ECDH public key\n\t* privateKey.length : length of the ECDH private key (2 bytes, unsigned integer)\n\t* privateKey : ECDH private key\n\n#### CruveName \u003c-\u003e CurveID\n\n CurveID | Curve name\n-------- | -----------\n 0x01    | secp112r1\n 0x02    | secp112r2\n 0x03    | secp128r1\n 0x04    | secp128r2\n 0x05    | secp160r1\n 0x06    | secp160r2\n 0x07    | secp160k1\n 0x08    | secp192r1\n 0x09    | secp192k1\n 0x0A    | secp224r1\n 0x0B    | secp224k1\n 0x0C    | secp256r1\n 0x0D    | secp256k1\n 0x0E    | secp384r1\n 0x0F    | secp521r1\n 0x80    | sect113r1\n 0x81    | sect113r2\n 0x82    | sect131r1\n 0x83    | sect131r2\n 0x84    | sect163r1\n 0x85    | sect163r2\n 0x86    | sect163k1\n 0x87    | sect193r1\n 0x88    | sect193r2\n 0x89    | sect233r1\n 0x8A    | sect233k1\n 0x8B    | sect239r1\n 0x8C    | sect283r1\n 0x8D    | sect283k1\n 0x8E    | sect409r1\n 0x8F    | sect409k1\n 0x90    | sect571r1\n 0x91    | sect571k1\n\n## License\n\nThis module is licensed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMowje%2Fnode-cryptopp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMowje%2Fnode-cryptopp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMowje%2Fnode-cryptopp/lists"}