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 實例都應該產生相同的結果,并且如果返回,則應該至少有一個值會產生不同的結果。truefalse
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 關注
- 176 瀏覽
添加回答
舉報
