Search code examples
node.jspublic-key-encryptionencryption-asymmetric

Encrypting data with a public key in Node.js


I need to encrypt a string using a public key (.pem file), and then sign it using a private key (also a .pem).

I am loading the .pem files fine:

publicCert = fs.readFileSync(publicCertFile).toString();

But after hours of scouring Google, I can't seem to find a way to encrypt data using the public key. In PHP I simply call openssl_public_encrypt(), but I don't see any corresponding function in Node.js or in any modules.


Solution

  • A library is not necessary. Enter crypto.

    Here's a janky little module you could use to encrypt/decrypt strings with RSA keys:

    var crypto = require("crypto");
    var path = require("path");
    var fs = require("fs");
    
    var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) {
        var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
        var publicKey = fs.readFileSync(absolutePath, "utf8");
        var buffer = Buffer.from(toEncrypt);
        var encrypted = crypto.publicEncrypt(publicKey, buffer);
        return encrypted.toString("base64");
    };
    
    var decryptStringWithRsaPrivateKey = function(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
        var absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey);
        var privateKey = fs.readFileSync(absolutePath, "utf8");
        var buffer = Buffer.from(toDecrypt, "base64");
        var decrypted = crypto.privateDecrypt(privateKey, buffer);
        return decrypted.toString("utf8");
    };
    
    module.exports = {
        encryptStringWithRsaPublicKey: encryptStringWithRsaPublicKey,
        decryptStringWithRsaPrivateKey: decryptStringWithRsaPrivateKey
    }
    

    I would recommend not using synchronous fs methods where possible, and you could use promises to make this better, but for simple use cases this is the approach that I have seen work and would take.