Here's what I'm trying to do in Haskell:
- take a message in ByteString format (doesn't really matter if lazy or strict)
- encrypt the message with an RSA public key
- base64 encode the encrypted message
The RSA library that I'm using handles lazy ByteStrings internally. The Base64 library, however, uses strict ByteStrings only. My application uses lazy ByteStrings to send the messages to network sockets.
So, it looks like I have to convert between lazy and strict ByteStrings. Here's what I do:
encrypt :: CryptoRandomGen t => t -> RSA.PublicKey -> L.ByteString -> L.ByteString
encrypt gen pubkey msg = do
let (ciphertext,_) = RSA.encrypt gen pubkey msg
(L.fromChunks . map encode . L.toChunks) $ ciphertext
decrypt :: RSA.PrivateKey -> L.ByteString -> Either String L.ByteString
decrypt privkey ciphertext = do
dec <- decode $ S.concat $ L.toChunks ciphertext
return $ RSA.decrypt privkey $ L.fromChunks [dec]
Unfortunately, sometimes this fails. When I decrypt a message encrypted in this way it sometimes results in garbage followed by the actual message. I'm not sure exactly where the problem is: is it the conversion from lazy to strict ByteStrings or is it the base64 encoding step? Or is it both?
Lazy ByteStrings are just lists of strict ByteString chunks. Do I implicitly modify the length of the message by converting it?
Please enlighten me.