snowflake-jdbc icon indicating copy to clipboard operation
snowflake-jdbc copied to clipboard

SNOW-1272895: Key Pair Authentication with Encrypted Key Not Working

Open KevinMellott91 opened this issue 11 months ago • 4 comments

  1. What version of JDBC driver are you using? 3.15.0

  2. What operating system and processor architecture are you using? Macbook M1 Max, Sonoma 14.4.1

  3. What version of Java are you using? openjdk version "1.8.0_402" OpenJDK Runtime Environment (Temurin)(build 1.8.0_402-b06) OpenJDK 64-Bit Server VM (Temurin)(build 25.402-b06, mixed mode)

  4. What did you do?

I'm unable to create a connection using the JDBC driver when using Key Pair authentication with an encrypted key. This works fine when using an unencrypted key, but that is not sufficient for our security needs.

To generate the key, I used the default instructions found at https://docs.snowflake.com/en/user-guide/key-pair-auth and am using openssl v3.1.1. I am also running the basic test program provided at https://docs.snowflake.com/en/developer-guide/jdbc/jdbc-using#java-sample-program.

openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 des3 -inform PEM -out rsa_key.p8
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub

I was able to connect to the Snowflake account using these credentials with SnowSQL. The script for that is below for reference.

export SNOWSQL_PRIVATE_KEY_PASSPHRASE="password"
snowsql -a "xxxxxxx" -u test_user -d core_test_db -r core_test_role -w core_test_wh --private-key-path "/Users/xxxxxx/testing/rsa_key.p8" -q "select CURRENT_CLIENT();"

However, when I attempt to do so with the JDBC driver in a test program, I receive the error below.

Exception in thread "main" net.snowflake.client.jdbc.SnowflakeSQLLoggedException: Private key provided is invalid or not supported: /Users/xxxxxxx/testing/rsa_key.p8: PBE parameter parsing error: expecting the object identifier for AES cipher
        at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initialize(DefaultSFConnectionHandler.java:130)
        at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initializeConnection(DefaultSFConnectionHandler.java:98)
        at net.snowflake.client.jdbc.SnowflakeConnectionV1.initConnectionWithImpl(SnowflakeConnectionV1.java:140)
        at net.snowflake.client.jdbc.SnowflakeConnectionV1.<init>(SnowflakeConnectionV1.java:120)
        at net.snowflake.client.jdbc.SnowflakeDriver.connect(SnowflakeDriver.java:211)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)
        at SnowflakeJDBCExample.getConnection(SnowflakeJDBCExample.java:91)
        at SnowflakeJDBCExample.main(SnowflakeJDBCExample.java:31)
  1. What did you expect to see?

I expected the JDBC driver to connect without issue.

  1. Can you set logging to DEBUG and collect the logs?

Here are the full logs...

Create JDBC connection
Exception in thread "main" net.snowflake.client.jdbc.SnowflakeSQLLoggedException: Private key provided is invalid or not supported: /Users/xxxxxx/testing/rsa_key.p8: PBE parameter parsing error: expecting the object identifier for AES cipher
        at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initialize(DefaultSFConnectionHandler.java:130)
        at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initializeConnection(DefaultSFConnectionHandler.java:98)
        at net.snowflake.client.jdbc.SnowflakeConnectionV1.initConnectionWithImpl(SnowflakeConnectionV1.java:140)
        at net.snowflake.client.jdbc.SnowflakeConnectionV1.<init>(SnowflakeConnectionV1.java:120)
        at net.snowflake.client.jdbc.SnowflakeDriver.connect(SnowflakeDriver.java:211)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:208)
        at SnowflakeJDBCExample.getConnection(SnowflakeJDBCExample.java:93)
        at SnowflakeJDBCExample.main(SnowflakeJDBCExample.java:31)

KevinMellott91 avatar Mar 26 '24 23:03 KevinMellott91

Hello @KevinMellott91 ,

Thanks for raising the issue, will look into it. Did you face the issue recently with 3.15.0 or it never worked before? was it working before or this is first time you trying with encrypted keys? Was it working with any previous version of openSSL before v3.1.1.

Regards, Sujan

sfc-gh-sghosh avatar Mar 27 '24 03:03 sfc-gh-sghosh

This issue is applicable to 3.15.0 too.

radhe-kishan avatar Mar 27 '24 04:03 radhe-kishan

Hello @KevinMellott91 ,

Thanks for raising the issue, will look into it. Did you face the issue recently with 3.15.0 or it never worked before? was it working before or this is first time you trying with encrypted keys? Was it working with any previous version of openSSL before v3.1.1.

Regards, Sujan

I haven't gotten this working before (never tried in the past), but I was not able to get the 3.13.30 driver to work either.

KevinMellott91 avatar Mar 27 '24 14:03 KevinMellott91

For context, I was trying driver 3.13.30 first because that is the version used within my Flyway version. When the Flyway connection could not be made, I dug deeper into the driver itself to find this issue.

KevinMellott91 avatar Mar 27 '24 14:03 KevinMellott91

Hello @KevinMellott91 ,

This is a commonly known issue with Java not supporting most modern encrypted key types https://github.com/snowflakedb/snowflake-sdks-drivers-issues-teamwork/issues/618

As a workaround you can try the below command openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out rsa_key.p8

if it doesnt work, please generate and export it from the older OpenSSL version, its still a secure private key of the legacy format.

Regards, Sujan

sfc-gh-sghosh avatar Apr 03 '24 12:04 sfc-gh-sghosh

Hello @KevinMellott91 ,

This is a commonly known issue with Java not supporting most modern encrypted key types https://github.com/snowflakedb/snowflake-sdks-drivers-issues-teamwork/issues/618

As a workaround you can try the below command openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -v1 PBE-SHA1-RC4-128 -out rsa_key.p8

if it doesnt work, please generate and export it from the older OpenSSL version, its still a secure private key of the legacy format.

Regards, Sujan

Hi @sfc-gh-sghosh thanks for the workaround information. Unfortunately, I won't be able to use this due to security team requirements.

However, I was wondering if #1671 is a fix for this issue? If I'm understanding the update correctly, it appears it would add a configuration that would allow Bouncy Castle to handle the decryption aspects.

KevinMellott91 avatar Apr 03 '24 16:04 KevinMellott91

Hi @KevinMellott91,

Yes, that's the objective of PR #1671. Would it be possible for you to build that PR and test the fix? Once you build the JDBC driver and replace your JAR, add the JVM argument -Dnet.snowflake.jdbc.enableBouncyCastle=true

sfc-gh-wfateem avatar Apr 03 '24 18:04 sfc-gh-wfateem

@sfc-gh-wfateem I just tested with a local version of the driver (built from that PR branch), and all worked as expected! That PR will fix this issue.

KevinMellott91 avatar Apr 03 '24 21:04 KevinMellott91

PR #1671 has been merged and we'll add documentation concerning the new JVM argument.

sfc-gh-wfateem avatar Apr 12 '24 20:04 sfc-gh-wfateem