解决 sun.security.validator.ValidatorException: PKIX path building failed 的问题

错误信息:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:                                                                    PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

问题原因:

源应用程序不信任目标应用程序的证书,因为在源应用程序的JVM信任库中找不到该证书或证书链。


解决办法: 

  • 写一个安全程序专门用于获取安全证书:
/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
import java.io.*;
import java.net.URL;
 
import java.security.*;
import java.security.cert.*;
 
import javax.net.ssl.*;
 
public class InstallCert {
 
    public static void main(String[] args) throws Exception {
    String host;
    int port;
    char[] passphrase;
    if ((args.length == 1) || (args.length == 2)) {
        String[] c = args[0].split(":");
        host = c[0];
        port = (c.length == 1) ? 443 : Integer.parseInt(c[1]);
        String p = (args.length == 1) ? "changeit" : args[1];
        passphrase = p.toCharArray();
    } else {
        System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
        return;
    }
 
    File file = new File("jssecacerts");
    if (file.isFile() == false) {
        char SEP = File.separatorChar;
        File dir = new File(System.getProperty("java.home") + SEP
            + "lib" + SEP + "security");
        file = new File(dir, "jssecacerts");
        if (file.isFile() == false) {
        file = new File(dir, "cacerts");
        }
    }
    System.out.println("Loading KeyStore " + file + "...");
    InputStream in = new FileInputStream(file);
    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    ks.load(in, passphrase);
    in.close();
 
    SSLContext context = SSLContext.getInstance("TLS");
    TrustManagerFactory tmf =
        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
    SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
    context.init(null, new TrustManager[] {tm}, null);
    SSLSocketFactory factory = context.getSocketFactory();
 
    System.out.println("Opening connection to " + host + ":" + port + "...");
    SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
    socket.setSoTimeout(10000);
    try {
        System.out.println("Starting SSL handshake...");
        socket.startHandshake();
        socket.close();
        System.out.println();
        System.out.println("No errors, certificate is already trusted");
    } catch (SSLException e) {
        System.out.println();
        e.printStackTrace(System.out);
    }
 
    X509Certificate[] chain = tm.chain;
    if (chain == null) {
        System.out.println("Could not obtain server certificate chain");
        return;
    }
 
    BufferedReader reader =
        new BufferedReader(new InputStreamReader(System.in));
 
    System.out.println();
    System.out.println("Server sent " + chain.length + " certificate(s):");
    System.out.println();
    MessageDigest sha1 = MessageDigest.getInstance("SHA1");
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    for (int i = 0; i < chain.length; i++) {
        X509Certificate cert = chain[i];
        System.out.println
            (" " + (i + 1) + " Subject " + cert.getSubjectDN());
        System.out.println("   Issuer  " + cert.getIssuerDN());
        sha1.update(cert.getEncoded());
        System.out.println("   sha1    " + toHexString(sha1.digest()));
        md5.update(cert.getEncoded());
        System.out.println("   md5     " + toHexString(md5.digest()));
        System.out.println();
    }
 
    System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
    String line = reader.readLine().trim();
    int k;
    try {
        k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1;
    } catch (NumberFormatException e) {
        System.out.println("KeyStore not changed");
        return;
    }
 
    X509Certificate cert = chain[k];
    String alias = host + "-" + (k + 1);
    ks.setCertificateEntry(alias, cert);
 
    OutputStream out = new FileOutputStream("jssecacerts");
    ks.store(out, passphrase);
    out.close();
 
    System.out.println();
    System.out.println(cert);
    System.out.println();
    System.out.println
        ("Added certificate to keystore 'jssecacerts' using alias '"
        + alias + "'");
    }
 
    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();
 
    private static String toHexString(byte[] bytes) {
    StringBuilder sb = new StringBuilder(bytes.length * 3);
    for (int b : bytes) {
        b &= 0xff;
        sb.append(HEXDIGITS[b >> 4]);
        sb.append(HEXDIGITS[b & 15]);
        sb.append(' ');
    }
    return sb.toString();
    }
 
