rzcoder/node-rsa

can not decrypt message

cristicmf opened this issue · 4 comments

I use the java can decrypt message. while, the node-sra can not made it . Still have the same question
such as

throw Error('Error during decryption (probably incorrect key). Original error: ' + e);
^
Error: Error during decryption (probably incorrect key). Original error: Error: Incorrect data or key

RudiX commented

already solved this?

Any resolution?

Having a similar issue here, but I'm encrypting w/h Java and decrypting with node-rsa.

Java Code (Simplified):

// PEM needs to be decoded to X509 for it to be accepted by the RSA Engine
byte[] decodedKey = Base64.decode(pemContents, Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);

Security.addProvider(new BouncyCastleProvider());
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
KeyFactory.getInstance("RSA");
rsa.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(keySpec));
return new String(rsa.doFinal(currentBytes), "UTF-8");

Node.JS Code (Simplified):

function decrypt(original) {
    var privateKey = new NodeRSA()
    privateKey.importKey(fs.readFileSync('./config/private.pem'), 'pkcs8-private-pem')
    privateKey.setOptions({encryptionScheme: 'pkcs1'})
    return privateKey.decrypt(Buffer.from(original, 'utf8')
}

Managed to figure it out using the crypto library, here's the code if anyone's interested:

Java Code (with implementation 'org.bouncycastle:bcprov-jdk15on:1.65')

/** Encrypts the message sent to the server through its public RSA key (PKCS1-OAEP). **/
public static String RSAServerEncrypt(Context context, String original, String privateKey) {
	// Returns a UTF-8 String buffer
	try {
		// PEM needs to be decoded to X509 for it to be accepted by the RSA Engine
		byte[] decodedKey = Base64.decode(privateKey, Base64.DEFAULT);
		X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);

		Security.addProvider(new BouncyCastleProvider());
		Cipher rsa = Cipher.getInstance("RSA/NONE/OAEPPadding");
		KeyFactory.getInstance("RSA");
		rsa.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(keySpec));

		// Split into 128 bytes per encoding
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		byte[] originalBytes = original.getBytes(StandardCharsets.UTF_8);
		int index = 0;
		while (index < originalBytes.length) {
			byte[] currentBytes = Arrays.copyOfRange(originalBytes, index, Math.min(index + 128, originalBytes.length));
			byte[] outputBytes = rsa.doFinal(currentBytes);
			outputStream.write(outputBytes);
			index += 128;
		}
		// UTF-8 String does not work but hex string does
		return ConverterFunctions.bytesToHex(outputStream.toByteArray());
	} catch(NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) {
		Log.w(ActivityConstants.LOG_APP_NAME, "Cryptography Error: Unable to encrypt message using server RSA key, stack trace is");
		e.printStackTrace();
		return null;
	}
}

JavaScript Code

const crypto = require('crypto')

var privateKey = 'Insert private PEM key with headers here'
function decrypt(original) {
    // Split buffer into 256 bytes per array and decrypt them as the client uses 256 bytes for each block of encryption
    var requestString = '', buffer = Buffer.from(original, 'hex'), currentBlock = []
    for (var i = 0; i < buffer.length; i++) {
        currentBlock.push(buffer[i])
        if (currentBlock.length === 256) {
            // Buffer length reached, decrypt this block first
            requestString += crypto.privateDecrypt(privateKey, Buffer.from(currentBlock)).toString('utf-8')
            currentBlock = []
        }
    }
    if (currentBlock.length > 0) {
        // Check if is more than zero to avoid wasting time
        requestString += privateKey.decrypt(Buffer.from(currentBlock))
    }
    return requestString
}