There is nothing wrong with the code; this is a mistake in the library used.
The problem is
generate_random_bytestring :: CryptoRandomGen g => g -> Int64 -> (ByteString, g) generate_random_bytestring g 0 = (BS.empty, g) generate_random_bytestring gx = (BS.cons' first rest, g'') where (rest, g') = generate_random_bytestring g (x - 1) (first, g'') = throwLeft $ crandomR (1,255) g'
which should generate a random ByteString given length without a 0-byte does not.
Hacking the source code of Codec.Crypto.RSA to check it, I get a 0-byte error very quickly.
This means that the decoded message is considered longer than it actually is, and garbage appears in front of it.
The specific error is that crandomR sometimes produces a 0-byte result due to an error in crandomR_Num :
Right (bs, g') -> let res = fromIntegral $ fromIntegral low + (bs2i bs .&. mask) in if res > high then go g' else Right (res, g')
Here mask is 0xFF (255), low is 1. If the generated unlimited byte is 255, then
res = fromIntegral 256
which is 0 and therefore not > high .
In the next version (0.4.1) of monadcryptorandom, the error should be fixed must be . will be soon already on the hack.
OAEP methods do not affect, as far as I see, because they use a different padding scheme to fill pieces of the required length.
Daniel Fischer
source share