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

SNOW-1279620: Error: Could not read private key with value passed in connection string. \n Error : incorrect private key value or private key format #903

Closed
jamespfluger-ava opened this issue Mar 27, 2024 · 2 comments
Assignees
Labels
bug status-information_needed Additional information is required from the reporter status-triage Issue is under initial triage

Comments

@jamespfluger-ava
Copy link

Main Issue

My issue is that the private key is not being read for some reason. I've included a sample project below and the format of my key file that is being read.

My main question is: how do I get my private key to be read properly?
My secondary question would be if there are character limitations on the passphrase for the file.

I have already read #587 and it didn't help. I'm at a loss, as no matter what I do it seems the key isn't being read properly. I'm assuming the issue is with the key, but I can't confirm this (I'm working with a key shared with me)


1. What version of .NET driver are you using?
3.1

2. What operating system and processor architecture are you using?
Windows 11, x64

3. What version of .NET framework are you using?
.NET 6

4. What did you do?

I have a runnable program - repo link is here:
https://github.com/jamespfluger-ava/snowflake-privatekey

Program.cs:

using System;
using System.IO;
using Snowflake.Data.Client;

string keyText = File.ReadAllText(@"C:\.keys\snowflake_key.p8").ReplaceLineEndings("\n");
string keyPwd = Environment.GetEnvironmentVariable("SNOWFLAKE_KEY_PASSPHRASE");

// NOTE: The following items with <[...]> need to be replaced with your own information (without the arrows)
SnowflakeDbConnectionStringBuilder connStringBuilder = new SnowflakeDbConnectionStringBuilder()
{
    ["ACCOUNT"] = "<ACCOUNT_NAME>",
    ["DB"] = "<DB_NAME>",
    ["SCHEMA"] = "<SCEHMA_NAME>",
    ["USER"] = "<USER_NAME>",
    ["ROLE"] = "<ROLE_NAME>",
    ["WAREHOUSE"] = "<WH_NAME>",
    ["AUTHENTICATOR"] = "SNOWFLAKE_JWT",
    ["PRIVATE_KEY"] = keyText,
    ["PRIVATE_KEY_PWD"] = keyPwd,
    ["CLIENT_CONFIG_FILE"] = @"C:\snowflake-privatekey\sf_client_config.json"
};

SnowflakeDbConnection conn = new SnowflakeDbConnection();
conn.ConnectionString = connStringBuilder.ConnectionString;
conn.Open();

Console.WriteLine("Connection successful!");

SnowflakePrivateKey.csproj:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Snowflake.Data" Version="3.1.0" />
    </ItemGroup>
</Project>

This uses the the private key file (does not contain any equals sign) with the exact format of

-----BEGIN ENCRYPTED PRIVATE KEY-----
MII[XXXXX...]
[many more lines]
[...XXXXX]tQr
-----END ENCRYPTED PRIVATE KEY-----

5. What did you expect to see?

Expect: to have a connection open to Snowflake and the text Connection successful! printed to the console

Instead: I receive a Snowflake.Data.Client.SnowflakeDbException with this message:

Error: Could not read private key with value passed in connection string. \n Error : incorrect private key value or private key format: use "\n" for newlines and double the equals sign. SqlState: , VendorCode: XXXXXX, QueryId: 

With this stack trace:

   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.GenerateJwtToken()
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.Authenticate()
   at Snowflake.Data.Core.SFSession.Open()
   at Snowflake.Data.Core.Session.SessionPool.NewSession(String connectionString, SecureString password)
   at Snowflake.Data.Core.Session.SessionPool.GetSession(String connStr, SecureString password)
   at Snowflake.Data.Client.SnowflakeDbConnection.Open()
   at Program.<Main>$(String[] args) in C:\snowflake-privatekey\Program.cs:line 25

Inner exception is an Org.BouncyCastle.Crypto.InvalidCipherTextException:

problem creating ENCRYPTED private key: Org.BouncyCastle.Crypto.InvalidCipherTextException: pad block corrupted
   at Org.BouncyCastle.Crypto.Paddings.Pkcs7Padding.PadCount(Byte[] input)
   at Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher.DoFinal(Byte[] output, Int32 outOff)
   at Org.BouncyCastle.Crypto.BufferedBlockCipher.DoFinal(Byte[] input, Int32 inOff, Int32 inLen)
   at Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory.CreatePrivateKeyInfo(Char[] passPhrase, Boolean wrongPkcs12Zero, EncryptedPrivateKeyInfo encInfo)
   at Org.BouncyCastle.OpenSsl.PemReader.ReadPrivateKey(PemObject pemObject)

