我正在實現我自己的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時,零字節不會出現。如果它是1,則它工作正常。這肯定與BigIntegers簽名有關。 – metroidsocrates
這就是你手工完成RSA的過程。 BigInteger算術沒有關於您希望答案有多大的概念。如果結果是25,無論模數有多大,你都會得到一個字節。你必須自己添加零。您可能需要編寫一個採用BigInteger和期望長度的方法,並返回一個長度爲大的字節數組,並根據需要預置零。 –