- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我的服务器使用的是 java 7,并且在 FIPS 模式下运行良好。现在我们正在升级到 jre8,在启动期间加载 cacerts 时出现以下异常。
java.lang.RuntimeException: java.security.NoSuchProviderException: no such provider: SunEC
at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:96)
at sun.security.util.ECUtil.decodeX509ECPublicKey(ECUtil.java:102)
at sun.security.pkcs11.P11ECKeyFactory.engineGeneratePublic(P11ECKeyFactory.java:170)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at sun.security.x509.X509Key.buildX509Key(X509Key.java:223)
at sun.security.x509.X509Key.parse(X509Key.java:170)
at sun.security.x509.CertificateX509Key.<init>(CertificateX509Key.java:75)
at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:667)
at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:167)
at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1806)
at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:195)
at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:99)
at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:339)
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:747)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
at java.security.KeyStore.load(KeyStore.java:1433)
at org.apache.commons.ssl.KeyStoreBuilder.tryJKS(KeyStoreBuilder.java:476)
at org.apache.commons.ssl.KeyStoreBuilder.parse(KeyStoreBuilder.java:383)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:212)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:165)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:170)
at org.apache.commons.ssl.TrustMaterial.<init>(TrustMaterial.java:175)
at org.apache.commons.ssl.TrustMaterial.<clinit>(TrustMaterial.java:88)
at org.opensaml.xml.security.x509.X509Util.decodeCertificate(X509Util.java:317)
Caused by: java.security.NoSuchProviderException: no such provider: SunEC
at sun.security.jca.GetInstance.getService(GetInstance.java:83)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
at java.security.KeyFactory.getInstance(KeyFactory.java:211)
at sun.security.util.ECUtil.getKeyFactory(ECUtil.java:94)
我所做的唯一修改是将 TLSv1.2 添加到 jdk.tls.disabledAlgorithms=SSLv3,TLSv1.2,因为 NSS 不支持 TLSv1.2。
我能够在 jre7u72 构建中加载相同的内容,我看到 sunpkcs11.jar 在 java 8 中被修改。这不应该是 cacerts 问题,因为我将 java7 cacerts 复制到 java8,但问题仍然存在。
有没有人见过这个问题?它应该是一个 java 错误吗?
=== 编辑 ===
打开了 java 8 错误。我编写了一个针对 jre7 成功运行但在 jre8 上失败的工具。
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import sun.security.provider.Sun;
import sun.security.rsa.SunRsaSign;
/**
* Before running the tool run the following in your Linux box.
*
1. export LD_LIBRARY_PATH=/usr/lib64
2. mkdir /tmp/fips/nssdb
3. modutil -create -dbdir /tmp/fips/nssdb/
4. modutil -fips true -dbdir /tmp/fips/nssdb
5. modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /tmp/fips/nssdb
(Give a strong password like password1!)
* @author atulsm@gmail.com
*
*/
public class TestKeyStoreFIPS {
public static final String NSS_LIB_DIR_PROP = "nss.lib";
public static final String NSS_DB_DIR_PROP = "nss.db";
public static final String SUN_JSSE = "SunJSSE";
public static List<String> disabledAlgs = new ArrayList<String>();
private static final Logger logger = Logger.getLogger(TestKeyStoreFIPS.class.getName());
/**
* @param args
*/
public static void main(String[] args) throws Exception{
if(args.length != 2){
System.out.println("Usage eg: java -Dnss.lib=/usr/lib64 -Dnss.db=/tmp/fips/nssdb -Djavax.net.ssl.keyStorePassword=password1! TestKeyStoreFIPS /tmp/jre8/lib/security/cacerts changeit");
System.exit(1);
}
enablePkcs11Jsse(System.getProperty(NSS_LIB_DIR_PROP), System.getProperty(NSS_DB_DIR_PROP));
testFips();
String file = args[0];
char[] keystorePassword = args[1].toCharArray();
FileInputStream keystoreStream = new FileInputStream(file);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keystoreStream, keystorePassword);
Enumeration<String> aliases = keyStore.aliases();
while(aliases.hasMoreElements()){
String alias = aliases.nextElement();
System.out.println(alias + " : " + keyStore.getCertificate(alias).getType());
}
}
private static void testFips(){
String keyPass = System.getProperty("javax.net.ssl.keyStorePassword");
KeyStore store;
try {
store = KeyStore.getInstance("PKCS11");
if (keyPass != null) {
store.load(null, keyPass.toCharArray());
} else {
store.load(null, null);
}
System.out.println("FIPS test success");
} catch (Throwable e) {
e.printStackTrace();
store = null;
System.out.println("FIPS test failed");
}
}
public static void enablePkcs11Jsse( String libDir, String dbDir) throws Exception {
removeAllProviders();
Provider nss = getNSSFIPSProvider( libDir, dbDir);
removeDisabledAlgos(nss);
Security.insertProviderAt(nss, 1);
Provider sunJsse = new com.sun.net.ssl.internal.ssl.Provider(nss);
removeDisabledAlgos(sunJsse);
Security.insertProviderAt(sunJsse,2);
Sun sun = new Sun();
removeDisabledAlgos(sun);
Security.insertProviderAt(sun,3);
SunRsaSign sunrsa = new SunRsaSign();
removeDisabledAlgos(sunrsa);
Security.insertProviderAt(sunrsa,4);
}
private static Provider getNSSFIPSProvider( String libDir, String dbDir) throws Exception {
if(libDir == null || dbDir == null) {
throw new Exception(NSS_LIB_DIR_PROP + " or " + NSS_DB_DIR_PROP + " not set.");
}
Properties props = new Properties();
props.put("name", "NSSfips");
props.put("nssLibraryDirectory", libDir);
props.put("nssSecmodDirectory", dbDir);
props.put("nssModule", "fips");
props.put("nssDbMode", "readWrite");
return createProvider(props);
}
private static Provider createProvider(Properties props) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
props.store(out, null);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Provider ret = new sun.security.pkcs11.SunPKCS11(in);
if (logger.isLoggable(Level.FINE)) {
// Log all of the registered services
for (Map.Entry<Object, Object> entry : ret.entrySet()) {
logger.log(Level.FINE, "{0} = {1}", new Object[]{entry.getKey(), entry.getValue()});
}
}
return ret;
}
private static void removeAllProviders(){
Provider[] providers = Security.getProviders();
for(Provider prov : providers){
Security.removeProvider(prov.getName());
}
}
private static void removeDisabledAlgos(Provider provider){
for(String alg : disabledAlgs){
if(provider.getProperty(alg) != null){
logger.info("Removing algorithm " + alg + " from provider " + provider);
provider.remove(alg);
}
}
}
}
最佳答案
虽然我探索了其他选项,但一种有效的方法是将我的一个信任库复制为 jre/lib/security/jssecacerts。我看到代码优先于 jssecacerts 而不是 cacerts 并且它现在工作正常。
关于Java 8 无法在 FIPS 中加载其 cacerts。异常 "no such provider: SunEC",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29362724/
我正在向 Java keystore 添加证书,但收到以下警告。命令成功。 keytool -import -trustcacerts -keystore /usr/lib/jvm/java-11-o
我如何确保我导入到 cacert 的证书 (myAppCertificate.crt) 已经存在于 cacert 文件中?有关信息,我正在使用 导入证书 keytool -import -alias
我是 Mercurial 的新手。我创建了一个 Bitbucket 帐户,创建了一个新的私有(private)存储库,然后尝试使用该存储库进行克隆。我收到此错误:中止:找不到 web.cacerts:
我正在与供应商的设备合作,他们使用默认的 Java cacert 来添加证书以允许自签名证书。在处理此过程时,我注意到 cacert 使用默认密码 changeit 为了提高安全性,我想更改 cace
我有一个从我的 CAS 服务器重定向到的 Web 应用程序。但我得到了这个异常(exception): javax.net.ssl.SSLHandshakeException: sun.securit
我已经在 CACert 注册为我的域 example.com 获取受信任的证书,当我想在 CACert 控制面板中添加域时,我必须选择用于该域的电子邮件地址: CACert 常见问题解答指出,目前除了
我的要求是将 Maven 存储库的证书导入全局 keystore 。 证书文件名为 maven-cacert.cer 。 我正在使用 C:\Program Files\Java\jdk1.6.0_20
我的程序中有一些代码设置套接字连接,然后写入远程服务器。 //Get Socket, set timeout, and initialize I/O streams S
我已将Java安装到Windows环境下的默认文件夹中。 但是,我没有管理员访问权限。如何将安全证书添加到 jre/lib/security 路径中的 cacerts 文件中?如果无法编辑此文件,我可
我现在使用devstack安装openstack,但不幸的是,我遇到了一个问题: /home/my/devstack/tools/create_userrc.sh -PA --target-dir /
我需要向 JRE 随附的 cacerts 添加受信任的证书,但我对客户的 JRE 安装没有控制权或所有权。除了假定 cacerts 文件的文件路径位置并将其读入自定义 TrustManager 之外,
我目前认为 cacert.pem 是一组 key ,我可以使用它们来检查我正在与之交谈的网站是否确实是它声称的网站。因此,如果我向某人发送依赖于 cacert.pem 的程序,我可以向他们发送我计算机
客户向我提供了一个用于服务调用的 HTTPS URL。我需要向该 URL 发出请求。我知道如果该 URL 的证书来自一个普通的提供者,那么它很可能已经在默认的 java truststore cace
我有 JAVA_HOME=C:\Users\myuser\jdk1.8.0_65 Eclipse 中的 JRE 系统库指向 C:\Users\myuser\jdk1.8.0_65 java -vers
在我的 Spring boot 应用程序中,我需要调用另一台服务器上的 API (GET: https://anotherserver.com/api)。服务器管理员给了我一个名为 cacerts(无
在我的 PayPal Pro 支付页面中,我使用带有以下选项的 cURL 函数 curl_setopt_array():cUIn CURLOPT_CAINFO => dirname(__FILE__)
我已经 root 了我的 Android (4.0.4) 手机并安装了一个应用程序来代理通过我的计算机的所有 HTTP 流量。这工作正常,我可以查看和修改所有 HTTP 请求。但是 HTTPS 流量不
我正在尝试通过 https 连接到使用非官方 CA 的网站。由于某种原因,它适用于 curl 但不适用于 python 请求。 请参阅下面的示例 Python 3.8.0 (default, Oct
我知道我可以使用 keytool -delete -alias alias -keystore .keystore 从证书存储中删除一些证书。但是我有 109 个证书存储在 cacerts 中:key
我正在使用 OpenJDK 8(从 https://jdk.java.net/java-se-ri/8 下载并解压,添加到 PATH),并且遇到了证书错误。 经过调查,我意识到 cacerts 存在问
我是一名优秀的程序员,十分优秀!