    private static class SavingTrustManager implements X509TrustManager {
 
    private final X509TrustManager tm;
    private X509Certificate[] chain;
 
    SavingTrustManager(X509TrustManager tm) {
        this.tm = tm;
    }
 
    public X509Certificate[] getAcceptedIssuers() {
        throw new UnsupportedOperationException();
    }
 
    public void checkClientTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
        throw new UnsupportedOperationException();
    }
 
    public void checkServerTrusted(X509Certificate[] chain, String authType)
        throws CertificateException {
        this.chain = chain;
        tm.checkServerTrusted(chain, authType);
    }
    }
 
}
  • 将代码保存为InstallCert.java文件,并通过javac InstallCert.java 命令编译Java程序
  • 执行 java InstallCert hostname 命令,如:java InstallCert 192.168.1.137:8443(要访问的目标程序的IP地址和端口),然后会看到如下信息:
java InstallCert ecc.fedora.redhat.com
Loading KeyStore /usr/jdk/instances/jdk1.5.0/jre/lib/security/cacerts...
Opening connection to ecc.fedora.redhat.com:443...
Starting SSL handshake...
 
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1476)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:846)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:815)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1025)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1038)
at InstallCert.main(InstallCert.java:63)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:221)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:145)
at sun.security.validator.Validator.validate(Validator.java:203)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
at InstallCert$SavingTrustManager.checkServerTrusted(InstallCert.java:158)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:839)
... 7 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:236)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:194)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:216)
... 13 more
 
Server sent 2 certificate(s):
 
1 Subject CN=ecc.fedora.redhat.com, O=example.com, C=US
   Issuer CN=Certificate Shack, O=example.com, C=US
   sha1    2e 7f 76 9b 52 91 09 2e 5d 8f 6b 61 39 2d 5e 06 e4 d8 e9 c7
   md5     dd d1 a8 03 d7 6c 4b 11 a7 3d 74 28 89 d0 67 54
 
2 Subject CN=Certificate Shack, O=example.com, C=US
   Issuer CN=Certificate Shack, O=example.com, C=US
   sha1    fb 58 a7 03 c4 4e 3b 0e e3 2c 40 2f 87 64 13 4d df e1 a1 a6
   md5     72 a0 95 43 7e 41 88 18 ae 2f 6d 98 01 2c 89 68
 
Enter certificate to add to trusted keystore or 'q' to quit: [1]

  • (如果报错,则换个电脑生成,直接copy过来就行)
  •  直接输入1,然后会在相应的目录下产生一个名为‘jssecacerts’的证书,将证书copy到$JAVA_HOME/jre/lib/security目录下,或者通过执行:
System.setProperty("javax.net.ssl.trustStore","D:\\UTA\\DOC_E_Health_XML\\Keystore\\jssecacerts")

