Ubuntu 22.04 安装 Apache Commons Crypto 指南
在 Ubuntu 22.04 服务器上从零搭建 Apache Commons Crypto 1.2.0 可用环境:JDK 17 与 Maven 安装、Maven 依赖与官方发行包两种获取方案、sha512 校验与最小验证代码实测。
Ubuntu 22.04 安装 Apache Commons Crypto 指南
目标:在 Ubuntu 22.04 服务器上从零搭建可编译、可运行 Apache Commons Crypto 1.2.0 的环境,覆盖 JDK 17 与 Maven 安装、两种 jar 获取方案、sha512 校验与最小验证代码,全部步骤已在 Ubuntu 22.04 / CentOS 8(JDK 17 + Maven)实测通过。
一、环境信息
本章先确认操作系统与基础软件版本,后续所有命令与回显均来自该环境。安装开始前,请先核对服务器系统版本:
grep PRETTY_NAME /etc/os-release && uname -r
回显(实测):
PRETTY_NAME="Ubuntu 22.04.5 LTS"
6.8.0-138-generic
本文使用的环境基准如下:
| 项目 | 内容 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| 内核 | 6.8.0-138-generic |
| JDK | OpenJDK 17.0.20.1(apt 仓库 openjdk-17-jdk) |
| 构建工具 | Apache Maven 3.6.3 |
| OpenSSL | 3.0.2 15 Mar 2022(系统默认 libcrypto.so.3) |
| 组件版本 | Apache Commons Crypto 1.2.0 |
表中 OpenSSL 版本是后续理解「加解密实现走 OpenSSL 还是回退 JCE」的关键:Ubuntu 22.04 自带 OpenSSL 3.0,而 Commons Crypto 1.2.0 的 JNI 代码在 OpenSSL 3.0 下只能部分工作,详见第八章 FAQ。
1.1 安装 JDK 17 与 Maven
Ubuntu 22.04 官方仓库直接提供 OpenJDK 17 与 Maven,一条命令完成安装:
apt update && apt install -y openjdk-17-jdk maven
安装完成后验证版本:
java -version
回显(实测):
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
mvn -version
回显(实测):
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"
注意 Default locale: en_US, platform encoding: ANSI_X3.4-1968:POSIX locale 下 javac 默认按 ASCII 读取源码,编译含中文注释的源文件时必须显式加 -encoding UTF-8,否则报 unmappable character 错误(见 FAQ Q4)。
1.2 确认 OpenSSL 运行库
Commons Crypto 的 native 加密路径依赖系统的 OpenSSL 动态库。先查看版本与已注册的 libcrypto:
openssl version
回显(实测):
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
ldconfig -p | grep libcrypto
回显(实测):
libcrypto.so.3 (libc6,x86-64) => /lib/x86_64-linux-gnu/libcrypto.so.3
仅安装服务器基础系统时,通常只有带版本号的 libcrypto.so.3。Commons Crypto 的 JNI 胶水库在运行时会尝试 dlopen 未带版本号的 libcrypto.so,因此建议补装开发包以生成该符号链接:
apt install -y libssl-dev
ldconfig -p | grep "libcrypto.so "
回显(实测):
libcrypto.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libcrypto.so
二、版本选型
选型前先明确两件事:JDK 版本要求,以及 native 库支持哪些平台。以下信息全部来自对 1.2.0 发行物的实测检查。
2.1 版本清单
| 版本 | 状态 | JDK 要求 | 说明 |
|---|---|---|---|
| 1.2.0 | 当前最新稳定版 | Java 8 及以上 | 2022-12-30 发布;实测 jar 内 class 文件 major version 为 52(即 Java 8 字节码),可在 JDK 8 至 17 上运行 |
| 1.1.0 | 旧稳定版 | Java 8 及以上 | 历史版本,可从 Apache 归档站点获取 |
| 1.0.0 | 旧稳定版 | Java 7 及以上 | 首个正式版,不建议新项目使用 |
选型建议:新项目直接使用 1.2.0。它同时是 Maven 中央仓库与 downloads.apache.org 上的最新版本,本文全部示例均基于 1.2.0。
💡 技术拓展:Commons Crypto 获取原生加解密能力有三条实现路径——JCE(JVM 自带软件实现,依赖 JVM 对 AES-NI 指令的优化)、OpenSSL JNI(jar 内自带各平台 JNI 胶水库,调用系统 OpenSSL 的 libcrypto)、JNA(通过 JNA 库调用 OpenSSL,无需编译 JNI,但吞吐较低,1.2.0 的 pom 中 jna 是编译期依赖,运行时作为可选路径)。本文环境实测:随机数走 OpenSSL JNI 路径成功,加密在 OpenSSL 3.0 下因 JNI 符号缺失自动回退 JCE(详见 FAQ Q2)。
2.2 native 支持平台
1.2.0 的 jar 内自带多平台 JNI 胶水库(jar tf 实测清单):
| 平台 | 内嵌库路径(jar 内) |
|---|---|
| Linux x86_64 | org/apache/commons/crypto/native/Linux/x86_64/libcommons-crypto.so |
| Linux aarch64 | org/apache/commons/crypto/native/Linux/aarch64/libcommons-crypto.so |
| Linux arm | org/apache/commons/crypto/native/Linux/arm/libcommons-crypto.so |
| Linux armhf | org/apache/commons/crypto/native/Linux/armhf/libcommons-crypto.so |
| macOS x86_64 | org/apache/commons/crypto/native/Mac/x86_64/libcommons-crypto.jnilib |
| Windows x86 | org/apache/commons/crypto/native/Windows/x86/commons-crypto.dll |
| Windows x86_64 | org/apache/commons/crypto/native/Windows/x86_64/commons-crypto.dll |
逐项说明:x86_64 Linux 服务器是本文环境;aarch64 适用于国产化 ARM 服务器;胶水库只是「JNI 桥」,运行时仍需系统提供 libcrypto(OpenSSL),jar 并不内嵌 OpenSSL 本体。
三、方案A:Maven 中央仓库依赖
方案A适合所有使用 Maven 的工程:在 pom 中声明依赖即可,无需手工管理 jar。Maven 坐标为 org.apache.commons:commons-crypto:1.2.0。
3.1 创建工程与 pom
mkdir -p /opt/install-demo/src/main/java/demo
创建 /opt/install-demo/pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>crypto-quickstart</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-crypto</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</project>
逐项说明:maven.compiler.source/target 设为 17 与本环境 JDK 匹配;project.build.sourceEncoding 强制 UTF-8,规避 POSIX locale 下的编译编码问题;依赖坐标只有 commons-crypto 一项。
3.2 编译并查看真实依赖树
cd /opt/install-demo && mvn -q compile && echo BUILD_OK
回显(实测):
BUILD_OK
mvn dependency:tree
回显(实测,节选):
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ crypto-quickstart ---
[INFO] demo:crypto-quickstart:jar:1.0.0
[INFO] \- org.apache.commons:commons-crypto:jar:1.2.0:compile
[INFO] +- net.java.dev.jna:jna:jar:5.13.0:compile
[INFO] \- com.sun.xml.bind:jaxb-impl:jar:2.3.7:compile
[INFO] +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:compile
[INFO] \- com.sun.activation:jakarta.activation:jar:1.2.2:runtime
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
依赖树解读:commons-crypto 1.2.0 的传递依赖只有 jna 5.13.0(对应可选 JNA 路径)与 jaxb-impl 2.3.7(来自 pom 中 JDK 11 及以上激活的 profile,用于在 JDK 11+ 上补齐 JAXB);jaxb-impl 再带入 jakarta.xml.bind-api 2.3.3 与 jakarta.activation 1.2.2。总体非常轻量,无冲突风险。
3.3 最小验证代码
将以下内容保存为 /opt/install-demo/src/main/java/EnvCheck.java,打印组件版本、native 加载状态、各变换实际选用的实现类:
import org.apache.commons.crypto.Crypto;
import org.apache.commons.crypto.cipher.CryptoCipher;
import org.apache.commons.crypto.cipher.CryptoCipherFactory;
import org.apache.commons.crypto.random.CryptoRandom;
import org.apache.commons.crypto.random.CryptoRandomFactory;
import java.util.Properties;
public class EnvCheck {
public static void main(String[] args) throws Exception {
System.out.println("component=" + Crypto.getComponentName() + "-" + Crypto.getComponentVersion());
System.out.println("nativeLoaded=" + Crypto.isNativeCodeLoaded());
for (String tr : new String[]{"AES/GCM/NoPadding", "AES/CTR/NoPadding", "AES/CBC/PKCS5Padding"}) {
CryptoCipher c = CryptoCipherFactory.getCryptoCipher(tr, new Properties());
System.out.println(tr + " -> " + c.getClass().getName());
c.close();
}
CryptoRandom r = CryptoRandomFactory.getCryptoRandom();
System.out.println("random -> " + r.getClass().getName());
r.close();
}
}
编译并把依赖 jar 复制到 lib 目录后直接运行:
cd /opt/install-demo && mvn -q compile && mvn -q dependency:copy-dependencies -DoutputDirectory=lib && ls lib && java -cp "target/classes:lib/*" EnvCheck
回显(实测):
commons-crypto-1.2.0.jar
jakarta.activation-1.2.2.jar
jakarta.xml.bind-api-2.3.3.jar
jaxb-impl-2.3.7.jar
jna-5.13.0.jar
component=Apache Commons Crypto-1.2.0
nativeLoaded=true
AES/GCM/NoPadding -> org.apache.commons.crypto.cipher.JceCipher
AES/CTR/NoPadding -> org.apache.commons.crypto.cipher.JceCipher
AES/CBC/PKCS5Padding -> org.apache.commons.crypto.cipher.JceCipher
random -> org.apache.commons.crypto.random.OpenSslCryptoRandom
结果解读:nativeLoaded=true 说明 jar 内嵌的 JNI 胶水库加载成功;随机数实现选中了 OpenSslCryptoRandom(OpenSSL JNI 路径生效);而三种加密变换都选中了 JceCipher——这是 Ubuntu 22.04 的 OpenSSL 3.0 环境下的正常现象(OpenSSL 3.0 缺少 1.2.0 JNI 代码引用的 EVP_CIPHER_CTX_block_size 符号,工厂静默回退 JCE),功能完全正确,只是没拿到 OpenSSL 的性能加成,详见 FAQ Q2。
四、方案B:官方发行包手动安装
方案B适合不能连 Maven 中央仓库、或只想用 javac/java -cp 轻量验证的场景。全部过程只依赖 curl 与系统 tar。
4.1 下载发行包并校验 sha512
cd /opt && curl -fsSLO https://downloads.apache.org/commons/crypto/binaries/commons-crypto-1.2.0-bin.tar.gz && curl -fsSLO https://downloads.apache.org/commons/crypto/binaries/commons-crypto-1.2.0-bin.tar.gz.sha512 && ls -l commons-crypto-1.2.0-bin.tar.gz*
回显(实测):
-rw-r--r-- 1 root root 451014 Oct 13 07:40 commons-crypto-1.2.0-bin.tar.gz
-rw-r--r-- 1 root root 129 Oct 13 07:40 commons-crypto-1.2.0-bin.tar.gz.sha512
发行包 451014 字节;.sha512 文件内容是一段裸哈希(没有文件名后缀),校验时需要手工拼上文件名再交给 sha512sum -c:
cat commons-crypto-1.2.0-bin.tar.gz.sha512
回显(实测):
fb9084a5d9adcd4df606c7deb9396fa5693443b6a91be12f5de17e4281d3e7d89b526dc6ebd7991569894bde2f9fb67036eb78504cb4fa26fae9b7a99d082051
printf "%s %s\n" "$(cat commons-crypto-1.2.0-bin.tar.gz.sha512)" commons-crypto-1.2.0-bin.tar.gz | sha512sum -c -
回显(实测):
commons-crypto-1.2.0-bin.tar.gz: OK
4.2 解包与目录结构
cd /opt && tar xzf commons-crypto-1.2.0-bin.tar.gz && ls -l commons-crypto-1.2.0/
回显(实测):
total 352
-rw-r--r-- 1 root root 6530 Dec 30 2022 CONTRIBUTING.md
-rw-r--r-- 1 root root 11358 Dec 30 2022 LICENSE.txt
-rw-r--r-- 1 root root 176 Dec 30 2022 NOTICE.txt
-rw-r--r-- 1 root root 16333 Dec 30 2022 README.md
-rw-r--r-- 1 root root 17522 Dec 30 2022 RELEASE-NOTES.txt
drwxr-xr-x 4 root root 4096 Oct 13 07:40 apidocs
-rw-r--r-- 1 root root 118088 Dec 30 2022 commons-crypto-1.2.0-sources.jar
-rw-r--r-- 1 root root 176035 Dec 30 2022 commons-crypto-1.2.0.jar
逐项说明:commons-crypto-1.2.0.jar 是运行所需的唯一 jar(176035 字节,native 库内嵌其中);apidocs 是离线 Javadoc;sources.jar 供阅读源码。可再用 jar tf 确认 jar 内确实带有本章 2.2 节列出的各平台 native 库。
4.3 编译并运行验证代码
把 3.3 节的 EnvCheck.java 放到工作目录(例如 /opt/install-manual),同时复制 jar:
mkdir -p /opt/install-manual && cd /opt/install-manual && cp /opt/commons-crypto-1.2.0/commons-crypto-1.2.0.jar . && javac -encoding UTF-8 -cp commons-crypto-1.2.0.jar EnvCheck.java && echo JAVAC_OK
回显(实测):
JAVAC_OK
java -cp .:commons-crypto-1.2.0.jar EnvCheck
回显(实测):
component=Apache Commons Crypto-1.2.0
nativeLoaded=true
AES/GCM/NoPadding -> org.apache.commons.crypto.cipher.JceCipher
AES/CTR/NoPadding -> org.apache.commons.crypto.cipher.JceCipher
AES/CBC/PKCS5Padding -> org.apache.commons.crypto.cipher.JceCipher
random -> org.apache.commons.crypto.random.OpenSslCryptoRandom
与方案A结果一致。注意两个要点:javac -cp 与 java -cp 各自都要带 jar 路径,漏掉任何一个都会报「程序包不存在」或「找不到主类」;Linux 下类路径分隔符是冒号。
💡 技术拓展:示例中的
AES/GCM/NoPadding、AES/CTR/NoPadding、AES/CBC/PKCS5Padding是三种常见分组加密模式。选型对比:ECB 无 IV、相同明文块得到相同密文块,已不安全,不建议使用;CBC 需随机 IV、串行加解密、密文有填充膨胀;CTR 把分组密码变成流密码、无填充、可并行,但严禁重复使用同一 IV 加密两份数据;GCM 在 CTR 基础上附加认证标签(默认 128 bit),能发现密文被篡改,是当前推荐模式。本文验证代码三种模式各测一条,实际业务建议优先 GCM、兼容场景用 CTR。
五、方案对比与选型建议
两种方案都能得到可用的 Commons Crypto 环境,差异集中在依赖管理与升级方式上:
| 对比项 | 方案A:Maven 依赖 | 方案B:发行包手动安装 |
|---|---|---|
| 获取方式 | pom 声明坐标,构建时自动下载 | curl 下载 tar.gz 并手工校验 |
| 完整性校验 | Maven 自带仓库校验机制 | 需手工执行 sha512 校验 |
| 传递依赖 | 自动解析(jna、jaxb-impl 等 4 个) | 无传递依赖,单 jar 直接可用 |
| 升级成本 | 改版本号重新构建 | 重新下载解包并替换 -cp 路径 |
| 适用场景 | 常规 Maven 工程、持续集成 | 无外网构建环境、快速验证、脚本工具 |
选型建议:工程开发一律选方案A,让 Maven 管理依赖与升级;临时排查问题、写一次性运维小工具或受限网络环境选方案B。两者可并存——本机用方案B的 jar 做命令行验证,工程内用方案A做集成。
六、多版本管理
服务器上常需同时保留多个 JDK。Ubuntu 通过 update-alternatives 管理:
update-alternatives --list java
回显(实测,本机装有 11 与 17 两个版本):
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
/usr/lib/jvm/java-17-openjdk-amd64/bin/java
切换默认 java:
update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java
java -version
回显(实测):
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
Commons Crypto 本身只出现在工程的 classpath 里,没有全局安装概念;多版本共存时只需保证运行与编译使用同一个 JDK 主版本,建议在脚本中显式使用 JAVA_HOME/bin/javac 与 JAVA_HOME/bin/java。
七、卸载
卸载分两层:移除 Maven/JDK 软件包,以及清理手工解压的发行包与工程目录。先用模拟模式确认 apt 将删除的内容(-s 只模拟,不实际删除):
apt-get -s remove openjdk-17-jdk maven
回显(实测,节选):
The following packages will be REMOVED:
Remv maven [3.6.3-5]
Remv openjdk-17-jdk [17.0.20.1+1-1~22.04]
确认无误后实际执行卸载:
apt-get remove --purge -y openjdk-17-jdk maven && apt-get autoremove -y
清理方案B产生的文件:
rm -rf /opt/commons-crypto-1.2.0 /opt/commons-crypto-1.2.0-bin.tar.gz /opt/commons-crypto-1.2.0-bin.tar.gz.sha512 /opt/install-manual /opt/install-demo
验证清理结果:
ls /opt | grep -c crypto || echo "commons-crypto files removed"
回显(实测):
commons-crypto files removed
Commons Crypto 运行时从 jar 内提取到临时目录的 native 库(形如 /tmp/commons-crypto-<uuid>-libcommons-crypto.so)在 JVM 退出时会自动删除,无需手工处理。
八、常见问题 FAQ
Q1:运行时报 Cannot load libcrypto.so (libcrypto.so: cannot open shared object file: No such file or directory),然后 JVM 直接崩溃?
这是 Ubuntu 22.04 最常见的坑:系统只有 libcrypto.so.3,没有未带版本号的 libcrypto.so 符号链接,而 Commons Crypto 的随机数 native 代码初始化时会按这个名字 dlopen。实测完整堆栈末尾为:
Caused by: java.lang.UnsatisfiedLinkError: Cannot load libcrypto.so (libcrypto.so: cannot open shared object file: No such file or directory)!
at org.apache.commons.crypto.random.OpenSslCryptoRandomNative.initSR(Native Method)
解法:安装 apt install -y libssl-dev 生成符号链接。注意一个实测细节:随机数工厂在实现类静态初始化抛出的是 Error(ExceptionInInitializerError),工厂的回退机制只捕获 Exception,因此此时不会回退到 JavaCryptoRandom 而是直接崩溃——所以必须补齐 libcrypto.so。
Q2:为什么随机数走了 OpenSslCryptoRandom,加密却总是 JceCipher?会不会是配置错了?
不是配置错误,是 OpenSSL 3.0 兼容性问题。实测在装好 libssl-dev 后,把 commons.crypto.cipher.classes 强制为只用 OpenSslCipher,可看到真实原因:
openssl-only FAILED: CryptoCipher {org.apache.commons.crypto.cipher.OpenSslCipher} is not available or transformation AES/CTR/NoPadding is not supported.
caused by: java.lang.IllegalStateException: java.lang.UnsatisfiedLinkError: EVP_CIPHER_CTX_block_size
EVP_CIPHER_CTX_block_size 这个符号在 OpenSSL 3.0 中已被移除,而 Ubuntu 22.04 只提供 OpenSSL 3.0,因此 1.2.0 的加密 JNI 路径无法初始化,工厂按默认 commons.crypto.cipher.classes=OpenSslCipher,JceCipher 静默回退到 JCE。功能正确、结果与 OpenSSL 路径完全一致(实测同密钥同 IV 密文逐字节相同),只损失部分吞吐。需要 OpenSSL 加密路径时,请部署提供 OpenSSL 1.1 的系统(如 CentOS 8)或等待官方支持 OpenSSL 3 的版本。
Q3:getCryptoCipher 抛 GeneralSecurityException: CryptoCipher {org.apache.commons.crypto.cipher.OpenSslCipher} is not available,且日志里没有任何警告?
工厂类的回退逻辑默认静默:OpenSslCipher 初始化失败后直接尝试列表中的下一个实现,不打印任何日志。排查时加 JVM 参数 -Dcommons.crypto.debug=true,可以看到 native 库从 jar 解压到临时目录、System.load 的完整过程,再配合 Q2 的「强制单一实现」方法即可拿到真实异常。
Q4:javac 报大量 error: unmappable character (0xE6) for encoding US-ASCII?
POSIX locale 下 javac 默认按 US-ASCII 读取源码,含中文注释的源文件会编译失败。两种解法:编译时加 -encoding UTF-8(本文方案B已演示);或在 Maven 工程里设置 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>(方案A的 pom 已包含)。
Q5:程序包 org.apache.commons.crypto 不存在,但 jar 明明在同目录?
javac 阶段漏了 -cp commons-crypto-1.2.0.jar(编译期需要 jar 解析符号),或 java 运行阶段漏了 -cp。完整写法参考 4.3 节:javac -encoding UTF-8 -cp commons-crypto-1.2.0.jar EnvCheck.java 编译、java -cp .:commons-crypto-1.2.0.jar EnvCheck 运行,冒号不能写成 Windows 的分号。
九、参考链接
- Apache Commons Crypto 官方主页:https://commons.apache.org/proper/commons-crypto/
- 官方用户指南:https://commons.apache.org/proper/commons-crypto/userguide.html
- 发行包下载目录:https://downloads.apache.org/commons/crypto/binaries/
- Maven 中央仓库 1.2.0 目录:https://repo1.maven.org/maven2/org/apache/commons/commons-crypto/1.2.0/
- 项目源码仓库:https://github.com/apache/commons-crypto