使用 PEM 文件通过 Java JDBC 连接到 Snowflake 时出错

Error connecting to Snowflake through Java JDBC with PEM file

我需要使用 P8

格式的密钥文件 Java 连接到 Snowflake
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;
}

}

当我 运行 代码时,出现错误:

    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.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

我正在搜索,但在文档中没有关于此配置的信息:原因:java.security.InvalidKeyException:需要 PBE 参数

我找到了更改导入的修复程序:

之前:

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;

新:

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;

还有 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>

除了接受的答案中的正确导入外,还值得检查 安全提供程序 是否从 Snowflake jdbc 驱动程序 没有保存在 Java 安全提供程序中,因为它包含不同的参数和数量 - 对我来说是:

  • 2727 参数 net.snowflake.client.jdbc.internal.org.bouncycastle.jcajce.provider
  • 2944 参数 org.bouncycastle.jcajce.provider

正在检查 Bouncy Castle 安全提供商:

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

正在从 bcprov-ext-jdk15on 库中删除现有的 Bouncy Castle Provider 并注册一个新的 Bouncy Castle Provider:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

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