Inner exception stack trace:

   at Org.BouncyCastle.OpenSsl.PemReader.ReadPrivateKey(PemObject pemObject)
   at Org.BouncyCastle.OpenSsl.PemReader.ReadObject()
   at Snowflake.Data.Core.Authenticator.KeyPairAuthenticator.GenerateJwtToken()

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

Yes, but they are empty. Log files in the format snowflake_dotnet_XXXXXX.log are created, but do not have ANY contents (at all) when log_level is set to DEBUG or TRACE using Easy Logging and the CLIENT_CONFIG_FILE

According to a coworker, there are no logs of an attempted connection, so it seems the issue is that the key isn't being read properly.

@github-actions github-actions bot changed the title Error: Could not read private key with value passed in connection string. \n Error : incorrect private key value or private key format SNOW-1279620: Error: Could not read private key with value passed in connection string. \n Error : incorrect private key value or private key format Mar 27, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka self-assigned this Mar 28, 2024
@sfc-gh-dszmolka sfc-gh-dszmolka added the status-triage Issue is under initial triage label Mar 28, 2024
@sfc-gh-dszmolka
Copy link
Contributor

sfc-gh-dszmolka commented Mar 28, 2024

hi - first of all, thank you so much for the detailed issue description and providing us with a clear repro , much appreciated !

To be honest, your program worked right off the bat for me like this, i changed nothing significant just

  • used a hardcoded PK password
  • also commented out the local client config as it should not be relevant for this issue:
  • PK path specified with \\ instead of single \ but I also retried it with single \ and worked as well
  • used Snowflake .NET driver 3.0.0, but tested with very latest 3.1.0 too and worked as well
using System;
using System.IO;
using Snowflake.Data.Client;

string keyText = File.ReadAllText(@"C:\\temp\\rsa_key_encrypted.p8").ReplaceLineEndings("\n");
//string keyPwd = Environment.GetEnvironmentVariable("SNOWFLAKE_KEY_PASSPHRASE");
string keyPwd = "<PK_password>";

// NOTE: The following items with <[...]> need to be replaced with your own information (without the arrows)
SnowflakeDbConnectionStringBuilder connStringBuilder = new SnowflakeDbConnectionStringBuilder()
{
    ["ACCOUNT"] = "<MY_ACCOUNT>",
    ["USER"] = "<MY_USER>",
    ["AUTHENTICATOR"] = "SNOWFLAKE_JWT",
    ["PRIVATE_KEY"] = keyText,
    ["PRIVATE_KEY_PWD"] = keyPwd
    //["CLIENT_CONFIG_FILE"] = @"C:\snowflake-privatekey\sf_client_config.json"
};

SnowflakeDbConnection conn = new SnowflakeDbConnection();
conn.ConnectionString = connStringBuilder.ConnectionString;
conn.Open();

Console.WriteLine("Connection successful!");

Resulted in successful connection. The private key itself was generated per the Snowflake Generate Private Key documentation.

Considering all of the above and the exception you're seeing, probably it would be worth trying to

  1. generate a new private key exactly as described in the above documentation
  2. of course you'd need to generate the public key part too and feed it to the Snowflake user (ALTER USER <myuser> SET RSA_PUBLIC_KEY_2='MII...'; - adds as an alternative, second key. Or without the 2 if you want to just replace the original public key)
  3. retry and see how it goes

Let me know please if you had a chance to try and how it went

edit: sorry I just see there was a secondary question on any character limitation regarding the password. As a quick check, I don't think there should be any limitations besides what's coming from String.ToCharArray() . Here's the logic on that.

@sfc-gh-dszmolka sfc-gh-dszmolka added the status-information_needed Additional information is required from the reporter label Mar 28, 2024
@jamespfluger-ava
Copy link
Author

@sfc-gh-dszmolka Thanks for the reply! I tried with a new key and it is being parsed correctly. So this issue was on my end.

Appreciate all the documentation that's up-to-date and that a .NET connector exists!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug status-information_needed Additional information is required from the reporter status-triage Issue is under initial triage
Projects
None yet
Development

No branches or pull requests

2 participants