Cipher Read Your Message Into a Large Buffer or a String Object.
This post will explicate the RSA algorithm, and how we tin implement RSA Encryption, Decryption and Signing in Node.js using its standard library.
RSA (Rivest–Shamir–Adleman) encryption is one of the most widely used algorithms for secure data encryption.
It is an asymmetric encryption algorithm, which is merely another way to say "one-way". In this case, it's easy for anyone to encrypt a piece of data, but only possible for someone with the correct "cardinal" to decrypt it.
If you desire to skip the explanation and simply encounter the working source code, you can view it here
RSA Encryption In A Nutshell
RSA works by generating a public and a private key. The public and private keys are generated together and grade a key pair.
The public key tin exist used to encrypt any arbitrary piece of data, but cannot decrypt it.
The private key tin can be used to decrypt whatsoever piece of information that was encrypted past it'south respective public primal.
This means we tin can give our public key to whoever we want. They tin then encrypt any information they want to send u.s.a., and the simply way to access this data is by using our private central to decrypt it.
The details of how the keys are generated, and how information is encrypted and decrypted is beyond the telescopic of this mail service, just if you lot want to delve into the details, at that place is a great video on the topic
Key Generation
The offset thing we want to practise is generate the public and private key pairs. These keys are randomly generated, and will be used for all post-obit operations.
We utilize the crypto standard library for generating the keys:
const crypto = require ( "crypto" ) ; // The `generateKeyPairSync` method accepts two arguments: // 1. The type ok keys we desire, which in this case is "rsa" // 2. An object with the backdrop of the key const { publicKey, privateKey } = crypto. generateKeyPairSync ( "rsa" , { // The standard secure default length for RSA keys is 2048 bits modulusLength: 2048 , } ) ; // use the public and private keys // ...
The publicKey
and privateKey
variables will be used for encryption and decryption respectively.
Encryption
Nosotros volition utilise the publicEncrypt
method for encrypting an capricious message. We must provide a few inputs to this method:
- The public primal that we generated in the previous step
- The padding scheme (we will apply OAEP padding for this)
- The hashing algorithm (nosotros will be using SHA256, which is a recommended secure hashing function as of this date)
- The data nosotros want to encrypt. This is in the from of a buffer since the encrypt method accepts encrypt raw bytes.
// This is the information we want to encrypt const data = "my secret data" ; const encryptedData = crypto. publicEncrypt ( { central: publicKey, padding: crypto.constants. RSA_PKCS1_OAEP_PADDING , oaepHash: "sha256" , } , // We convert the data string to a buffer using `Buffer.from` Buffer. from (information) ) ; // The encrypted data is in the form of bytes, so we impress it in base64 format // so that it'due south displayed in a more readable grade panel. log ( "encypted data: " , encryptedData. toString ( "base64" ) ) ;
This volition print out the encrypted bytes, which expect more than or less like garbage.
Decryption
To access the information contained in the encrypted bytes, they need to be decrypted.
The only mode we tin decrypt them is by using the private primal respective to the public central we encrypted them with.
The crypto library contains the privateDecrypt method which nosotros volition apply to go the original information back from the encrypted data.
The data we have to provide for decryption is:
- The encrypted data (called the nix text)
- The hash that nosotros used to encrypt the information
- The padding scheme that we used to encrypt the data
- The individual key, which we generated previously
const decryptedData = crypto. privateDecrypt ( { central: privateKey, // In order to decrypt the data, we need to specify the // same hashing function and padding scheme that nosotros used to // encrypt the data in the previous pace padding: crypto.constants. RSA_PKCS1_OAEP_PADDING , oaepHash: "sha256" , } , encryptedData ) ; // The decrypted data is of the Buffer type, which we can catechumen to a // string to reveal the original data console. log ( "decrypted data: " , decryptedData. toString ( ) ) ;
Signing And Verification
RSA keys are also used for signing and verification. Signing is dissimilar from encryption, in that it enables you to assert authenticity, rather than confidentiality.
What this means is that instead of masking the contents of the original message (like what was washed in encryption), a slice of data is generated from the message, chosen the "signature".
Anyone who has the signature, the message, and the public key, can utilize RSA verification to brand sure that the message really came from the party by whom the public key is issued. If the information or signature don't friction match, the verification procedure fails.
Notation that only the political party with the private cardinal tin sign a bulletin, but anyone with the public cardinal tin can verify it.
// Create some sample data that we want to sign const verifiableData = "this need to be verified" ; // The signature method takes the data we want to sign, the // hashing algorithm, and the padding scheme, and generates // a signature in the form of bytes const signature = crypto. sign ( "sha256" , Buffer. from (verifiableData) , { fundamental: privateKey, padding: crypto.constants. RSA_PKCS1_PSS_PADDING , } ) ; panel. log (signature. toString ( "base64" ) ) ; // To verify the data, we provide the same hashing algorithm and // padding scheme we provided to generate the signature, along // with the signature itself, the data that we want to // verify against the signature, and the public primal const isVerified = crypto. verify ( "sha256" , Buffer. from (verifiableData) , { central: publicKey, padding: crypto.constants. RSA_PKCS1_PSS_PADDING , } , signature ) ; // isVerified should be `true` if the signature is valid console. log ( "signature verified: " , isVerified) ;
Conclusion
In this post we have seen how to generate RSA public and private keys and how to apply them to encrypt, decrypt, sign and verify arbitrary information.
There are some limitations that y'all should take annotation of:
- The data you are trying to encrypt should be much shorter than the flake forcefulness of your keys. For example, the EncryptOEAP documentation says "The message must be no longer than the length of the public modulus minus twice the hash length, minus a further ii."
- The hashing algorithm used should also exist appropriate for your use example. SHA256 (which is used in the examples hither) is considered sufficient for most use cases, but you may want to consider something like SHA512 for more than information-critical applications.
You can find the complete working source code for all examples here
Source: https://www.sohamkamani.com/nodejs/rsa-encryption/
0 Response to "Cipher Read Your Message Into a Large Buffer or a String Object."
Post a Comment