Ubuntu 22.04 安装 Apache Commons Crypto 指南

在 Ubuntu 22.04 服务器上从零搭建 Apache Commons Crypto 1.2.0 可用环境:JDK 17 与 Maven 安装、Maven 依赖与官方发行包两种获取方案、sha512 校验与最小验证代码实测。

Apache Commons CryptoApache Commons Crypto2026/10/13

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
JDKOpenJDK 17.0.20.1(apt 仓库 openjdk-17-jdk)
构建工具Apache Maven 3.6.3
OpenSSL3.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_64org/apache/commons/crypto/native/Linux/x86_64/libcommons-crypto.so
Linux aarch64org/apache/commons/crypto/native/Linux/aarch64/libcommons-crypto.so
Linux armorg/apache/commons/crypto/native/Linux/arm/libcommons-crypto.so
Linux armhforg/apache/commons/crypto/native/Linux/armhf/libcommons-crypto.so
macOS x86_64org/apache/commons/crypto/native/Mac/x86_64/libcommons-crypto.jnilib
Windows x86org/apache/commons/crypto/native/Windows/x86/commons-crypto.dll
Windows x86_64org/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 的分号。

九、参考链接

  1. Apache Commons Crypto 官方主页:https://commons.apache.org/proper/commons-crypto/
  2. 官方用户指南:https://commons.apache.org/proper/commons-crypto/userguide.html
  3. 发行包下载目录:https://downloads.apache.org/commons/crypto/binaries/
  4. Maven 中央仓库 1.2.0 目录:https://repo1.maven.org/maven2/org/apache/commons/commons-crypto/1.2.0/
  5. 项目源码仓库:https://github.com/apache/commons-crypto