BigInteger在加密算法中必须使用——RSA、DSA等依赖远超64位的整数精度,Java原生类型无法承载;密钥生成需用probablePrime和isProbablePrime确保大素数安全;核心运算如modPow、gcd、modInverse等不可手动实现;明文须经UTF-8字节数组转BigInteger(signum=1)后参与计算。

BigInteger在加密算法中不是“能用”,而是“必须用”——因为RSA、DSA等公钥算法的核心运算(如模幂、大素数生成、欧拉函数计算)全部依赖于远超64位的整数精度,而Java原生类型根本无法承载。
密钥生成离不开probablePrime和素性检验
生成安全密钥的第一步是获得两个足够大的随机素数p和q。不能靠遍历或硬编码,必须用BigInteger.probablePrime(bitLength, random)生成候选值,并立即用isProbablePrime(certainty)验证。
- bitLength建议1024起,生产环境推荐2048或3072:太小易被分解,太大拖慢加解密
- certainty通常设256:表示素性错误概率低于1/2²⁵⁶,已远超实际攻击可能性
- 要避免
new BigInteger(String)直接构造素数——那只是字符串转数,不保证是素数
核心运算全靠modPow、gcd、remainder这些方法
RSA每一步都对应BigInteger的一个原子操作,手动实现既易错又不安全:
- 计算n = p × q → 用
p.multiply(q) - 计算φ(n) = (p−1)×(q−1) → 先
p.subtract(ONE)再multiply - 选公钥e满足gcd(e, φ(n)) = 1 → 用
e.gcd(phi).equals(ONE) - 求私钥d满足e·d ≡ 1 (mod φ(n)) → 用
e.modInverse(phi)(比手写扩展欧几里得更稳) - 加密c = me mod n → 直接
m.modPow(e, n),一行搞定
明文预处理必须转字节数组再升为BigInteger
明文是字符串,不能直接当m参与模幂。常见做法是:
- 用
str.getBytes(StandardCharsets.UTF_8)得到byte[] - 用
new BigInteger(1, bytes)构造正整数(首参数1表示signum,避免负数解释) - 确保m n.bitLength()/8 − 11(PKCS#1 v1.5填充预留),就必须拆分
- 解密后用
decrypted.toByteArray()还原字节数组,再new String(..., UTF_8)
性能与安全边界必须心里有数
BigInteger高效但非零成本:
- 所有运算都是O(n²)或更差(如乘法默认用朴素算法,大数时可用
multiply内部切换Karatsuba) - 避免频繁
toString()或intValue()——可能截断或抛异常;需要int值时先compareTo校验范围 - 密钥材料(p、q、d)绝不能打印、记录日志;用
SecureRandom而非Random,防止可预测性 - 不要把私钥存成普通String或BigInteger字段——考虑用
Clearable包装或及时clear()

















