1 回答

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超3個(gè)贊
執(zhí)行 RSA 解密操作所需的最少信息是模數(shù)n
和解密指數(shù)d
。有一種優(yōu)化可以應(yīng)用于涉及中國(guó)余數(shù)定理的 RSA 解密,其中分別對(duì) RSA 素?cái)?shù)進(jìn)行求冪,然后組合以產(chǎn)生最終值,因此RSA 私鑰語法中有一些用于此目的的額外字段以及RSAPrivateCrtKey
模仿它的Java接口。
現(xiàn)在這里提出的問題是:兩個(gè) RSAPrivateCrtKey 實(shí)例何時(shí)相等?我認(rèn)為當(dāng)它們?cè)?RSA 算法中功能相同時(shí),它們是相等的。您要求更狹窄的定義,即當(dāng)它們的編碼形式相等時(shí)它們相等。這個(gè)定義的問題在于它過于特定于實(shí)現(xiàn)。目前,當(dāng)“Sun”提供商生成密鑰對(duì)時(shí),它總是對(duì)素?cái)?shù)進(jìn)行排序p
,q
使得p
>?q
。但我喜歡另一種方式,其中p
<?q
。RSAPrivateCrtKey 接口不關(guān)心任何一種方式,因?yàn)樗贿M(jìn)行檢查。該接口的 Javadoc 沒有指定順序。您可以更改我的代碼以生成與以下內(nèi)容相同的編碼形式當(dāng)前的“Sun”實(shí)現(xiàn)只需反轉(zhuǎn)p.compareTo(q) > 0
.?但是,默認(rèn)實(shí)現(xiàn)可以更改以符合我將來的偏好,如果我接管世界的計(jì)劃成功的話,默認(rèn)實(shí)現(xiàn)就會(huì)更改。Javadoc 是規(guī)范,只要符合 Javadocs,實(shí)現(xiàn)就可以更改。
下面我提供了一個(gè)相等函數(shù)的實(shí)現(xiàn),其中我嘗試合并與規(guī)范一致的盡可能廣泛的相等概念。也就是說,在 RSA 算法中使用時(shí),任何兩個(gè)keyEquals
返回的RSAPrivateCRTKey 實(shí)例都應(yīng)該產(chǎn)生相同的結(jié)果,并且如果返回,則應(yīng)該至少有一個(gè)值會(huì)產(chǎn)生不同的結(jié)果。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 關(guān)注
- 175 瀏覽
添加回答
舉報(bào)