2017-04-06 37 views
1

我正在實現我自己的RSA版本,以及Java中的填充方案RSA-OAEP。這是我的基本算法代碼:使用Java BigIntegers在RSA中解密時,如何在原始數據的開頭保留零字節?

public byte[] encrypt(byte[] data, RSA_PublicKey publicKey) { 
    BigInteger message = new BigInteger(data); 
    BigInteger n = publicKey.getModulus(); //RSA Modulus 
    BigInteger e = publicKey.getPublicExponent(); //RSA Public Exponent 
    if (message.compareTo(n) >= 0) { 
     throw new InvalidDataException(); 
    } 
    byte[] cipherText = message.modPow(e, n).toByteArray(); //Encryption 
    return cipherText; 
} 

public byte[] decrypt(byte[] data, RSA_PrivateKey privateKey) { 
    BigInteger cipherText = new BigInteger(data); 
    BigInteger n = privateKey.getModulus(); //RSA Modulus 
    BigInteger d = privateKey.getPrivateExponent(); //RSA Private Exponent 
    if (cipherText.compareTo(n) >= 0) { 
     throw new InvalidDataException(); 
    } 
    if (cipherText.compareTo(n.subtract(BigInteger.ONE)) == 1) { 
     throw new InvalidDataException(); 
    } 
    byte[] message = cipherText.modPow(d, n).toByteArray(); //Decryption 
    return message; 
} 

在RSA-OAEP,都對數據使用加密前的掩模生成函數隨機種子進行一系列的操作。零字節位於填充數據的前面。這就是它看起來像在我的代碼:

buffer = ByteBuffer.allocate(k); 
buffer.put((byte)0); 
buffer.put(maskedSeed); 
buffer.put(maskedDB); 
byte[] em = buffer.array(); 
byte[] cipherText = encrypt(em, publicKey); 
return cipherText 

當我解密這個密文,有時零字節仍是導致字節數組中,其他時候它不是。例如,該數據(十六進制)中的加密之前和解密之後是相同的:

00c127a743b56f53e46223eba367b63d3378648c1d5ce3e8eec1f714c099a15b674c528d5051c1c9a32dc39fb13ee745864c7f572fa950dc8336a54d89503754f6c18dd463ec1633e6e94638230d9b10cc6e2904f4c69247a8bac0c60885b37b8adefe3b682b3a6d39f445447fa2f173b408346d3d0db086e199ef9c1fd0d14f

然而,這樣的數據:

001c924b794c178c9955d4f3211c67ecda59ffe8c4be55c101bcd5ff3ce0a746ca447b5fc8fd8725cbb083e4b9244cf49b6ca84465680c0c49bec2bab3dfab6371673f0d01605d641330592ffb8915229c2dc4ea1ffcdf8a9a0e461fdf224f5cf57f74affac9d35dd3ce61ff1dd068a8c9495290735415984ddb71515823f746

被解密爲這樣:

1c924b794c178c9955d4f3211c67ecda59ffe8c4be55c101bcd5ff3ce0a746ca447b5fc8fd8725cbb083e4b9244cf49b6ca84465680c0c49bec2bab3dfab6371673f0d01605d641330592ffb8915229c2dc4ea1ffcdf8a9a0e461fdf224f5cf57f74affac9d35dd3ce61ff1dd068a8c9495290735415984ddb71515823f746

按照RSA標準,將解密的填充的數據被認爲被檢查這個零字節,以確保它是正確填充,並返回一個錯誤消息如果不是。我相信這與BigIntegers簽署的事實有關。有沒有解決這個問題的方法?

+0

*「當我解密這個密文,有時零字節仍是生成的字節數組中,其他時候它不是。 「* - 請[編輯]你的問題給一些例子。 –

+0

我剛剛意識到,零字節後的填充數據的第一位是0時,零字節不會出現。如果它是1,則它工作正常。這肯定與BigIntegers簽名有關。 – metroidsocrates

+0

這就是你手工完成RSA的過程。 BigInteger算術沒有關於您希望答案有多大的概念。如果結果是25,無論模數有多大,你都會得到一個字節。你必須自己添加零。您可能需要編寫一個採用BigInteger和期望長度的方法,並返回一個長度爲大的字節數組,並根據需要預置零。 –

回答

0

new BigInteger(data)始終以雙補碼錶示法解析數據,其中最重要的位用信號表示符號。在RSA,所有的數字都是積極的,所以你可以設置登錄爲1

new BigInteger(1, data) 
+0

我試過了。它不能解決問題。 – metroidsocrates

+0

你是否這樣做加密? –

+0

我做了加密和解密。 – metroidsocrates

相關問題