在配置带有jndi数据源的tomcat以使用ssl身份验证连接到postgres服务器时(请参阅为tomcat jndi连接到postgresql提供证书,我遇到以下错误:
[main] WARN org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata : Cannot create PoolableConnectionFactory (Could not find a java cryptographic algorithm: Cannot find any provider supporting 1.2.840.113549.1.5.13.)
(这是初始化时间的警告,但是当我实际尝试使用连接时,我看到的错误与阻止访问数据库相同)。
基于以下答案:以PEM格式读取PKCS8:找不到我尝试/usr/lib/jvm/java-11-openjdk- amd64/conf/security/java.security通过添加org.bouncycastle.jce.provider.BouncyCastleProvider为第一个安全提供程序来修改的提供程序。我还尝试将jar bcprov-jdk15on-1.64.jar添加到/usr/lib/jvm/java-11-openjdk- amd64/lib和/usr/share/java(在任何地方都没有lib / ext目录)。
/usr/lib/jvm/java-11-openjdk- amd64/conf/security/java.security
org.bouncycastle.jce.provider.BouncyCastleProvider
/usr/lib/jvm/java-11-openjdk- amd64/lib
/usr/share/java
问题仍然存在。
我应该如何告诉在Java运行时,tomcat或hibernate状态下使用Bouncy Castle安全提供程序?
更新:还尝试安装libbcprov-java并在java.security中设置安全提供程序,但未成功。
我认为这足以回答问题,比注释更易读。而且更安全。
SunJCE和bcprov都Cipher为多个PBES2家族密码(和作为组成部分的PBKDF2)实现实例,但都没有Cipher按名称或OID为PBES2 实例实现,因为PBES2不是一个密码,因此是一个(大)家族。如前所述,SunJCE确实AlgorithmParameters通过OID和名称为PBES2 实现。(Bouncy当然会在内部实现PBES2参数,在我看来,它们似乎可以在直接或“轻量” API中使用,但不会通过提供者SPI公开它们。)
Cipher
AlgorithmParameters
您的密钥文件 采用 PKCS8加密格式;问题在于PKCS8加密可以使用许多加密方案(密码),包括不是由一个OID标识的PBES2系列(如PKCS5v1和PKCS12中的较旧/较简单的OBID),而是由三个:“外部” PBES2,PBKDF2(带有派生)参数)和基础对称密码(带有加密参数)。
假设https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/ssl/LazyKeyManager.java是正确的代码(行号205确实与您的stacktrace匹配)不适用于处理两层(PBES2)情况。但是,它 确实 会首先尝试 未加密的 PKCS8,并且只有在失败的情况下才尝试加密的PKCS8。使用由一个OID标识的方案。因此,如果您的环境中具有未加密的密钥文件是可以接受的,那应该行得通,我的建议也应该使用通过单级方案(例如PKCS12的pbeWithSHAAnd3-KeyTripleDES- CBC)进行加密的PKCS8-通过检查,我发现SunJCE实际上将其命名为PBEWithSHA1AndDESede使用正确的OID 1.2.840.113549.1.12.1.3,此处重要的是所有内容。(bcprov使用标准名称,但大写除外-JCA不区分大小写。)
根据创建密钥文件的软件或过程的不同,可能会对其进行调整以产生所需的格式。如果没有,并且您拥有或获得OpenSSL,则它可以处理许多(大多数)PKCS8选项:
# we need an intermediate PEM file; for safety (PB)encrypt it openssl pkey <p8unusable.der -inform d -aes256 >temp.pem # to unencrypted PKCS8 openssl pkcs8 -topk8 <temp.pem -outform d -nocrypt >p8unenc.der # to encrypted PKCS8 using single-level PKCS12 scheme openssl pkcs8 -topk8 <temp.pem -outform d -v1 pbeWithSHA1And3-KeyTripleDES-CBC >p8encone.der # note OpenSSL spells SHA1 where PKCS12 had SHA (which was technically wrong) # OTOH OpenSSL implies this is PKCS5v1 which it isn't. Bleah. rm temp.pem # or erase or whatever