当前位置: 首页 > 知识库问答 >
问题:

JavaSSLhandshake_failure如果应用程序构建与jpack

薛鹏飞
2023-03-14

我正在使用jpackage在Mac和PC上分发java应用程序,当它试图从某些站点使用https加载图像时,我的握手失败。如果我在Mac和PC上从Eclipse或命令行运行代码,则代码工作正常,但如果将其作为打包应用程序运行,则代码工作正常。如果我从某些站点加载图像,问题就会消失:https://st4.depositphotos.com例如这让我觉得“问题网站”不在信任链中。

但是,当作为打包应用程序运行时,为什么信任链应该不同呢?

使用java 14.0.2和15可以看到相同的行为。以下示例使用OpenJDK运行时环境(build 15 36-1562)。

请注意,jpack将运行时集成到应用程序中。这是一个非模块化应用程序(我在下面显示了使用的jpack选项)。

在Mac上调试并使用-Djavax。网debug=all选项,我查找打包应用程序正在使用的trustStore。打印路径无效,因为它是以/应用程序而不是/卷开始的,但除此之外,它还可以。也许这只是一个打印问题?不管怎样,我用的是-Djavax。网ssl。信任库=/Library/Java/JavaVirtualMachines/jdk-15。jdk/Contents/Home/lib/security/cacerts强制打包的应用程序使用与jdk相同的信任库,这并没有改善问题。

您认为我的代码有错误还是jpack有问题?非常感谢您的任何帮助!

以下是打包命令:

--verbose \
--type pkg \
--input HelloTest \
--name HelloTest \
--main-class HelloTest.HelloTest \
--main-jar HelloTest.jar \
--runtime-image target/java-runtime \
--java-options -Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts \
--java-options -Djavax.net.debug=all \
--vendor "ACME Inc." \
--copyright "Copyright © 2019-20 ACME Inc." \
--mac-package-identifier com.acme.app \
--mac-package-name ACME

代码如下:

public class HelloTest{

    public static void main(String... args) throws IOException {

        System.out.println("javax.net.ssl.trustStore = " + System.getProperty("javax.net.ssl.trustStore"));
        
        JFrame f = new JFrame(); //creates jframe f
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); //this is your screen size
        int halfWidth = screenSize.width/2;
        int halfHeight = screenSize.height/2;

        ImageIcon img = new ImageIcon();
        //OK: ... https://st4.depositphotos.com seems to be well trusted
        // String urlName = "https://st4.depositphotos.com/36188500/38581/i/1600/depositphotos_385811360-stock-photo-woman-lingerie-dog-rose.jpg";
        //KO: ... https://en.iconda.solutions is only trusted when code is run from Eclipse or the command line
        String urlName = "https://en.iconda.solutions/wp-content/uploads/2020/07/getting_equipped.png";
        
        JLabel lbl = new JLabel();
        URL url;
        
        try {
         url = new URL(urlName);
         HttpsURLConnection httpsConnection = (HttpsURLConnection)url.openConnection();

            try {
                /* The following works from Eclipse and from the command line, but not from an app with an integrated runtime
                 * that was produced using jpackage ... */
                try {
                    
                    img = new ImageIcon(ImageIO.read(httpsConnection.getInputStream())
                            .getScaledInstance(screenSize.width, screenSize.height, Image.SCALE_SMOOTH));
        
                } catch(Exception e) {
                    System.out.println("went wrong #1 for " + urlName);
                    e.printStackTrace();
                }
                
            } catch(Exception e) {
                System.out.println("went wrong #2 for " + urlName);
                e.printStackTrace();
            }
            
        } catch (MalformedURLException e) {
         e.printStackTrace();
        } catch (IOException e) {
         e.printStackTrace();
        }

        lbl.setIcon(img);
        
        f.getContentPane().add(lbl); //puts label inside the jframe
        f.setSize(halfWidth, halfHeight); // set frame size to half of screen ... but need to resize the image
        int x = (screenSize.width - f.getSize().width)/2; //These two lines are the dimensions
        int y = (screenSize.height - f.getSize().height)/2;//of the center of the screen
        f.setLocation(x, y); //sets the location of the jframe
        f.setVisible(true); //makes the jframe visible
    }
    
}

以下是调试输出中的几行:

