10

I have a system that requires a RSA keypair to be generated in javascript, have the public key then stored in a database at the server side (as a string), then the server side which is in Java will encrypt a string with the stored public key and send it to the client side which will decrypt the string with the private key.

I'm using a browsified version of node-rsa on my client browser.

First at the client i generate a keypair and export the keys, storing them as strings

var NodeRSA = require('node-rsa');
var key = new NodeRSA({b: 1024});
key.exportKey("pkcs8-private");
key.exportKey("pkcs8-public-pem");

The exported private key is stored at the client and the public at the server

Next i used java to encrypt a string with the public key received, so i parse the pkcs8 public key into a Java PublicKey object.

String pubKey = "<Retrieved pkcs8 public key>";
pubKey = pubKey.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");
byte[] keyBytes = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(spec);

And encrypt a text with it

byte[] cipherText;
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pk);
cipherText = cipher.doFinal("Hello World!".getBytes());
return Base64.encodeBase64String(cipherText);

Which works nicely and returns me a Base64 encoded encrypted string like this

WTS1J2f4w5icsUOCtulyHDaBmB5lN7D8mnj0QWMDBkUGiPHkM8nHVx9pd0MtbQAQNasQS2X8kisLMYyEMPasFZtDH0zX1e8lNYaW0xMKsg++ge87f+95nl+TmxDy6S1m7Ce/n0wXno+0MbSv8YsJtsUcAleyyfQX2bxqX8u7Gjs=

Then i try to decrypt it the string at the client side

First i reimport the stored keys in node-rsa

var NodeRSA = require('node-rsa');
var key = new NodeRSA();
key.importKey("<exported private key string>","pkcs8-private");
key.importKey("<exported public key string>","pkcs8-public-pem");

Then i try to decrypt the Base64 encoded encrypted string

key.decrypt("<Base64 Encoded Encrypted>", 'utf-8');

This is where the problem happens, javascript throws this error

Uncaught Error: Error during decryption (probably incorrect key). Original error: Error: Error decoding message, the lHash calculated from the label provided and the lHash in the encrypted data do not match.(…) However i have tested that if i encrypt and decrypt the text just within javascript, it works just fine. This makes me think that it's some difference between the way i encrypted it at java and how it's done at javascript

Could anyone point out the mistake that I've made here please?

2 Answers 2

14

Oh i found the solution. It was a difference in the encryption method.

I just had to initialize Cipher with

Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");

instead of

Cipher.getInstance("RSA");

to match node-rsa

Sign up to request clarification or add additional context in comments.

2 Comments

Can you make the same encryption with NodeRsa?
This alone did not work for me, I had do add also Cipher init parameters: cipher.init(Cipher.DECRYPT_MODE, privKey, new OAEPParameterSpec( "SHA-1", "MGF1", MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT ));
0

Instead of change the encryption mode on my backend, I change it on front.

const rsa = new NodeRSA({ b: 2048 });
rsa.setOptions({ encryptionScheme: 'pkcs1' });
rsa.importKey(
    'key',
    'pkcs8-public',
);

and keep using Cipher.getInstance("RSA"); to encrypt and decrypt on backend.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.