我在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)。
答案 0 :(得分:9)
虽然安装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网址(例如java URLGet https://www.google.com/
)以确认Java可以处理SSL。