You maybe surprised about the long and unhandy title of the article but the RSA encryption has many (different) encryption types so it is important to name them correctly.
The general "problem" with RSA encryption is the limited ability to encrypt large sized plaintext. The size depends on the key size and can get calculated with this general formula
maximum plaintext to encrypt = key size in bytes - padding
Taking our RSA sample key of 2048 bit = 256 byte we get:
maximum plaintext to encrypt = 256 - 42 = 214 byte
This size is good for short strings or - that is the way it should be done for larger sizes - using a hybrid encryption scheme. In short it uses a randomly created AES key of 32 byte, encrypts the data with this key in AES CBC- or (better) GCM- mode and encrypts the key with the RSA public key (and vice versa with the RSA private key for decryption).
Using the RSA encryption there are three padding modes: "no padding", "PKCS1.5 padding" or "OAEP padding". As the first two named are very vulnerable please don't use them, instead use an OAEP padding because it adds a random parameter so the ciphertext will differ each time you encrypt (even with an equal key and plaintext).
The OAEP-padding includes a hashing algorithm that is not always named by the algorithm name so there is a high chance that the Cross platform cryptography will fail. For this example I'm using the "OAEP with SHA-1" as it is available on all platforms (except for CryptoJs where RSA is not available at all).
The encryption is performed with the Public key of the recipient. For the decryption the Private Key of the recipient is used - so in a typical environment the Public Key is provided from the recipient to the encryptor(s) of the data and only the recipient is been able to decrypt the data.
Key generation: All examples use pre-generated keys that are described on the page RSA sample keys. If you want to see how my keys got generated visit the page RSA key generation.
When comparing the other RSA-programs you will have noticed that the keys for C# looking like different as they are not in the "PEM"-format ("---Begin...") but in a XML-format. For this program I had to use .net 5 that includes the option to directly read a PEM encoded private and public key so there is no need to use XML-formatted keys.
One note about the key management in my programs: usually the keys are (securely) stored in files or a key store and may have additional password protection. Both scenarios are unhandy in demonstration programs running in an online compiler. That's why I'm using static, hard-coded keys in my programs - please do not do this in production environment! Never ever store a Private Key in the source! The minimum is to load the keys from a secured device; simply uncomment a line in the code to load the key from a file.
The program follows the usual sequence:
- generate a RSA key pair - here we are using a static, hard-coded key pair in form of a PEM encoded string (Java, PHP, C#, NodeJs, Python, Go)
- convert the data to encrypt into a binary format (e.g. a byte array)
- start the encryption process
- load the Public key
- set the encryption parameters
- encrypt the "data to encrypt" and show the result ("ciphertext") in Base64 encoding
- start the decryption process
- load the Private key
- Base64 decoding of the ciphertext
- set the decryption parameters (same as used for encrypting)
- decrypt the ciphertext to the "decryptedtext" and show the result.
I do not provide a "decryption lony" version as all functions are available in this program.
This is a serious warning regarding the security of the programs shown in these article series. Always keep in mind my disclaimer regarding my programs: All programs are for educational purposes and are not intended to use in production or any other programs where a secure solution is needed. The programs do not have proper exceptional/error handling and in some cases they use insecure key lengths or other methods that are insecure. Never ever use the programs in real life unless checked by a qualified professional cryptographer.
The following links provide the solutions in code and an online compile that runs the code.
Language | available | Online-compiler |
---|---|---|
Java | ✅ | repl.it CpcJavaRsaEncryptionOaepSha256String |
PHP | ✅ | repl.it CpcPhpRsaEncryptionOaepSha256String |
C# (.net 5 needed) | ✅ | dotnetfiddle.net CpcCsharpRsaEncryptionOaepSha256String |
Javascript CryptoJs | ❌ | the encryption functionality is not available in CryptoJs |
NodeJS Crypto | ✅ | repl.it CpcNodeJsCryptoRsaEncryptionOaepSha256String |
NodeJS forge | ✅ | repl.it CpcNodeJsRsaEncryptionOaepSha256String |
Webcrypto encryption only | ✅ | your browser WebcryptoRsaEncryptOaepSha256String.html |
Webcrypto decryption only | ✅ | your browser WebcryptoRsaDecryptOaepSha256String.html |
Python *1) | ✅ | repl.it CpcPythonRsaEncryptionOaepSha256String |
Go | ✅ | repl.it CpcGoRsaEncryptionOaepSha256String |
*1) you need the external library pycryptodome, version 3.9.9
This is an output (your will differ because a random element):
RSA 2048 encryption OAEP SHA-256 string
plaintext: The quick brown fox jumps over the lazy dog
* * * encrypt the plaintext with the RSA public key * * *
ciphertextBase64: Xbuere0B5jmZ3zaxKcRK+WeKwlnrSR2ftJbqhmIaZW2Sx+HMySPpLWYPkjkbhFcEKMQxNYubcsdN+U8tySbkPNytX1O9yFHdxnVK7b0GRIq98H7+fdeU5VIyalndJCliS+MD3RdWU4VZqxDxaGgnDl/NV0Nst9bH1I3eW1UtT8tSxVJwSInIWgky/Bk9UHxkwMidpV9SSss/r8VMNTR6708psxf/FmvNDQd8XxpqjAmRm4bqiPVbiI1tvSfXEReWzWzc7DQvFLFLv/tLfMavzT4BxEI2JWHCBzgtrMABGRMIJjMF64lIkLClpnG0W7dchunqbNbb3vAROajQ+rjdew==
* * * decrypt the ciphertext with the RSA private key * * *
ciphertextReceivedBase64: Xbuere0B5jmZ3zaxKcRK+WeKwlnrSR2ftJbqhmIaZW2Sx+HMySPpLWYPkjkbhFcEKMQxNYubcsdN+U8tySbkPNytX1O9yFHdxnVK7b0GRIq98H7+fdeU5VIyalndJCliS+MD3RdWU4VZqxDxaGgnDl/NV0Nst9bH1I3eW1UtT8tSxVJwSInIWgky/Bk9UHxkwMidpV9SSss/r8VMNTR6708psxf/FmvNDQd8XxpqjAmRm4bqiPVbiI1tvSfXEReWzWzc7DQvFLFLv/tLfMavzT4BxEI2JWHCBzgtrMABGRMIJjMF64lIkLClpnG0W7dchunqbNbb3vAROajQ+rjdew==
decryptedtext: The quick brown fox jumps over the lazy dog
Last update: Apr. 21st 2021
Back to the main page: readme.md