RUDE

Прочитайте значение .DER из диспетчера секретов GCP и сохраните его в файле .DER.

Во-первых, это мой первый пост - извините, если этот пост не очень хорошо описан и оформлен.

Моя проблема в том, что мне нужно подключиться к БД в GCP с помощью SSL-соединения, используя весеннюю загрузку. Внутри GCP я генерирую три необходимых сертификата (client-cert.pem, client-key.pem, server-ca.pem). К сожалению, Spring не может подключиться к базе данных с клиентским ключом, хранящимся в файле pem, поэтому я должен хранить клиентский ключ, например, внутри сертификата .DER.

Для подключения к БД я использую этот фрагмент кода.

return DataSourceBuilder
                .create()
                .url("jdbc:postgresql://XXX:5432/XXX?" +
                        "ssl=true&sslmode=verify-ca&" +
                        "sslrootcert=server-ca.pem&" +
                        "sslcert=client-cert.pem&" +
                        "sslkey=client-key.der")
                .build();
    }

Чтобы сгенерировать .DER из файла .PEM, я использовал эту команду:

openssl pkcs8 -topk8 -inform PEM -in client-key.pem -outform DER -nocrypt -out client-key.der

Локально это работает, но я должен хранить сертификаты внутри секретного менеджера (SM) в GCP. SM может хранить только значения, поэтому я сохраняю двоичные значения из файла .DER.

![Take a look at image](https://i.stack.imgur.com/dAjLU.png).

Я использую java-библиотеки GCP для подключения к SM:

 private String getKey(String projectId, String secretCertName, boolean isPEM) {
            try (SecretManagerServiceClient client = SecretManagerServiceClient.create()) {
                SecretVersionName secretVersionName = SecretVersionName.of(projectId, secretCertName, "latest");
                AccessSecretVersionResponse response = client.accessSecretVersion(secretVersionName);
                return response.getPayload().getData().toStringUtf8();
                
            } catch (IOException e) {
                System.out.println("gcp cant connect !");
            }
            return null;
    }

Он работает с PEM и строковыми значениями, но если я хочу сохранить этот ключ в файле .DER, тогда мой файл client-key.der не соответствует сертификату, сгенерированному openssl, и Spring не может подключиться к БД со стеком:

org.postgresql.util.PSQLException: Could not read SSL key file client-key.der. at org.postgresql.ssl.LazyKeyManager.getPrivateKey(LazyKeyManager.java:284) ~[postgresql-42.3.2.jar:42.3.2] at java.base/sun.security.ssl.AbstractKeyManagerWrapper.getPrivateKey(SSLContextImpl.java:1696) ~[na:na] ...

Caused by: java.io.IOException: Invalid lenByte at java.base/sun.security.util.DerValue.<init>(DerValue.java:374) ~[na:na] at java.base/sun.security.util.DerValue.<init>(DerValue.java:312) ~[na:na] at java.base/javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:86) ~[na:na] at org.postgresql.ssl.LazyKeyManager.getPrivateKey(LazyKeyManager.java:236) ~[postgresql-42.3.2.jar:42.3.2] ... 73 common frames omitted

Любая идея, как я должен читать двоичные файлы (например, сертификат .DER) из GCP SM? Я читал, что это должно быть закодировано, но до сих пор у меня не было успеха.

Спасибо за заранее и, пожалуйста, будьте нежны, это мой первый пост :)


2
52
1

Ответ:

Решено

Основываясь на комментарии Джона, я сохранил закодированный файл .DER в секретном менеджере. Затем я расшифровал значение из API секретного менеджера. Важная вещь в этом случае - сохранить byte[] вместо String в файл!