从 GCP 秘密管理器读取 .DER 值并将其保存到 .DER 文件
Read .DER value from GCP secret manager and save it to .DER file
首先,这是我的第一个 post - 如果这个 post 描述和设计不完善,请见谅。
我的问题是我需要使用 spring 引导通过 SSL 连接连接到 GCP 中的数据库。在 GCP 内部生成三个所需的证书(客户端-cert.pem、客户端-key.pem、服务器-ca.pem)。不幸的是 spring 无法使用存储在 pem 文件中的客户端密钥连接到数据库,因此我必须将 exmaple 的客户端密钥保存在 .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();
}
为了从 .PEM 文件生成 .DER,我使用了这个命令:
openssl pkcs8 -topk8 -inform PEM -in client-key.pem -outform DER -nocrypt -out client-key.der
它在本地有效,但我必须将证书保存在 GCP 的秘密管理器 (SM) 中。 SM 只能存储值,所以我保留 .DER 文件中的二进制值
![Take a look at image](https://i.stack.imgur.com/dAjLU.png).
我正在使用 GCP java 库连接到 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 文件中,那么我的客户端-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
知道我应该如何从 GCP SM 读取二进制文件(如 .DER 证书)吗?我读到应该编码,但直到现在我都没有成功。
感谢提前,请保持温柔,这是我的第一次 post :)
根据 John 的评论,我将编码的 .DER 文件保存在秘密管理器中。接下来我解码了来自秘密管理器 API 的值。在这种情况下很重要 - 将 byte[] 而不是 String 保存到文件 !
更新:
您不需要在 SM 中保存编码的 .DER 值。您可以保留二进制值,但要从 API 获取这些值,您需要使用:
return response.getPayload().getData().toByteArray();
并保存在 .DER 证书中,然后使用以下行:
try (FileOutputStream stream = new FileOutputStream(path)) {
stream.write(Base64.getMimeDecoder().decode(Base64.getEncoder().encode(certValue)));
}
首先,这是我的第一个 post - 如果这个 post 描述和设计不完善,请见谅。
我的问题是我需要使用 spring 引导通过 SSL 连接连接到 GCP 中的数据库。在 GCP 内部生成三个所需的证书(客户端-cert.pem、客户端-key.pem、服务器-ca.pem)。不幸的是 spring 无法使用存储在 pem 文件中的客户端密钥连接到数据库,因此我必须将 exmaple 的客户端密钥保存在 .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();
}
为了从 .PEM 文件生成 .DER,我使用了这个命令:
openssl pkcs8 -topk8 -inform PEM -in client-key.pem -outform DER -nocrypt -out client-key.der
它在本地有效,但我必须将证书保存在 GCP 的秘密管理器 (SM) 中。 SM 只能存储值,所以我保留 .DER 文件中的二进制值
![Take a look at image](https://i.stack.imgur.com/dAjLU.png).
我正在使用 GCP java 库连接到 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 文件中,那么我的客户端-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
知道我应该如何从 GCP SM 读取二进制文件(如 .DER 证书)吗?我读到应该编码,但直到现在我都没有成功。
感谢提前,请保持温柔,这是我的第一次 post :)
根据 John 的评论,我将编码的 .DER 文件保存在秘密管理器中。接下来我解码了来自秘密管理器 API 的值。在这种情况下很重要 - 将 byte[] 而不是 String 保存到文件 !
更新: 您不需要在 SM 中保存编码的 .DER 值。您可以保留二进制值,但要从 API 获取这些值,您需要使用:
return response.getPayload().getData().toByteArray();
并保存在 .DER 证书中,然后使用以下行:
try (FileOutputStream stream = new FileOutputStream(path)) { stream.write(Base64.getMimeDecoder().decode(Base64.getEncoder().encode(certValue))); }