1 回答
TA贡献1895条经验 获得超3个赞
执行 RSA 解密操作所需的最少信息是模数n
和解密指数d
。有一种优化可以应用于涉及中国余数定理的 RSA 解密,其中分别对 RSA 素数进行求幂,然后组合以产生最终值,因此RSA 私钥语法中有一些用于此目的的额外字段以及RSAPrivateCrtKey
模仿它的Java接口。
现在这里提出的问题是:两个 RSAPrivateCrtKey 实例何时相等?我认为当它们在 RSA 算法中功能相同时,它们是相等的。您要求更狭窄的定义,即当它们的编码形式相等时它们相等。这个定义的问题在于它过于特定于实现。目前,当“Sun”提供商生成密钥对时,它总是对素数进行排序p
,q
使得p
> q
。但我喜欢另一种方式,其中p
< q
。RSAPrivateCrtKey 接口不关心任何一种方式,因为它不进行检查。该接口的 Javadoc 没有指定顺序。您可以更改我的代码以生成与以下内容相同的编码形式当前的“Sun”实现只需反转p.compareTo(q) > 0
. 但是,默认实现可以更改以符合我将来的偏好,如果我接管世界的计划成功的话,默认实现就会更改。Javadoc 是规范,只要符合 Javadocs,实现就可以更改。
下面我提供了一个相等函数的实现,其中我尝试合并与规范一致的尽可能广泛的相等概念。也就是说,在 RSA 算法中使用时,任何两个keyEquals
返回的RSAPrivateCRTKey 实例都应该产生相同的结果,并且如果返回,则应该至少有一个值会产生不同的结果。true
false
public static boolean keyEquals(RSAPrivateCrtKey k1, RSAPrivateCrtKey k2) {
final BigInteger ZERO = BigInteger.ZERO;
boolean result = true;
result = result && isConsistent(k1) && isConsistent(k2);
result = result && k1.getModulus().equals(k2.getModulus());
BigInteger lambda = computeCarmichaelLambda(k1.getPrimeP(), k1.getPrimeQ());
result = result && k1.getPublicExponent().subtract(k2.getPublicExponent()).mod(lambda).equals(ZERO);
result = result && k1.getPrivateExponent().subtract(k2.getPrivateExponent()).mod(lambda).equals(ZERO);
return result;
}
private static boolean isConsistent(RSAPrivateCrtKey k1) {
final BigInteger ZERO = BigInteger.ZERO;
final BigInteger ONE = BigInteger.ONE;
BigInteger n = k1.getModulus();
BigInteger p = k1.getPrimeP();
BigInteger q = k1.getPrimeQ();
BigInteger e = k1.getPublicExponent();
BigInteger d = k1.getPrivateExponent();
boolean result = true;
result = p.multiply(q).equals(n);
BigInteger lambda = computeCarmichaelLambda(p, q);
result = result && e.multiply(d).mod(lambda).equals(ONE);
result = result && d.subtract(key.getPrimeExponentP()).mod(p.subtract(ONE)).equals(ZERO);
result = result && d.subtract(key.getPrimeExponentQ()).mod(q.subtract(ONE)).equals(ZERO);
result = result && q.multiply(k1.getCrtCoefficient()).mod(p).equals(ONE);
return result;
}
private static BigInteger computeCarmichaelLambda(BigInteger p, BigInteger q) {
return lcm(p.subtract(BigInteger.ONE), q.subtract(BigInteger.ONE));
}
private static BigInteger lcm(BigInteger x, BigInteger y) {
return x.multiply(y).divide(x.gcd(y));
}
- 1 回答
- 0 关注
- 129 浏览
添加回答
举报