import java.util.Properties;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.util.Base64;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.KeyFactory;
import java.security.PrivateKey;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
public class TestJdbc
{
public static void main(String[] args)
throws Exception
{
File f = new File("<path>/rsa_key.p8");
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int) f.length()];
dis.readFully(keyBytes);
dis.close();
String encrypted = new String(keyBytes);
String passphrase = System.getenv("PRIVATE_KEY_PASSPHRASE");
encrypted = encrypted.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "");
encrypted = encrypted.replace("-----END ENCRYPTED PRIVATE KEY-----", "");
EncryptedPrivateKeyInfo pkInfo = new EncryptedPrivateKeyInfo(Base64.getMimeDecoder().decode(encrypted));
PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
SecretKeyFactory pbeKeyFactory = SecretKeyFactory.getInstance(pkInfo.getAlgName());
PKCS8EncodedKeySpec encodedKeySpec = pkInfo.getKeySpec(pbeKeyFactory.generateSecret(keySpec));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey encryptedPrivateKey = keyFactory.generatePrivate(encodedKeySpec);
Class.forName("net.snowflake.client.jdbc.SnowflakeDriver");
String url = "jdbc:snowflake://<account>.snowflakecomputing.com";
Properties prop = new Properties();
prop.put("user", "<user>");
prop.put("account", "<account>");
prop.put("privateKey", encryptedPrivateKey);
Connection conn = DriverManager.getConnection(url, prop);
Statement stat = conn.createStatement();
ResultSet res = stat.executeQuery("select 1");
res.next();
System.out.println(res.getString(1));
conn.close();
}
}
You can use "node-rsa" Package for RSA encryption technique.
Check this github linke for sample
Also you can do this using node.js Crypto package
//Generate Keys
const { writeFileSync } = require('fs')
const { generateKeyPairSync } = require('crypto')
function generateKeys() {
const { privateKey, publicKey } = generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
type: 'pkcs1',
format: 'pem',
},
privateKeyEncoding: {
type: 'pkcs1',
format: 'pem',
cipher: 'aes-256-cbc',
passphrase: '',
},
})
writeFileSync('private.pem', privateKey)
writeFileSync('public.pem', publicKey)
}
//encryption and decryption process
const crypto = require('crypto')
const path = require('path')
const fs = require('fs')
function encrypt(toEncrypt, relativeOrAbsolutePathToPublicKey) {
const absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey)
const publicKey = fs.readFileSync(absolutePath, 'utf8')
const buffer = Buffer.from(toEncrypt, 'utf8')
const encrypted = crypto.publicEncrypt(publicKey, buffer)
return encrypted.toString('base64')
}
function decrypt(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
const absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey)
const privateKey = fs.readFileSync(absolutePath, 'utf8')
const buffer = Buffer.from(toDecrypt, 'base64')
const decrypted = crypto.privateDecrypt(
{
key: privateKey.toString(),
passphrase: '',
},
buffer,
)
return decrypted.toString('utf8')
}
const enc = encrypt('hello', `public.pem`)
console.log('enc', enc)
const dec = decrypt(enc, `private.pem`)
console.log('dec', dec)
I solved it by writing a java class and imported into nodejs using node-java package.
Java package
package com.nearinfinity.nodeJava; import java.io.*; import java.util.Base64; import java.security.spec.PKCS8EncodedKeySpec; import java.security.*; import javax.crypto.EncryptedPrivateKeyInfo; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; public class EncryptedPrivateKeyDecode { public PrivateKey getPrivatekey(String [] args) { try { if (args.length == 0) { throw new NullPointerException("the encoded parameter " + "must be non-null"); } // Please change the path to your pem file File f = new File(args[0]); FileInputStream fis = new FileInputStream(f); DataInputStream dis = new DataInputStream(fis); byte[] keyBytes = new byte[(int) f.length()]; dis.readFully(keyBytes); dis.close(); String encrypted = new String(keyBytes); String passphrase = new String(args[1]); encrypted = encrypted.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", ""); encrypted = encrypted.replace("-----END ENCRYPTED PRIVATE KEY-----", ""); EncryptedPrivateKeyInfo pkInfo = new EncryptedPrivateKeyInfo(Base64.getMimeDecoder().decode(encrypted)); PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray()); SecretKeyFactory pbeKeyFactory = SecretKeyFactory.getInstance(pkInfo.getAlgName()); PKCS8EncodedKeySpec encodedKeySpec = pkInfo.getKeySpec(pbeKeyFactory.generateSecret(keySpec)); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey encryptedPrivateKey = keyFactory.generatePrivate(encodedKeySpec); return encryptedPrivateKey; } catch (Exception e) { e.printStackTrace(); } return null; } }Node code
const java = jinst.getInstance(); const EncryptedPrivateKeyDecode = java.import( 'com.nearinfinity.nodeJava.EncryptedPrivateKeyDecode' ); const privateKey = new EncryptedPrivateKeyDecode().getPrivatekeySync([ privateKeyPath, privateKeyPassphrase ]);and now we can use this privateKey in node-jdbc package