使用函数计算运行程序时候,往外调一个https的WSDL报错,请问有处理案例吗?

使用函数计算运行程序时候,往外调一个https的WSDL报错,请问有处理案例吗?It failed with: \n\tPKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target.

展开
收起
三分钟热度的鱼 2024-03-13 19:10:45 28 发布于安徽 分享
分享
版权
举报
阿里云 AI 助理回答

在使用阿里云函数计算运行程序时,如果调用一个HTTPS的WSDL接口报错,错误信息为:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

这通常是由于目标服务器的SSL证书未被Java的信任库(TrustStore)识别导致的。以下是针对该问题的详细解决方案:


问题原因

该错误表明Java运行时无法验证目标HTTPS服务的SSL证书链。可能的原因包括: 1. 目标服务器使用了自签名证书或非受信任的CA签发的证书。 2. 函数计算环境中的默认信任库未包含目标服务器证书的根CA。


解决方案

方法一:将目标服务器的证书导入到函数计算的信任库

  1. 获取目标服务器的SSL证书
    使用以下命令从目标服务器导出SSL证书:

    openssl s_client -connect <目标服务器域名>:443 -showcerts </dev/null 2>/dev/null | openssl x509 -outform PEM > server-cert.pem
    

    <目标服务器域名>替换为实际的目标服务器域名。

  2. 上传证书到函数计算代码包
    将导出的server-cert.pem文件与您的函数代码一起打包上传。

  3. 修改代码以加载自定义证书
    在代码中指定信任库,加载自定义证书。例如,使用Java语言时,可以通过以下方式实现:

    import javax.net.ssl.*;
    import java.io.InputStream;
    import java.security.KeyStore;
    import java.security.cert.CertificateFactory;
    
    public class CustomTrustManager {
       public static void main(String[] args) throws Exception {
           // 加载自定义证书
           CertificateFactory cf = CertificateFactory.getInstance("X.509");
           InputStream certInputStream = CustomTrustManager.class.getResourceAsStream("/server-cert.pem");
           java.security.cert.X509Certificate caCert = (java.security.cert.X509Certificate) cf.generateCertificate(certInputStream);
    
           // 创建KeyStore并加载证书
           KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
           keyStore.load(null, null);
           keyStore.setCertificateEntry("caCert", caCert);
    
           // 初始化TrustManagerFactory
           TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
           tmf.init(keyStore);
    
           // 配置SSLContext
           SSLContext sslContext = SSLContext.getInstance("TLS");
           sslContext.init(null, tmf.getTrustManagers(), null);
    
           // 设置全局默认SSLContext
           HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
    
           // 测试调用HTTPS接口
           URL url = new URL("https://<目标服务器域名>/wsdl");
           HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
           conn.setRequestMethod("GET");
           System.out.println("Response Code: " + conn.getResponseCode());
       }
    }
    
  4. 重新部署函数
    将修改后的代码和证书文件重新打包并部署到函数计算。


方法二:禁用SSL证书验证(不推荐)

如果目标服务器的证书无法获取或您仅需临时测试,可以通过禁用SSL证书验证来绕过此问题。但请注意,这种方式存在安全风险,不建议在生产环境中使用

以下是一个示例代码,展示如何禁用SSL证书验证:

import javax.net.ssl.*;
import java.security.cert.X509Certificate;

public class DisableSSLValidation {
    public static void main(String[] args) throws Exception {
        // 创建一个信任所有证书的TrustManager
        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }
        };

        // 初始化SSLContext
        SSLContext sc = SSLContext.getInstance("TLS");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());

        // 设置全局默认SSLContext
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // 禁用主机名验证
        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);

        // 测试调用HTTPS接口
        URL url = new URL("https://<目标服务器域名>/wsdl");
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        System.out.println("Response Code: " + conn.getResponseCode());
    }
}

方法三:通过API网关代理请求

如果您无法直接解决证书问题,可以考虑使用阿里云API网关作为代理。API网关支持配置SSL证书,并可以将请求转发到目标HTTPS服务。具体步骤如下: 1. 在API网关中创建一个后端服务,指向目标HTTPS服务。 2. 配置API网关的SSL证书,确保其信任目标服务器的证书。 3. 修改函数代码,将请求发送到API网关的地址,而不是直接访问目标HTTPS服务。


注意事项

  • 安全性:在生产环境中,务必使用受信任的SSL证书,避免禁用SSL验证。
  • 证书更新:如果目标服务器的证书发生变更,请及时更新函数计算中的证书文件。
  • 函数计算限制:函数计算环境中的默认信任库可能不包含某些自定义CA证书,因此需要手动处理。

通过上述方法,您可以有效解决函数计算调用HTTPS WSDL接口时的证书验证问题。如果仍有疑问,请提供更多上下文信息以便进一步分析。您可以复制页面截图提供更多信息,我可以进一步帮您分析问题原因。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答

快速交付实现商业价值。

还有其他疑问?
咨询AI助理