JDBC 使用私钥连接到 Snowflake - 没有密码

JDBC Connection to Snowflake with Private key - without passphrase

我正在开发一个 Java 基于客户端的代码,该代码尝试使用私钥连接到 snowflake JDBC 我在网上搜索并找到了这个链接:

https://domohelp.domo.com/hc/en-us/articles/360042931854-Snowflake-Using-Key-Pair-Authentication-Connector

https://docs.snowflake.com/en/user-guide/jdbc-configure.html 和其他链接,都需要使用密码

和我的代码

        Properties p = new Properties();
    p.setProperty(USER, jdbcDetails.username);
    String privateKey = jdbcDetails.getPrivateKey().replace("-----BEGIN ENCRYPTED PRIVATE KEY-----\n", "");
    privateKey = privateKey.replace("\n-----END ENCRYPTED PRIVATE KEY-----", "");
    String passphrase = "abcdefg";
    EncryptedPrivateKeyInfo pkInfo = new EncryptedPrivateKeyInfo(Base64.getMimeDecoder().decode(privateKey));
    PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
    SecretKeyFactory pbeKeyFactory = SecretKeyFactory.getInstance(pkInfo.getAlgName());
    PKCS8EncodedKeySpec encodedKeySpec = pkInfo.getKeySpec(pbeKeyFactory.generateSecret(keySpec));
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PrivateKey encryptedPrivateKey = keyFactory.generatePrivate(encodedKeySpec);
    p.put("privateKey", encryptedPrivateKey);
    return p;

似乎此代码对连接有效,但在与我们的 DBA 交谈后 他告诉我他可以在不指定密码的情况下连接

使用此命令:

snowsql -h a-b-c-d.snowflakecomputing.com -a abcd.AWS_US_EAST-1 -u username  -d  INTEGRATION_ENGINE    --private-key-path ~postgres/ADHOC/12345/rsa_key.p8 -q "select 1"

我如何使用带有私钥的 jdbc 进行连接 - 而没有 passspharse?

可以使用加密私钥和解密私钥创建 2 种类型的用户,此代码片段构建私钥对象并需要添加到属性中

有 2 个 pemObject 实例,一个用于加密,需要 passPharase,另一个不需要

// pemObject instanceof PKCS8EncryptedPrivateKeyInfo(加密私钥) // pemObject instanceof PrivateKeyInfo 解密私钥

public class PrivateKeyReader {


    public static PrivateKey get(File file, String passPhrase)
    {
        try {
            PrivateKeyInfo privateKeyInfo = null;
            Security.addProvider(new BouncyCastleProvider());
            // Read an object from the private key file.
            final PEMParser pemParser = new PEMParser(new FileReader(file));
            final Object pemObject = pemParser.readObject();
            if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
                // Handle the case where the private key is encrypted.
                final PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemObject;
                final 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();
            final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
            return converter.getPrivateKey(privateKeyInfo);
        } catch (Exception ex){
            throw new RuntimeException(ex.getMessage(), ex);
        }
    }
}

为了将它加载到我使用的连接:

PrivateKey privateKey = PrivateKeyReader.get(tempPublicKeyFile, jdbcDetails.getDecryptedPassPhrase());
    p.put("privateKey", privateKey);