#jdbc #snowflake-cloud-data-platform
#jdbc #snowflake-cloud-data-platform
Вопрос:
Я использую snowflake-jdbc для подключения к базе данных snowflake
ниже приведена библиотека
<!-- https://mvnrepository.com/artifact/net.snowflake/snowflake-jdbc -->
<dependency>
<groupId>net.snowflake</groupId>
<artifactId>snowflake-jdbc</artifactId>
<version>3.13.11</version>
</dependency>
Свойства драйвера заданы ниже.
String url = "jdbc:snowflake://<account_identifier>.snowflakecomputing.com";
Properties prop = new Properties();
prop.put("user", "<user>");
props.put("private_key_file", "/tmp/rsa_key.p8");
props.put("private_key_file_pwd", "dummyPassword");
prop.put("db", "<database_name>");
prop.put("schema", "<schema_name>");
prop.put("warehouse", "<warehouse_name>");
prop.put("role", "<role_name>");
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();
Когда я тестирую на своем локальном компьютере, я могу установить соединение, но при развертывании на AWS ECS (docker) Я получаю приведенную ниже ошибку, когда я пытался установить соединение
предоставленный закрытый ключ недействителен или не поддерживает 1.2.840.113549.1.5.13 недоступна secretkeyfactory Я проверил все пути и убедился, что в указанном пути есть файл private_key.
чего-нибудь не хватает в конфигурации?
Ответ №1:
При аутентификации с использованием аутентификации по паре ключей с использованием закрытого ключа, который генерируется с использованием OpenSSL 1.1.1g, и при подключении к Snowflake через драйвер JDBC отображается ошибка типа -Предоставленный закрытый ключ недействителен или не поддерживается -rsa-key-p8. Целью этой статьи является предоставление обходных путей для решения этой проблемы
Ответ №2:
Существуют некоторые несовместимости между версией OpenSSL, используемой для шифрования закрытого ключа, и криптографическими библиотеками Java.
Вам нужно изменить подход и не использовать свойства:
props.put("private_key_file", "/tmp/rsa_key.p8");
props.put("private_key_file_pwd", "dummyPassword");
Но замените их решением с одним свойством ‘PrivateKey‘:
props.put("privateKey", PrivateKeyReader.get(PRIVATE_KEY_FILE));
Вот пример кода, взятый из официальной документации Snowflake:
Цитата из блока: https://docs.snowflake.com/en/user-guide/jdbc-configure.html#privatekey-property-in-connection-properties
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;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.Security;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.DriverManager;
import java.util.Properties;
public class TestJdbc
{
// Path to the private key file that you generated earlier.
private static final String PRIVATE_KEY_FILE = "/<path>/rsa_key.p8";
public static class PrivateKeyReader
{
// If you generated an encrypted private key, implement this method to return
// the passphrase for decrypting your private key.
private static String getPrivateKeyPassphrase() {
return "<private_key_passphrase>";
}
public static PrivateKey get(String filename)
throws Exception
{
PrivateKeyInfo privateKeyInfo = null;
Security.addProvider(new BouncyCastleProvider());
// Read an object from the private key file.
PEMParser pemParser = new PEMParser(new FileReader(Paths.get(filename).toFile()));
Object pemObject = pemParser.readObject();
if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
// Handle the case where the private key is encrypted.
PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemObject;
String passphrase = getPrivateKeyPassphrase();
InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passphrase.toCharArray());
privateKeyInfo = encryptedPrivateKeyInfo.decryptPrivateKeyInfo(pkcs8Prov);
} else if (pemObject instanceof PrivateKeyInfo) {
// Handle the case where the private key is unencrypted.
privateKeyInfo = (PrivateKeyInfo) pemObject;
}
pemParser.close();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
return converter.getPrivateKey(privateKeyInfo);
}
}
public static void main(String[] args)
throws Exception
{
String url = "jdbc:snowflake://<account_identifier>.snowflakecomputing.com";
Properties prop = new Properties();
prop.put("user", "<user>");
prop.put("privateKey", PrivateKeyReader.get(PRIVATE_KEY_FILE));
prop.put("db", "<database_name>");
prop.put("schema", "<schema_name>");
prop.put("warehouse", "<warehouse_name>");
prop.put("role", "<role_name>");
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();
}
}