Error connecting to Snowflake through Java JDBC with PEM file

1.1k Views Asked by At

I need to connect to Snowflake using Java using Key File in format P8

class JustTheCode {

public static void main(String[] args) throws Exception {
    Security.addProvider(new BouncyCastleProvider());
    String path = "/<path>/app_rsa_key.p8";
    String passphrase = "myKey";//System.getenv("PRIVATE_KEY_PASSPHRASE");
    bcParcer(path,passphrase);
}

private static PrivateKey bcParcer(String keyFilePath, String password)
    throws IOException, OperatorCreationException, PKCSException, Exception {
    PEMParser pemParser = new PEMParser(new FileReader(Paths.get(keyFilePath).toFile()));
    PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemParser.readObject();
    pemParser.close();
    InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(
        password.toCharArray());
    JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(
        BouncyCastleProvider.PROVIDER_NAME);
    PrivateKeyInfo decryptedPrivateKeyInfo = encryptedPrivateKeyInfo.decryptPrivateKeyInfo(
        pkcs8Prov);
    PrivateKey privateKey = converter.getPrivateKey(decryptedPrivateKeyInfo);
    System.out.println(privateKey);
    return privateKey;
}

}

When I run the code, I'm getting the error:

    Exception in thread "main" net.snowflake.client.jdbc.internal.org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.3 not available: requires PBE parameters
    at net.snowflake.client.jdbc.internal.org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source)
    at configmgmt.snowflake.reader.impl.JustTheCode.bcParcer(PrivateKeyReader.java:122)
    at configmgmt.snowflake.reader.impl.JustTheCode.main(PrivateKeyReader.java:102)
Caused by: net.snowflake.client.jdbc.internal.org.bouncycastle.operator.OperatorCreationException: 1.2.840.113549.1.5.3 not available: requires PBE parameters
    at net.snowflake.client.jdbc.internal.org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder$1.get(Unknown Source)
    ... 3 more
Caused by: java.security.InvalidKeyException: requires PBE parameters
    at java.base/com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(PBEWithMD5AndDESCipher.java:186)
    at java.base/javax.crypto.Cipher.implInit(Cipher.java:867)
    at java.base/javax.crypto.Cipher.chooseProvider(Cipher.java:929)
    at java.base/javax.crypto.Cipher.init(Cipher.java:1299)
    at java.base/javax.crypto.Cipher.init(Cipher.java:1236)
    ... 4 more
Caused by: java.security.InvalidAlgorithmParameterException: Parameters missing
    at java.base/com.sun.crypto.provider.PBES1Core.init(PBES1Core.java:214)
    at java.base/com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(PBEWithMD5AndDESCipher.java:220)
    at java.base/com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(PBEWithMD5AndDESCipher.java:184)
    ... 8 more

I am searching but in the documentation there is no information about this configuration: Caused by: java.security.InvalidKeyException: requires PBE parameters

2

There are 2 best solutions below

0
On BEST ANSWER

I found the fix changing the imports:

Previously:

import net.snowflake.client.jdbc.internal.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import net.snowflake.client.jdbc.internal.org.bouncycastle.jce.provider.BouncyCastleProvider;
import net.snowflake.client.jdbc.internal.org.bouncycastle.openssl.PEMParser;
import net.snowflake.client.jdbc.internal.org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import net.snowflake.client.jdbc.internal.org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
import net.snowflake.client.jdbc.internal.org.bouncycastle.operator.InputDecryptorProvider;
import net.snowflake.client.jdbc.internal.org.bouncycastle.operator.OperatorCreationException;
import net.snowflake.client.jdbc.internal.org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import net.snowflake.client.jdbc.internal.org.bouncycastle.pkcs.PKCSException;

new:

import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
import org.bouncycastle.operator.InputDecryptorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
import org.bouncycastle.pkcs.PKCSException;

And the pom:

<dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-ext-jdk15on</artifactId>
        <version>1.70</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.70</version>
    </dependency>
0
On

Besides having correct imports as in the accepted answer, it's also worth checking if the Security provider registered from the Snowflake jdbc driver is not saved in the Java Security Providers, as it contains different parameters and amount of them - for me it was:

  • 2727 parameters for net.snowflake.client.jdbc.internal.org.bouncycastle.jcajce.provider
  • 2944 parameters for org.bouncycastle.jcajce.provider

Checking Bouncy Castle Security Provider:

Security.getProvider("BC"); //or Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);

Removing existing and registering a new Bouncy Castle Provider from the bcprov-ext-jdk15on library:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

Security.removeProvider("BC");
Security.addProvider(new BouncyCastleProvider());