<think>好的,我现在需要解决用户的问题,即如何通过批处理(.bat)脚本来删除或清理HEX文件中多余的FF填充数据。首先,我要回忆一下之前用户提供的引用内容,看看有没有相关的信息。 用户提到使用Vector的HexView工具,并且引用[3]和[4]都涉及到使用HexView的命令行接口来处理HEX文件。特别是引用[4]中提到了剪切数据的功能,使用/CR参数来移除特定地址范围的数据。但用户现在的问题是要删除连续的FF填充数据,而不是某个固定地址范围的数据。所以可能需要更灵活的方法。 HexView工具是否有检测连续FF并删除的功能呢?我需要查阅一下HexView的文档或者用户提供的引用。引用[3]提到HexView支持增删改查HEX文件,并且有填充的功能。可能填充是用特定的值填充,但如何删除已有的填充呢? 用户之前的问题中,引用[4]中的/CR参数是剪切指定地址范围的数据,但需要知道具体的地址范围。如果FF填充分布在不同的地址段,可能需要先识别这些地址,然后逐一剪切。但手动指定每个地址范围不现实,尤其是当文件较大时。 或许可以结合HexView的其他功能,比如查找连续FF的区域,并生成对应的地址范围,再用/CR参数处理。不过,目前引用的内容中没有提到HexView是否有自动检测连续FF的功能。因此,可能需要编写一个脚本,先解析HEX文件,找到所有连续FF的地址范围,然后生成对应的HexView命令进行剪切。 不过,这样的脚本可能会比较复杂,需要解析HEX文件的格式,识别连续的FF数据块。可能超出了批处理脚本的能力范围,需要借助其他工具或者HexView自身的功能。 或者,是否有HexView的命令可以直接删除所有连续的FF数据?例如,使用某种替换功能,将连续超过一定长度的FF替换为空。但引用中并没有提到这样的功能,可能需要查看HexView的文档。 另一个思路是,如果这些FF填充位于文件的末尾或者特定的未使用区域,可以通过指定地址范围来删除。例如,假设从地址0x1000到0x1FFF都是FF,那么可以用/CR参数剪切这个范围。但用户的问题可能是指任意位置的连续FF,而不仅仅是特定区域。 在这种情况下,可能需要分步骤处理:首先使用HexView将HEX文件转换为二进制(BIN),然后用其他工具处理BIN文件,删除连续的FF,再转换回HEX。但用户希望用.bat脚本集成HexView,所以可能需要HexView本身的功能。 或者,用户提到的引用[5]中的签名和加密功能可能不相关,但引用[3]中的填充操作可能相关,例如,填充时可以用特定值填充,但如何删除已有的填充呢? 可能需要进一步分析HexView的命令行参数。根据引用[4],/CR参数可以剪切指定的地址范围,但需要知道这些地址范围。因此,解决方案可能需要先用HexView生成一个地址范围列表,然后逐一剪切。 或者,是否存在HexView的选项可以直接删除所有连续的FF数据?例如,使用类似“删除所有连续的FF超过N字节”的功能。如果HexView支持正则表达式或模式匹配,可能可以实现。但根据现有引用,没有明确提到这样的功能。 因此,可能的步骤是: 1. 使用HexView将HEX文件转换为二进制(BIN)文件。 2. 使用其他工具或自定义脚本处理BIN文件,识别并删除连续的FF数据块。 3. 将处理后的BIN文件转换回HEX格式。 但用户希望全部通过批处理脚本和HexView完成,可能需要HexView本身支持这样的操作。假设HexView没有直接支持,可能需要结合其他工具,如使用Python或PowerShell脚本处理BIN文件,再在.bat中调用这些脚本。 不过,用户明确要求使用.bat脚本,所以可能需要寻找纯HexView的方法。或者,是否有HexView的命令可以逐段检查并删除连续的FF? 另一个可能的方法是使用HexView的填充功能,将特定的地址范围填充为空白(即删除),但需要先确定哪些地址范围是连续的FF。这又回到了如何确定这些地址的问题。 总结来说,可能的解决方案步骤: 1. 解析原始HEX文件,找到所有连续FF的地址范围。 2. 生成对应的HexView命令,使用/CR参数剪切这些地址范围。 3. 执行HexView命令处理HEX文件。 但如何解析HEX文件并找到连续FF的地址范围呢?这可能需要编写额外的脚本,或者使用HexView本身的某些功能。例如,HexView是否有导出数据为某个格式,可以分析数据内容? 如果没有,可能需要分两步: a. 使用HexView的导出功能将HEX文件转换为二进制BIN文件。 b. 分析BIN文件,找到所有连续FF的区域的起始和结束地址。 c. 将这些地址范围作为参数传递给HexView的/CR命令,剪切这些区域。 但这个过程需要额外的工具来分析BIN文件,可能超出了批处理脚本的能力,需要借助其他编程语言如Python。不过用户可能希望仅使用批处理和HexView。 如果HexView可以输出文件的地址范围和数据,可能可以编写一个批处理脚本来处理输出,识别连续FF的区域。例如,HexView是否有命令可以按地址输出数据,然后批处理脚本逐行分析,记录连续FF的起始和结束地址。 不过,这可能比较复杂,尤其是处理大文件时。此外,批处理脚本处理二进制数据可能不太方便,可能需要HexView提供某种文本格式的输出。 另一种可能:HexView的某个命令可以直接删除所有连续的FF数据。例如,使用替换命令将连续的FF替换为空,但需要确保替换操作不会破坏文件结构。但根据现有引用,没有提到这样的功能。 综上所述,最可行的办法可能是结合HexView的剪切命令和外部脚本分析HEX文件,生成需要剪切的地址范围列表,然后在批处理脚本中调用HexView进行处理。 不过,由于用户可能没有其他工具,只能使用HexView和批处理脚本,可能需要另一种方式。例如,如果HexView支持脚本输入,可以编写一个HexView脚本文件,其中包含多个/CR命令来剪切所有连续FF的区域。 因此,最终的步骤可能如下: 1. 使用HexView将HEX文件转换为二进制(BIN)文件。 2. 使用自定义脚本(如Python)分析BIN文件,找出所有连续FF的地址范围。 3. 生成一个包含多个/CR参数的HexView命令,剪切这些地址范围。 4. 执行HexView命令处理原始HEX文件,生成清理后的HEX文件。 但用户可能希望整个过程在.bat中完成,无需其他脚本语言。这时候,可能需要寻找HexView自身的功能来识别这些区域,或者接受手动指定地址范围。 如果用户知道需要删除的地址范围,可以直接在批处理脚本中使用HexView的/CR参数。例如: ``` hexview.exe /CR:0x1000-0x1FFF input.hex output.hex ``` 但如果不知道具体地址,就需要自动化识别。这时候可能需要结合其他工具,或者HexView的某些高级功能。 假设用户无法使用其他工具,只能使用HexView和批处理脚本,可能的解决方案是: - 编写一个批处理脚本,调用HexView多次,每次处理一个地址范围,但这些地址范围需要提前确定。 因此,可能无法完全自动化,除非HexView有某种检测功能。 经过上述思考,可能的结论是:使用HexView的剪切命令,但需要知道具体的地址范围。如果用户无法提供这些地址范围,就需要其他工具辅助分析HEX文件,找到连续FF的区域,然后生成对应的HexView命令。 因此,在回答中需要说明这个步骤,并给出示例脚本,结合HexView和可能的其他工具(如PowerShell或Python)来识别地址范围,然后调用HexView进行处理。如果用户只能使用HexView和批处理,可能需要手动处理,或者建议使用HexView的其他功能。</think>通过Vector HexView工具的命令行功能,可以使用以下步骤实现HEX文件连续FF数据的清理: 1. **识别有效数据范围** 使用HexView的地址范围分析功能,结合/CR剪切参数清理无效区域。假设有效数据范围为0x1000-0x7FFF,其余区域为FF填充: ```bat hexview.exe input.hex /CR:0x0-0xFFF /CR:0x8000-0xFFFF /OUT:output.hex ``` 2. **动态检测填充区域(需自定义逻辑)** 若需自动化检测连续FF区域,需编写辅助脚本生成地址范围列表。例如使用Python解析HEX文件后生成批处理命令: ```python # find_ff_ranges.py 示例代码 with open("input.hex", "rb") as f: data = f.read() # 检测连续FF的逻辑(伪代码) ranges = detect_ff_ranges(data) with open("cut_commands.bat", "w") as bat: bat.write("hexview.exe input.hex " + " ".join([f"/CR:{r}" for r in ranges]) + " /OUT:output.hex") ``` 3. **集成到批处理脚本** 将上述逻辑封装为可执行流程: ```bat @echo off :: Step1: 转换HEX为BIN以便分析 hexview.exe input.hex /BIN:temp.bin :: Step2: 调用Python脚本检测连续FF区域 python find_ff_ranges.py :: Step3: 执行生成的剪切命令 call cut_commands.bat :: 清理临时文件 del temp.bin ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值