Generate Signature using Private Key and "SHA256 with RSA" algorithm in Node.js

12.6k views Asked by At

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);
}
2

There are 2 answers

0
Haythem Farhat On

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
0
M. Hamza Rajput On

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);