首先,这是我的第一篇文章-如果这篇文章没有经过精心描述和设计,那就很抱歉了。
我的问题是,我需要使用spring-boot通过SSL连接连接到GCP中的DB。在GCP内部,我正在生成三个所需的证书(client-cert.pem,client-key.pem,server-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文件中,那么我的client-key.DER文件与openssl生成的证书不匹配,spring无法连接到具有堆栈的DB:
org.postgresql.util.PSQLException:无法读取java.base/sun.security.SSL.AbstractKeyManagerWrapper.getPrivateKey(SSLContextImpl.java:1696(~[postgresql-42.3.2.jar:42.3.2]上的SSL密钥文件client-key.der。。。
由以下原因引起:java.io.io异常:java.base/sun.security.util.DerValue处的lenByte无效。<init>(DerValue.java:374(~[na:na],位于java.base/sun.security.util.DerValue。<init>(DerValue.java:312(~[na:na],位于java.base/javax.crypto.EncryptedPrivateKeyInfo。<init>(EncryptedPrivateKeyInfo.java:86(~[na:na]在org.postgresql.ssl.LazyKeyManager.getPrivateKey(LazyKeyManager.java:236(~[postgresql-42.3.2.jar:42.3.2]…73个常见帧省略
知道我应该如何从GCP SM读取二进制文件(如.DER证书(吗?我读到了应该编码的内容,但直到现在我都没有成功。
谢谢你的提前通知,请温柔一点,这是我的第一篇帖子:(
基于John注释,我将编码的.DER文件保存在秘密管理器中。接下来我解码了来自秘密管理器API的值。在这种情况下,重要的是将byte[]而不是String保存到文件中!
更新:您不需要在SM中保存编码的.DER值。您可以保留二进制值,但要从API获得这些值,您需要使用:
return response.getPayload().getData().toByteArray();
并保存在内部。DER证书然后使用以下行:
try(FileOutputStream流=新的FileOutputStream(路径(({stream.write(Base64.getMimeDecoder((.decode(Base64.GetEncode((.encode(certValue(((;}