OpenSSL with Java

我必须在Java Web项目中使用OpenSSL,我对’OpenSSL’一无所知。

如何将OpenSSL与我的项目集成? 有什么好的基础教程可以学习吗?

首先:你需要什么库?

  • 如果要使用简单的加密函数,请使用随JDK部署的Java SE Security组件 。
  • 如果您需要更高级的function(例如某些数字签名格式等),请使用加密库( BouncyCastle是最受欢迎的function之一)
  • 但是,如果您需要从Java代码打开SSL连接,并处理证书身份validation等,您将不需要以下任何一个:
    • 如果您正在使用Java EE容器,则容器可以validation传入的SSL请求:这只是配置问题
    • 此外,如果您需要连接到SSL端口,JDK会提供一些基本类(请参阅此示例 )。 请注意,在这种情况下,您需要在java命令上设置一些系统属性。

喜欢这些属性:

 -Djavax.net.ssl.keyStore=keystore_path -Djavax.net.ssl.keyStorePassword=password -Djavax.net.ssl.trustStore=truststore_path -Djavax.net.ssl.trustStorePassword=trustword 

每个人都在谈论BouncyCastle,但在我们的用例中,Gnu Crypto图书馆赢得了胜利。 原生java。

对于一些客户来说,我们的数据库(aerospike)至少花费了10%的时间计算哈希值,因为这些实现很慢。 我欢迎在每台Linux机器上都有可用的加密库的本机实现。 我认为一些Java7虚拟机将包含更多算法,但我还没有看到它们。

在提出任何建议之前,您需要回答几个重要问题

1)你真的想调用JAVA的C ++(native)实现吗?

2)openssl的哪些function是JCE和Bouncycastle无法解决的

3)范围是否仅限于使用openssl生成的证书,解密openssl生成的文件?

最佳解决方案:将Java的内置安全性用于简单任务,或者使用BouncyCastle用于更高级的任务。

如果你必须从Java使用OpenSSL,你有两个选择:

  1. 将openssl作为Java的进程调用。
  2. 为OpenSSL创建一个JNI层,但这似乎完全浪费了我的时间。 这些都不是真正好的方法。

有许多用于加密的Java本机库。 但是,它们通常与OpenSSL无法完全互操作,有时会明显变慢(请参阅下面网站上的指标),并且并非所有平台都支持。 几乎每个平台都支持OpenSSL,并且通常具有高性能。

话虽这么说,使用基于VM的加密有一些安全优势。 这也应该是一个考虑因素。

Apache组已经构建了一个Java库,它使用JNI访问openssl进行AES加密。 我认为这是使用JNI访问openssl的最佳公共示例,您可以使用maven轻松地引用它。

https://github.com/apache/commons-crypto

如果需要,可以拉出库中的JNI绑定部分并实现所需的function。

这个makefile显示了如何使用javah从.class中获取所需内容以构建.c代码:

https://github.com/apache/commons-crypto/blob/master/Makefile

具体来说,Makefile中的这一行调用javah: $(JAVAH) -force -classpath $(TARGET)/classes -o $@ org.apache.commons.crypto.cipher.OpenSslNative来生成正确的“OpenSslNative.h”文件在OpenSslNative.class上。

https://github.com/apache/commons-crypto/blob/master/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java

注意如何import java.nio.ByteBuffer; 用于允许C输出缓冲区。

相关的.c程序在这里:

https://github.com/apache/commons-crypto/blob/master/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c

它的编写考虑了跨平台支持,是一个很好的例子。 每个导出的函数都必须以JNIEXPORT开头,您可以看到每个函数名中的完整类路径。

我已经看到很多糟糕的JNI绑定,传递字符串等等。从一个坚实的基础开始,在Java中构建良好的OpenSSL集成还有很长的路要走。

Apache Tomcat Native Library是解决方案。 https://github.com/apache/tomcat-native

它使用OpenSSL进行TLS / SSLfunction。 您可以将它用作独立库(就像我一样)或连接您的Tomcat。 它是一个开源项目,具有良好的Java代码。

为什么tomcat原生?

JSSE很慢,很难使用。 在我的项目中,为了获得最佳性能,我们决定为OpenSSL查找/编写JNI包装器,因为在运行中升级证书的可能性是一个问号,而密钥库太复杂了。

由于Bouncy Castle Crypto API是用Java编写的,因此您不能期望获得最佳效率。

Tomcat Native是一个包装器,因此您仅限于OpenSSL版本的function。