You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSL双向认证连接抛出NoSuchAlgorithmException问题求助

连接双向认证Web服务时Web应用抛出NoSuchAlgorithmException(Java应用正常)

我在连接一个需要客户端/服务端双向认证的Web服务时,抛出了NoSuchAlgorithmException异常。相同代码作为标准Java应用运行完全正常,但部署成Web应用运行时就会触发这个异常,求解决思路。

代码示例

try {
    System.setProperty("javax.net.debug", "ssl,handshake");
    System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
    System.setProperty("javax.net.ssl.keyStore", "c:\\Sifen\\F1T_5159.p12");
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    
    String soapRequest = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            + "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:xsd=\"http://ekuatia.set.gov.py/sifen/xsd\">\n"
            + "<soap:Header/>\n"
            + "<soap:Body>\n"
            + "<xsd:rEnviConsRUC xmlns=\"http://ekuatia.set.gov.py/sifen/xsd\"\n"
            + "                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
            + "                xsi:schemaLocation=\"http://ekuatia.set.gov.py/sifen/xsd/ siConsRUC_v150.xsd\">\n"
            + "    <xsd:dId>1</xsd:dId>\n"
            + "    <xsd:dRUCCons>80033703</xsd:dRUCCons>\n"
            + "</xsd:rEnviConsRUC>\n"
            + "</soap:Body>\n"
            + "</soap:Envelope>";

    String url = "https://sifen-test.set.gov.py/de/ws/consultas/consulta-ruc.wsdl";

    URL obj = new URL(url);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    con.setRequestMethod("POST");
    con.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
    con.setDoOutput(true);
    
    try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
        wr.writeBytes(soapRequest);
        wr.flush();
    }
    
    String responseStatus = con.getResponseMessage();
    System.out.println(responseStatus);
    BufferedReader in = new BufferedReader(new InputStreamReader(
            con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();
    
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    String finalvalue = response.toString();
    System.out.println(finalvalue);
} catch (Exception e) {
    System.out.println(e.getMessage());
}

异常信息

java.security.NoSuchAlgorithmException: 构造实现时出错(算法: Default,提供者: SunJSSE,类: sun.security.ssl.SSLContextImpl$DefaultSSLContext)

解决思路

  • 排查类加载冲突:Web容器的类加载机制和标准Java应用不同,检查Web应用依赖中是否包含第三方SSL/Crypto相关jar包(比如bcprov-jdkxx等),这类jar会覆盖JRE自带的SunJSSE实现,导致算法找不到。移除冲突jar即可。
  • 提前设置系统属性:Web应用中通过System.setProperty设置SSL属性的时机可能太晚,建议在Web应用启动初期(比如ServletContextListener的contextInitialized方法)设置,或者直接在Web容器启动参数中配置(如Tomcat的catalina.sh添加-Djavax.net.ssl.keyStore=xxx等参数)。
  • 修正密钥库路径与权限:Web应用运行的工作目录和本地Java应用不同,即使使用绝对路径,也可能因容器权限限制无法读取密钥库。可以将密钥库放到Web应用资源目录,通过类加载器获取路径:Thread.currentThread().getContextClassLoader().getResource("F1T_5159.p12").getPath(),同时确保容器进程有读取该文件的权限。
  • 统一JRE版本:检查Web容器使用的JRE版本和本地运行的JRE是否一致,部分旧版JRE对SSL算法支持不足,或默认Provider配置不同。
  • 手动初始化SSLContext:不依赖默认SSLContext,手动构建SSL上下文并绑定到连接,避免容器默认配置干扰:
KeyStore keyStore = KeyStore.getInstance("PKCS12");
try (InputStream is = new FileInputStream("c:\\Sifen\\F1T_5159.p12")) {
    keyStore.load(is, "password".toCharArray());
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, "password".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

内容的提问来源于stack exchange,提问作者César

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 20:15:41