$ /Applications/HelloTest.app/Contents/MacOS/HelloTest ; exit;
javax.net.ssl.trustStore = /Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:05.852 CEST|null:-1|System property jdk.tls.client.cipherSuites is set to 'null'
…
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.130 CEST|null:-1|trustStore is: /Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts
trustStore type is: pkcs12
trustStore provider is: 
the last modified time is: Wed Aug 12 02:19:32 CEST 2020
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.131 CEST|null:-1|Reload the trust store
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.283 CEST|null:-1|Reload trust certs
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.286 CEST|null:-1|Reloaded 91 trust certs
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.430 CEST|null:-1|adding as trusted certificates (
  "certificate" : {
    "version"            : "v3",
    "serial number"      : "00 A6 8B 79 29 00 00 00 00 50 D0 91 F9",
    "signature algorithm": "SHA384withECDSA",
    "issuer"             : "CN=Entrust Root Certification Authority - EC1, OU="(c) 2012 Entrust, Inc. - for authorized use only", OU=See www.entrust.net/legal-terms, O="Entrust, Inc.", C=US",
…
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.445 CEST|null:-1|keyStore is : 
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.445 CEST|null:-1|keyStore type is : pkcs12
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.445 CEST|null:-1|keyStore provider is : 
javax.net.ssl|ALL|01|main|2020-09-17 07:27:06.445 CEST|null:-1|init keystore
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.446 CEST|null:-1|init keymanager of type SunX509
javax.net.ssl|ALL|01|main|2020-09-17 07:27:06.447 CEST|null:-1|trigger seeding of SecureRandom
javax.net.ssl|ALL|01|main|2020-09-17 07:27:06.449 CEST|null:-1|done seeding of SecureRandom
javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.476 CEST|null:-1|System property jdk.tls.client.SignatureSchemes is set to 'null'
javax.net.ssl|WARNING|01|main|2020-09-17 07:27:06.478 CEST|null:-1|Signature algorithm, ed25519, not supported by JSSE
javax.net.ssl|WARNING|01|main|2020-09-17 07:27:06.479 CEST|null:-1|Signature algorithm, ed448, not supported by JSSE
javax.net.ssl|WARNING|01|main|2020-09-17 07:27:06.480 CEST|null:-1|No AlgorithmParameters for x25519 (
"throwable" : {
  java.security.NoSuchAlgorithmException: Algorithm x25519 not available
    at java.base/javax.crypto.KeyAgreement.getInstance(Unknown Source)
    at java.base/sun.security.ssl.NamedGroup.<init>(Unknown Source)
…
javax.net.ssl|ERROR|01|main|2020-09-17 07:27:09.230 CEST|null:-1|Fatal (HANDSHAKE_FAILURE): Received fatal alert: handshake_failure (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)

下面是关于我的问题的有用评论,下面是一个解决此问题的打包脚本示例:

detected_modules=`jdeps \
  -q \
  --ignore-missing-deps \
  --print-module-deps \
  --class-path "MyApp.jar:../sandbox/jars/*" \
  -recursive MyApp.jar \
    MyApp/MyApp.class`
echo "detected modules: ${detected_modules}"

manual_modules=jdk.crypto.cryptoki
echo "manual modules: ${manual_modules}"

rm -rf ../runtime

jlink \
  --no-header-files \
  --no-man-pages  \
  --compress=2  \
  --strip-debug \
  --add-modules "${detected_modules},${manual_modules}" \
  --output ../runtime

jpackage \
--verbose \
--type pkg \
--input ../sandbox \
--dest ../output \
--name MyApp \
--app-version $1 \
--main-class MyApp.MyApp \ 
--main-jar MyApp.jar \
--runtime-image ../runtime \
--mac-package-name MyApp 

共有1个答案

沈子实
2023-03-14

在网上找到了这个。看起来没有这样的算法错误。

JAVA安全NoSuchAlgorithmException:算法x25519不可用

链接中的解决方案:

需要添加jdk。加密。cryptoki到jlink中的--添加模块列表。

 类似资料:
  • 一个普通的应用程序由以下文件组成: 二进制文件 这个安装在 /usr/bin。 一个桌面文件 这个桌面文件向shell提供关于这个程序的重要信息,例如名称、图标、D-Bus名称,启动的命令行。安装在 /usr/share/applications. 一个图标 这个图标安装在 /usr/share/icons/hicolor/48x48/apps, 无论当前背景是什么系统都会到这里查找图标。 一个设

  • 问题内容: 对于这个问题,我实际上并没有太多的摆动或GUI设计方面的经验(大学中的一些WPF应用程序的水平差不多),但是我的任务是在工作中重构摆动旧式应用程序的一部分。 我被要求重构的部分围绕一个弹出窗口,该窗口可以根据特定的值对象以三种不同的格式显示。这3种不同的格式都共享一些基本字段,然后有条件地确定其他字段。负责此GUI元素的类的长度约为5k,我当时认为应该将其分为三个子类,并在基类中共享这

  • 问题内容: 我正在为NodeJS使用ExpressJS Web框架。 使用ExpressJS的人将他们的环境(开发,生产,测试…),路线等放置在。我认为这不是一个好方法,因为当您拥有大型应用程序时,app.js太大了! 我想要这个目录结构: 这是我的代码: app.js config / environment.js config / routes.js 我的代码运行良好,我认为目录的结构很漂亮。

  • 问题内容: 是否有在 Express.js 应用程序中分解和模块化文件的通用约定?还是将所有内容保存在一个文件中很普遍? 问题答案: 我的分解如下: 我使用Exports返回相关内容。例如,在模型中,我这样做: 然后,如果我需要创建一个电话号码,则非常简单: 如果我需要使用架构,那么 (假设我们正在routes文件夹中工作,需要先上一层然后再下一层模型) 编辑4 该 快递维基 具有建立在它之上的框

  • 目标 了解对象或对象集合如何变成应用程序 使用 Eclipse 创建驱动程序类 应用程序入口点 所有 Java 应用程序都需要一个入口点,让 Java 运行时知道将从这里开始执行代码。这个入口点就是 main() 方法。域对象(即应用程序的业务域 中包含的对象,例如 Person 和 Employee)通常没有 main() 方法,但每个应用程序中必须至少有一个类。 众所周知,Person 和它的

  • 利用一套工具,Qt 开发人员可以简化在所有支持平台中构建应用程序的流程。描述应 用程序、库和插件的项目文件被用来为每个平台生成适当的 makefile。 .pro 文件描述了各个项目,该文件以文本方式概述了源文件、头文件、 Qt Designer 窗体以及其他资源。这些资源都是由 qmake 工具来处理的,以便为每个平台中的项目生成 适当的 Makefile。 项目文件可描述 Qt 的所有库、工具