[英]Why httpclient has a different behavior (SSL-related) on DO droplet?
[英]IllegalStateException thrown by Maven (SSL-related?) when downloading project dependencies
我在ARM机器上设置开发环境,使用以下版本的Java和Maven,都通过apt-get
安装:
(xenial)craig@localhost:~$ mvn -version
Apache Maven 3.3.9
Maven home: /usr/share/maven
Java version: 1.8.0_91, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-openjdk-armhf/jre
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "3.14.0", arch: "arm", family: "unix"
(xenial)craig@localhost:~$ java -version
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-0ubuntu4~16.04.1-b14)
OpenJDK Zero VM (build 25.91-b14, interpreted mode)
但是,当我在我的项目上运行mvn clean install
时,它无法尝试下载确实存在的POM文件。 (我可以在浏览器中访问它。)
堆栈跟踪非常大,但根似乎是:
Caused by: java.lang.IllegalStateException
at sun.security.ec.ECDHKeyAgreement.deriveKey(Native Method)
at sun.security.ec.ECDHKeyAgreement.engineGenerateSecret(ECDHKeyAgreement.java:130)
at sun.security.ec.ECDHKeyAgreement.engineGenerateSecret(ECDHKeyAgreement.java:163)
at javax.crypto.KeyAgreement.generateSecret(KeyAgreement.java:648)
at sun.security.ssl.ECDHCrypt.getAgreedSecret(ECDHCrypt.java:101)
at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:1067)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:348)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)
不幸的是,Maven失败了:
Caused by: org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.jacoco:jacoco-maven-plugin:jar:0.7.6.201602180812
堆栈以deriveKey()
抛出的异常结束。 我在机器上错过了一些加密库吗?
这是Xenial(16.04 LTS)的全新安装。
虽然安装Oracle JRE是一种简单的方法,但以下是您希望特别使用OpenJDK Zero VM的说明,无论是使用Maven,SSL,ECDH密钥协议还是在本机代码中实现的任何其他加密方法。 OpenJDK默认加密提供程序。
我假设ECDHKeyAgreement.deriveKey
方法失败,因为它是一个本机方法,并且在Ubuntu for Raspberry Pi中打包的OpenJDK Zero VM无法处理它; 我没有能力调试那个失败。
Ubuntu打包了用纯Java实现的BouncyCastle加密提供程序。 你需要以通常的方式安装它:
sudo apt install libbcprov-java*
(这也安装了文档)
然后按照/usr/share/doc/libbcprov-java/README.Debian
的说明进行操作,使其成为默认的加密提供程序。 具体来说,你需要从JRE的ext目录链接到提供者jar,所以做一个update-java-alternatives -l
后跟(在我的情况下 - 我一直在使用Ubuntu 16.04 Raspberry Pi中提供的默认值)服务器安装 - 特定的JRE目录可能会及时更改):
sudo ln -s /usr/share/java/bcprov.jar /usr/lib/jvm/java-1.8.0-openjdk-armhf/jre/lib/ext/bcprov.jar
然后编辑/usr/lib/jvm/java-1.8.0-openjdk-armhf/jre/lib/security/java.security
文件(使用sudo
调用编辑器),添加以下行:
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
...列出加密提供程序,并在已存在的加密提供程序的优先级中加1,以使列表看起来类似于:
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=sun.security.ec.SunEC
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
security.provider.6=com.sun.crypto.provider.SunJCE
security.provider.7=sun.security.jgss.SunProvider
security.provider.8=com.sun.security.sasl.Provider
security.provider.9=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.10=sun.security.smartcardio.SunPCSC
Java中的加密现在应该可以工作,尽管速度很慢。 这是一个我用来确认它的示例程序,如果你不想使用Maven:
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
public class URLGet {
public static void main(String[] args) {
try {
URL url = new URL(args[0]);
URLConnection urlConnection = url.openConnection();
try (
InputStream stream = urlConnection.getInputStream();
) {
byte[] buf = new byte[4096];
int read;
while ((read = stream.read(buf, 0, buf.length)) > 0) {
System.out.write(buf, 0, read);
}
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
将其指向任何https URL(例如java URLGet https://www.google.com/
)以确认Java可以处理SSL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.