亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從模數和指數重建 RSA 私鑰失敗

從模數和指數重建 RSA 私鑰失敗

PHP
慕標5832272 2023-06-24 15:19:53
我正在嘗試從模數和私有/公共指數重建 RSA 密鑰對。比較編碼的私鑰時,轉換對于公鑰正確,但對于私鑰則失敗。當使用此重建私鑰/公鑰對進行加密時,它在 Java 中可以工作(?。?,但是當在 PHP 中使用重建密鑰對時,解密部分失?。用苷诠ぷ鳎栽谖铱磥?,重建私鑰是不同的到“原始”私鑰。僅供參考:使用“原始”密鑰對,PHP 中一切正常。所以我的問題是:如何從(BigInteger)模數和私有指數中檢索“原始”私鑰?編輯:最后查看我的最終編輯我的示例代碼顯示了公鑰與重建密鑰的相等性,并且私鑰是不同的:Rebuilding of a RSA PrivateKey from modulus & exponentprivateKey equals rebuild: falsepublicKey equals rebuild: true代碼:import java.math.BigInteger;import java.security.*;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.RSAPrivateKeySpec;import java.security.spec.RSAPublicKeySpec;import java.util.Arrays;public class RebuildRSAPrivateKey {    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {        System.out.println("Rebuilding of a RSA PrivateKey from modulus & exponent");        // rsa key generation        KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");        //kpGen.initialize(2048, new SecureRandom());        kpGen.initialize(2048, new SecureRandom());        KeyPair keyPair = kpGen.generateKeyPair();        // private key        PrivateKey privateKey = keyPair.getPrivate();        // get modulus & exponent        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;        BigInteger modulus = rsaPrivateKey.getModulus();        BigInteger privateExponent = rsaPrivateKey.getPrivateExponent();    }}編輯:以下程序將顯示從編碼密鑰派生的 RSA 私鑰/公鑰對可以恢復,并且加密和解密可以在 Java 和 PHP 中進行。密鑰是不安全的RSA 512 位密鑰并經過 Base64 解碼。然后從模數和私有/公共指數派生出相同的密鑰,并且加密/解密在 Java 中有效,但在 PHP 中無效。這就是為什么我想從模數和指數中獲取“原始”RSA 密鑰,感謝您的好意幫助。
查看完整描述

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));

}


查看完整回答
反對 回復 2023-06-24
  • 1 回答
  • 0 關注
  • 176 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號