Java应用程序使用jpackage构建后出现SSL握手失败问题。

huangapple go评论92阅读模式
英文:

Java SSL handshake_failure if app built with jpackage

问题

我正在使用jpackage在Mac和PC上分发Java应用程序,但是当尝试从某些站点使用https加载图像时,出现了握手失败(handshake_failure)的问题。如果我从Eclipse或命令行上运行代码,无论是在Mac还是PC上,都能正常工作,但是打包成应用程序后就不行了。

如果我从某些站点加载图像(例如https://st4.depositphotos.com),问题就会消失。这使我认为“有问题的站点”不在信任链中。

但是为什么运行打包的应用程序时,信任链会有所不同呢?

使用Java 14.0.2和15时,看到了相同的行为。以下示例使用OpenJDK Runtime Environment(版本15+36-1562)。

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

在Mac上进行调试,并使用-Djavax.net.debug=all选项,我查找了打包的应用程序使用的trustStore。打印的路径无效,因为它以/Applications开头,而不是/Volumes,但除此之外还可以。也许这只是一个打印问题?无论如何,我使用了-Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts来强制打包的应用程序使用与JDK相同的trustStore,但情况没有改善。

您认为我的代码有问题还是jpackage存在问题?非常感谢您的帮助!

以下是打包命令:

  1. --verbose \
  2. --type pkg \
  3. --input HelloTest \
  4. --name HelloTest \
  5. --main-class HelloTest.HelloTest \
  6. --main-jar HelloTest.jar \
  7. --runtime-image target/java-runtime \
  8. --java-options -Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts \
  9. --java-options -Djavax.net.debug=all \
  10. --vendor "ACME Inc." \
  11. --copyright "Copyright © 2019-20 ACME Inc." \
  12. --mac-package-identifier com.acme.app \
  13. --mac-package-name ACME

以下是代码:

  1. public class HelloTest{
  2. public static void main(String... args) throws IOException {
  3. System.out.println("javax.net.ssl.trustStore = " + System.getProperty("javax.net.ssl.trustStore"));
  4. JFrame f = new JFrame(); //creates jframe f
  5. Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); //this is your screen size
  6. int halfWidth = screenSize.width/2;
  7. int halfHeight = screenSize.height/2;
  8. ImageIcon img = new ImageIcon();
  9. //OK: ... https://st4.depositphotos.com seems to be well trusted
  10. // String urlName = "https://st4.depositphotos.com/36188500/38581/i/1600/depositphotos_385811360-stock-photo-woman-lingerie-dog-rose.jpg";
  11. //KO: ... https://en.iconda.solutions is only trusted when code is run from Eclipse or the command line
  12. String urlName = "https://en.iconda.solutions/wp-content/uploads/2020/07/getting_equipped.png";
  13. JLabel lbl = new JLabel();
  14. URL url;
  15. try {
  16. url = new URL(urlName);
  17. HttpsURLConnection httpsConnection = (HttpsURLConnection)url.openConnection();
  18. try {
  19. /* The following works from Eclipse and from the command line, but not from an app with an integrated runtime
  20. * that was produced using jpackage ... */
  21. try {
  22. img = new ImageIcon(ImageIO.read(httpsConnection.getInputStream())
  23. .getScaledInstance(screenSize.width, screenSize.height, Image.SCALE_SMOOTH));
  24. } catch(Exception e) {
  25. System.out.println("went wrong #1 for " + urlName);
  26. e.printStackTrace();
  27. }
  28. } catch(Exception e) {
  29. System.out.println("went wrong #2 for " + urlName);
  30. e.printStackTrace();
  31. }
  32. } catch (MalformedURLException e) {
  33. e.printStackTrace();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. lbl.setIcon(img);
  38. f.getContentPane().add(lbl); //puts label inside the jframe
  39. f.setSize(halfWidth, halfHeight); // set frame size to half of screen ... but need to resize the image
  40. int x = (screenSize.width - f.getSize().width)/2; //These two lines are the dimensions
  41. int y = (screenSize.height - f.getSize().height)/2;//of the center of the screen
  42. f.setLocation(x, y); //sets the location of the jframe
  43. f.setVisible(true); //makes the jframe visible
  44. }
  45. }

以下是调试输出的部分内容:

  1. $ /Applications/HelloTest.app/Contents/MacOS/HelloTest ; exit;
  2. javax.net.ssl.trustStore = /Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts
  3. 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'
  4. 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
  5. trustStore type is: pkcs12
  6. trustStore provider is:
  7. the last modified time is: Wed Aug 12 02:19:32 CEST 2020
  8. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.131 CEST|null:-1|Reload the trust store
  9. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.283 CEST|null:-1|Reload trust certs
  10. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.286 CEST|null:-1|Reloaded 91 trust certs
  11. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.430 CEST|null:-1|adding as trusted certificates (
  12. "certificate" : {
  13. "version" : "v3",
  14. "serial number" : "00 A6 8B 79 29 00 00 00 00 50 D0 91 F9",
  15. "signature algorithm": "SHA384withECDSA",
  16. "issuer" : "CN=Entrust Root Certification Authority - EC1, OU=\"(c) 2012 Entrust
  17. <details>
  18. <summary>英文:</summary>
  19. I am using jpackage to distribute a java app on Mac and PC and I have a handshake_failure when it tries to load an image using https from certain sites. The code works fine if I run it from Eclipse or from the command line, both on Mac and PC, but not if run it as a packaged app.
  20. The problem goes away if I load an image from certain sites: https://st4.depositphotos.com, for example. This makes me think that the “problem sites” are not in the chain of trust.
  21. But why should the chain of trust be different when running as a packaged app?
  22. The same behaviour is seen using java 14.0.2 and 15. The following example uses OpenJDK Runtime Environment (build 15+36-1562).
  23. Note that jpackage integrates a runtime into the app. This is a non-modular app (I show the jpackage options used below).
  24. Debugging on the Mac and using the -Djavax.net.debug=all option, I looked for the trustStore being used by the packaged app. The printed path was invalid as it started with /Applications, rather than /Volumes, but apart from that it was ok. Maybe this was just a printing problem? Either way, I used -Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts to force the packaged app to use the same trustStore as the JDK and this didn’t improve matters.
  25. Do you think that my code is buggy or is there a problem in jpackage? Many thanks for any help!
  26. Here is the packaging command:
  27. ```jpackage \
  28. --verbose \
  29. --type pkg \
  30. --input HelloTest \
  31. --name HelloTest \
  32. --main-class HelloTest.HelloTest \
  33. --main-jar HelloTest.jar \
  34. --runtime-image target/java-runtime \
  35. --java-options -Djavax.net.ssl.trustStore=/Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts \
  36. --java-options -Djavax.net.debug=all \
  37. --vendor &quot;ACME Inc.&quot; \
  38. --copyright &quot;Copyright &#169; 2019-20 ACME Inc.&quot; \
  39. --mac-package-identifier com.acme.app \
  40. --mac-package-name ACME

Here is the code:

  1. public class HelloTest{
  2. public static void main(String... args) throws IOException {
  3. System.out.println(&quot;javax.net.ssl.trustStore = &quot; + System.getProperty(&quot;javax.net.ssl.trustStore&quot;));
  4. JFrame f = new JFrame(); //creates jframe f
  5. Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); //this is your screen size
  6. int halfWidth = screenSize.width/2;
  7. int halfHeight = screenSize.height/2;
  8. ImageIcon img = new ImageIcon();
  9. //OK: ... https://st4.depositphotos.com seems to be well trusted
  10. // String urlName = &quot;https://st4.depositphotos.com/36188500/38581/i/1600/depositphotos_385811360-stock-photo-woman-lingerie-dog-rose.jpg&quot;;
  11. //KO: ... https://en.iconda.solutions is only trusted when code is run from Eclipse or the command line
  12. String urlName = &quot;https://en.iconda.solutions/wp-content/uploads/2020/07/getting_equipped.png&quot;;
  13. JLabel lbl = new JLabel();
  14. URL url;
  15. try {
  16. url = new URL(urlName);
  17. HttpsURLConnection httpsConnection = (HttpsURLConnection)url.openConnection();
  18. try {
  19. /* The following works from Eclipse and from the command line, but not from an app with an integrated runtime
  20. * that was produced using jpackage ... */
  21. try {
  22. img = new ImageIcon(ImageIO.read(httpsConnection.getInputStream())
  23. .getScaledInstance(screenSize.width, screenSize.height, Image.SCALE_SMOOTH));
  24. } catch(Exception e) {
  25. System.out.println(&quot;went wrong #1 for &quot; + urlName);
  26. e.printStackTrace();
  27. }
  28. } catch(Exception e) {
  29. System.out.println(&quot;went wrong #2 for &quot; + urlName);
  30. e.printStackTrace();
  31. }
  32. } catch (MalformedURLException e) {
  33. e.printStackTrace();
  34. } catch (IOException e) {
  35. e.printStackTrace();
  36. }
  37. lbl.setIcon(img);
  38. f.getContentPane().add(lbl); //puts label inside the jframe
  39. f.setSize(halfWidth, halfHeight); // set frame size to half of screen ... but need to resize the image
  40. int x = (screenSize.width - f.getSize().width)/2; //These two lines are the dimensions
  41. int y = (screenSize.height - f.getSize().height)/2;//of the center of the screen
  42. f.setLocation(x, y); //sets the location of the jframe
  43. f.setVisible(true); //makes the jframe visible
  44. }
  45. }

And here are a few lines from the debug output:

  1. $ /Applications/HelloTest.app/Contents/MacOS/HelloTest ; exit;
  2. javax.net.ssl.trustStore = /Library/Java/JavaVirtualMachines/jdk-15.jdk/Contents/Home/lib/security/cacerts
  3. 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 &#39;null&#39;
  4. 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
  5. trustStore type is: pkcs12
  6. trustStore provider is:
  7. the last modified time is: Wed Aug 12 02:19:32 CEST 2020
  8. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.131 CEST|null:-1|Reload the trust store
  9. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.283 CEST|null:-1|Reload trust certs
  10. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.286 CEST|null:-1|Reloaded 91 trust certs
  11. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.430 CEST|null:-1|adding as trusted certificates (
  12. &quot;certificate&quot; : {
  13. &quot;version&quot; : &quot;v3&quot;,
  14. &quot;serial number&quot; : &quot;00 A6 8B 79 29 00 00 00 00 50 D0 91 F9&quot;,
  15. &quot;signature algorithm&quot;: &quot;SHA384withECDSA&quot;,
  16. &quot;issuer&quot; : &quot;CN=Entrust Root Certification Authority - EC1, OU=&quot;(c) 2012 Entrust, Inc. - for authorized use only&quot;, OU=See www.entrust.net/legal-terms, O=&quot;Entrust, Inc.&quot;, C=US&quot;,
  17. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.445 CEST|null:-1|keyStore is :
  18. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.445 CEST|null:-1|keyStore type is : pkcs12
  19. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.445 CEST|null:-1|keyStore provider is :
  20. javax.net.ssl|ALL|01|main|2020-09-17 07:27:06.445 CEST|null:-1|init keystore
  21. javax.net.ssl|DEBUG|01|main|2020-09-17 07:27:06.446 CEST|null:-1|init keymanager of type SunX509
  22. javax.net.ssl|ALL|01|main|2020-09-17 07:27:06.447 CEST|null:-1|trigger seeding of SecureRandom
  23. javax.net.ssl|ALL|01|main|2020-09-17 07:27:06.449 CEST|null:-1|done seeding of SecureRandom
  24. 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 &#39;null&#39;
  25. javax.net.ssl|WARNING|01|main|2020-09-17 07:27:06.478 CEST|null:-1|Signature algorithm, ed25519, not supported by JSSE
  26. javax.net.ssl|WARNING|01|main|2020-09-17 07:27:06.479 CEST|null:-1|Signature algorithm, ed448, not supported by JSSE
  27. javax.net.ssl|WARNING|01|main|2020-09-17 07:27:06.480 CEST|null:-1|No AlgorithmParameters for x25519 (
  28. &quot;throwable&quot; : {
  29. java.security.NoSuchAlgorithmException: Algorithm x25519 not available
  30. at java.base/javax.crypto.KeyAgreement.getInstance(Unknown Source)
  31. at java.base/sun.security.ssl.NamedGroup.&lt;init&gt;(Unknown Source)
  32. javax.net.ssl|ERROR|01|main|2020-09-17 07:27:09.230 CEST|null:-1|Fatal (HANDSHAKE_FAILURE): Received fatal alert: handshake_failure (
  33. &quot;throwable&quot; : {
  34. javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
  35. at java.base/sun.security.ssl.Alert.createSSLException(Unknown Source)

Following the helpful comments on my question, here is an example packaging script that solves the issue:

  1. detected_modules=`jdeps \
  2. -q \
  3. --ignore-missing-deps \
  4. --print-module-deps \
  5. --class-path &quot;MyApp.jar:../sandbox/jars/*&quot; \
  6. -recursive MyApp.jar \
  7. MyApp/MyApp.class`
  8. echo &quot;detected modules: ${detected_modules}&quot;
  9. manual_modules=jdk.crypto.cryptoki
  10. echo &quot;manual modules: ${manual_modules}&quot;
  11. rm -rf ../runtime
  12. jlink \
  13. --no-header-files \
  14. --no-man-pages \
  15. --compress=2 \
  16. --strip-debug \
  17. --add-modules &quot;${detected_modules},${manual_modules}&quot; \
  18. --output ../runtime
  19. jpackage \
  20. --verbose \
  21. --type pkg \
  22. --input ../sandbox \
  23. --dest ../output \
  24. --name MyApp \
  25. --app-version $1 \
  26. --main-class MyApp.MyApp \
  27. --main-jar MyApp.jar \
  28. --runtime-image ../runtime \
  29. --mac-package-name MyApp

答案1

得分: 4

在互联网上找到了这个。从外观上看,出现了相同的“no such algorithm”错误。

链接:https://stackoverflow.com/questions/62238883/java-security-nosuchalgorithmexception-algorithm-x25519-not-available

链接中的解决方法:

需要将jdk.crypto.cryptoki添加到jlink的--add-modules列表中。

英文:

Found this on the Interwebs. Same no such algorithm error from the looks of it.

https://stackoverflow.com/questions/62238883/java-security-nosuchalgorithmexception-algorithm-x25519-not-available

The solution from the link:

Need to add jdk.crypto.cryptoki to the --add-modules list in jlink.

huangapple
  • 本文由 发表于 2020年9月17日 14:11:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63932217.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定