3

Our system will be calling an API with Authentication server. This server is built in java and requires a lot of key encryption. One requirement is to generate a Signature with client's(it's us) private key using "SHA256 with RSA" algorithm. I have done this in Java but not sure if it's right. Rur server is written in Nodejs. How can I translate below Java code to Node.js?

public static String signSHA256RSA(String input, String strPk) throws Exception {
    Security.addProvider(new BouncyCastleProvider());
       // Remove markers and new line characters in private key
       String realPK = strPk.replaceAll("-----END PRIVATE KEY-----", "")
                            .replaceAll("-----BEGIN PRIVATE KEY-----", "")
                            .replaceAll("\n", "");

       byte[] b1 = Base64.getDecoder().decode(realPK);
       PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
       KeyFactory kf = KeyFactory.getInstance("RSA");

       Signature privateSignature = Signature.getInstance("SHA256withRSA");
       privateSignature.initSign(kf.generatePrivate(spec));
       privateSignature.update(input.getBytes("UTF-8"));
       byte[] s = privateSignature.sign();
       return Base64.getEncoder().encodeToString(s);
}
  • Please post your most recent NodeJS code and describe the problem. – Topaco Dec 06 '20 at 10:16
  • Unfortunately, I haven't written a Nodejs code for this and that's what I am looking. Been googling it but no luck :'(. I'm new to cryptography. The above code accepts privateKey string from a .jks. –  Dec 06 '20 at 10:24

2 Answers2

6

NodeJS has a built in utilities in the crypto package that could help you with that

More on that here https://nodejs.org/api/crypto.html#crypto_class_sign

here's an example from the docs


const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1'
});

const sign = crypto.createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = crypto.createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature, 'hex'));
// Prints: true
Haythem Farhat
  • 737
  • 7
  • 13
2

Here is the complete Flow

Generate Public and Private keys

const crypto = require('crypto');
const fs = require('fs');

const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
        type: 'pkcs1',
        format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs1',
        format: 'pem'
    }
});

// Writing keys to files.
fs.writeFileSync("./private.key", privateKey);
fs.writeFileSync("./public.key", publicKey);

Sign and Verify using Public and Private keys

const crypto = require('crypto');
const fs = require('fs');

// Reading keys from files.
const privateKey = fs.readFileSync('./private.key');
const publicKey = fs.readFileSync('./public.key');


const data = Buffer.from("My Name is MHamzaRajput"); 

const signature = crypto.sign('RSA-SHA256', data, privateKey).toString("base64"); 
console.log("Signing done", signature);


const verify = crypto.verify('RSA-SHA256', data, publicKey, Buffer.from(signature, "base64"));
console.log("verfy done", verify);
M. Hamza Rajput
  • 7,810
  • 2
  • 41
  • 36