Reputation: 11
I'm a beginner at cryptography so bear with me. I want to use RSA encryption with EBC mode included I have searched around and found a library in JavaScript called JsEncrypt that perform RSA encrytion with keys generation but there is nothing on the documentation about the padding the cipher mode that is use. I'm working on React Native project and I request the public key from secure third-party API. All I want to do is to encrypt using the public key already provided with the third party using RSA encryption and cipher mode must be ECB. Any help will be appreciated
Upvotes: 1
Views: 1696
Reputation: 34113
I'm a beginner at cryptography so bear with me.
Sure thing! Everyone has to start somewhere.
I want to use RSA encryption
You almost certainly do not.
Encrypting arbitrary messages directly with your asymmetric primitive is almost never what you want to do in the real world. I'll explain what you want to do below.
with EBC mode
You never want to use ECB mode either.
RSA+ECB is a javax.crypto.Cipher
idiom. Don't follow their examples.
I have searched around and found a library in JavaScript called JsEncrypt that perform RSA encrytion with keys generation but there is nothing on the documentation about the padding the cipher mode that is use.
To sate your curiosity: It uses PKCS #1 padding, version 2.
Most cryptographers don't recommend RSA anymore. Most security experts also advise against its use.
You want libsodium instead.
On the front-end, you want to use crypto_box_seal()
with an ECDH public key. On the back-end, you want to use crypto_box_seal_open()
with your ECDH keypair.
This is easily demonstrated using sodium-plus (a cross-platform, asynchronous JavaScript implementation of libsodium).
const { SodiumPlus, X25519PublicKey } = require('sodium-plus');
let sodium;
const publicKey = X25519Publickey.from(
'fb1a219011c1e0d17699900ef22723e8a2b6e3b52ddbc268d763df4b0c002e73',
'hex'
);
(async function () {
if (!sodium) sodium = await SodiumPlus.auto();
const message = 'Your message here.';
let sendMe = await sodium.crypto_box_seal(message, publicKey);
console.log(sendMe);
})();
You can then transmit your encrypted data (stored in sendMe
) and have it decrypted elsewhere.
You can then find a congruent libsodium implementation for your back-end language.
If you're using Node.js server-side, you can use a very similar API for decryption.
const { SodiumPlus, X25519PublicKey, X25519SecretKey } = require('sodium-plus');
let sodium;
const secretKey = X25519SecretKey.from(
'0202040a9fbf98e1e712b0be8f4e46e73e4f72e25edb72e0cdec026b370f4787',
'hex'
);
const publicKey = X25519Publickey.from(
'fb1a219011c1e0d17699900ef22723e8a2b6e3b52ddbc268d763df4b0c002e73',
'hex'
);
(async function () {
if (!sodium) sodium = await SodiumPlus.auto();
const encrypted = ''; // Get from client-side
let decrypted = await sodium.crypto_box_seal_open(encrypted, publicKey, secretKey);
console.log(decrypted);
})();
The beauty of libsodium is that you don't have to even care what's going on under the hood in order to use it correctly. That's the entire point of libsodium.
But for the curious: This is a sealing API which combines an Elliptic Curve Diffie-Hellman key agreement protocol (where one keypair is only used once) with authenticated symmetric-key encryption.
Your message is actually encrypted with XSalsa20-Poly1305. The encryption key is calculated from ECDH of the one-time (sk, pk)
keypair generated client-side with the server's public key. (A nonce is calculated from the BLAKE2b hash of the two public keys.) The ephemeral (one-time) public key is prepended to the ciphertext.
On the server-side, it strips the public key from the sealed message, performs a congruent ECDH calculation (to arrive at the same symmetric key you generated client-side). Then it performs the XSalsa20-Poly1305 decryption with this shared key.
If anything goes wrong server-side, it will throw a SodiumError
. This means that chosen-ciphertext attacks will fail. (Can you guarantee the same with RSA-ECB?)
But all you need to know is:
encrypted = crypto_box_seal(message, pk)
decrypted = crypto_box_seal_open(encrypted, pk, sk)
There are similar APIs in sodium-plus (and other libsodium APIs) that solve different cryptography problems.
Getting familiar with a hard-to-misuse library like libsodium is a great use of one's time as a beginner. After that, there's CryptoPals for self-education.
Upvotes: 2