Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to connect with key pair authentication if private key password contains special characters #1186

Closed
StevenMassaro opened this issue Nov 8, 2022 · 3 comments
Assignees
Labels

Comments

@StevenMassaro
Copy link

When using key pair authentication to connect to snowflake through jdbc, and using a special character (like #) in the URL causes an exception: Private key provided is invalid or not supported: rsa_key_bad2.p8: Cannot retrieve the PKCS8EncodedKeySpec

To reproduce this issue, set up key pair auth access to snowflake by following this page, and make sure to choose a password like pass#ord when generating the private key. (You may need to use these instructions to generate your keys: https://community.snowflake.com/s/article/Private-key-provided-is-invalid-or-not-supported-rsa-key-p8--data-isn-t-an-object-ID)

Then, using the newly generated private and public keys, try to connect to Snowflake using this sample Java program, making sure to replace the placeholder values with your values for URL, KEYFILE, and KEYPWD:

import java.sql.*;
import java.util.Properties;

public class Main {
    public static void main(String[] args) throws Exception {
        // get connection
        System.out.println("Create JDBC connection");
        Connection connection = getConnection();
        System.out.println("Done creating JDBC connection\n");

        // create statement
        System.out.println("Create JDBC statement");
        Statement statement = connection.createStatement();
        System.out.println("Done creating JDBC statement\n");

        // create a table
        System.out.println("Create demo table");
        statement.executeUpdate("create or replace table demo(c1 string)");
        System.out.println("Done creating demo table\n");

        // insert a row
        System.out.println("Insert 'hello world'");
        statement.executeUpdate("insert into demo values ('hello world')");
        System.out.println("Done inserting 'hello world'\n");

        // query the data
        System.out.println("Query demo");
        ResultSet resultSet = statement.executeQuery("select * from demo");
        System.out.println("Metadata:");
        System.out.println("================================");

        // fetch metadata
        ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
        System.out.println("Number of columns=" + resultSetMetaData.getColumnCount());
        for (int colIdx = 0; colIdx < resultSetMetaData.getColumnCount(); colIdx++) {
            System.out.println(
                    "Column " + colIdx + ": type=" + resultSetMetaData.getColumnTypeName(colIdx + 1));
        }

        // fetch data
        System.out.println("\nData:");
        System.out.println("================================");
        int rowIdx = 0;
        while (resultSet.next()) {
            System.out.println("row " + rowIdx + ", column 0: " + resultSet.getString(1));
        }
        resultSet.close();
        statement.close();
        connection.close();
    }

    private static Connection getConnection() throws SQLException, ClassNotFoundException {
        // build connection properties
        Class.forName("net.snowflake.client.jdbc.SnowflakeDriver");
        Properties properties = new Properties();
        properties.put("user", ""); // replace "" with your user name
        properties.put("warehouse", ""); // replace "" with target warehouse name
        properties.put("db", ""); // replace "" with target database name
        properties.put("schema", ""); // replace "" with target schema name
        String connectStr = "jdbc:snowflake://URL?private_key_file=KEYFILE&private_key_file_pwd=KEYPWD";
        return DriverManager.getConnection(connectStr, properties);
    }
}

You should get the following exception:

Exception in thread "main" net.snowflake.client.jdbc.SnowflakeSQLLoggedException: Private key provided is invalid or not supported: C:/dev/temp/DAT-11888/rsa_key_bad2.p8: Cannot retrieve the PKCS8EncodedKeySpec
	at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initialize(DefaultSFConnectionHandler.java:109)
	at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initializeConnection(DefaultSFConnectionHandler.java:79)
	at net.snowflake.client.jdbc.SnowflakeConnectionV1.initConnectionWithImpl(SnowflakeConnectionV1.java:116)
	at net.snowflake.client.jdbc.SnowflakeConnectionV1.<init>(SnowflakeConnectionV1.java:96)
	at net.snowflake.client.jdbc.SnowflakeDriver.connect(SnowflakeDriver.java:176)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
	at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:189)
	at Main.getConnection(Main.java:63)
	at Main.main(Main.java:8)
@StevenMassaro
Copy link
Author

I couldn't find a way to escape the #. I tried URL encoding it, since the Snowflake driver will decode the values: https://github.com/snowflakedb/snowflake-jdbc/blob/master/src/main/java/net/snowflake/client/jdbc/SnowflakeConnectString.java#L91-L92, but that causes the following error: JWT token is invalid.

@sfc-gh-spanaite
Copy link
Contributor

@StevenMassaro Are you still able to reproduce the issue with the latest JDBC driver version? And if yes, can you please provide me with the OS version and OpenSSL version?

@sfc-gh-spanaite
Copy link
Contributor

Closing since no updates since Oct last year.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants