[Haskell-cafe] How to use an crypto with hackage cereal?

Andrey Sverdlichenko blaze at ruddy.ru
Wed Apr 22 03:26:05 UTC 2015


You can't really modify source bytestring inside Get monad, and this is what decryption effectively do. The only option I know about is to run another parser inside Get monad. I'd rather write decrypt-runGetPartial-decrypt-runGetPartial loop and return Fail from it on decryption error.

On Tue, Apr 21, 2015 at 8:12 PM, Magicloud Magiclouds
<magicloud.magiclouds at gmail.com> wrote:

> How about fail in Get monad if decrypt failed? So decrypt failure would
> lead to a result of "Left String" on decode.
> On Wed, Apr 22, 2015 at 11:05 AM, Andrey Sverdlichenko <blaze at ruddy.ru>
> wrote:
>> You probably should not merge decrypt and decode operations, it is bad
>> crypto habit. Until you decrypted and verified integrity of data, parsing
>> is dangerous and opening your service to attacks. Correct way of
>> implementing this would be to pass ciphertext to decryption function and
>> run parser only if decryption is successful. If bytestring is too big to be
>> decrypted in one piece, consider encrypting it in blocks and feeding
>> decrypted parts to parser.
>>
>>
>>
>> On Tue, Apr 21, 2015 at 7:49 PM, Magicloud Magiclouds <
>> magicloud.magiclouds at gmail.com> wrote:
>>
>>> Similar as you envisaged. I would receive a bytestring data and a config
>>> point out what cipher to use. Then I deserialize the data to a data type
>>> with some fields. The serialize process is something like:
>>>
>>> msum $ map (encrypt . encode) [field1, field2, field3]
>>>
>>> I could parse the bytestring outside Get/Put monads. But I think that
>>> looks ugly. I really want to embed the decrypt process into Get/Put monads.
>>>
>>> On Tue, Apr 21, 2015 at 10:08 PM, Ivan Lazar Miljenovic <
>>> ivan.miljenovic at gmail.com> wrote:
>>>
>>>> On 21 April 2015 at 23:58, Magicloud Magiclouds
>>>> <magicloud.magiclouds at gmail.com> wrote:
>>>> > Thank you. But how if the cipher was specified outside the binary
>>>> data? I
>>>> > mean I need to pass the decrypt/encrypt function to get/put while they
>>>> do
>>>> > not accept parameters. Should I use Reader here?
>>>>
>>>> Maybe you could explain what you're doing better.
>>>>
>>>> I would envisage that you would get a Bytestring/Text value, then
>>>> encrypt/decrypt and then put it back (though if you're dealing with
>>>> Bytestrings, unless you're wanting to compose them with others there's
>>>> no real need to use Get and Put as you'll have the resulting
>>>> Bytestring already...).
>>>>
>>>> Or are you wanting to implement your own encryption/decryption scheme?
>>>>  In which case, you might want to either:
>>>>
>>>> a) write custom functions in the Get and Put monads OR
>>>>
>>>> b) write custom parsers (e.g. attoparsec) and builders (using the
>>>> Builder module in bytestring); this is probably going to suit you
>>>> better.
>>>>
>>>> >
>>>> > On Tue, Apr 21, 2015 at 6:43 PM, Yitzchak Gale <gale at sefer.org> wrote:
>>>> >>
>>>> >> Magicloud Magiclouds wrote:
>>>> >> > I am trying to work with some binary data that encrypted by field
>>>> >> > instead of
>>>> >> > the result of serialization. I'd like to use Data.Serialize to wrap
>>>> the
>>>> >> > data
>>>> >> > structure. But I could not figure out how to apply an runtime
>>>> specified
>>>> >> > cipher method to the bytestring.
>>>> >>
>>>> >> Are you using the set of crypto libraries written by
>>>> >> Victor Hanquez, such as cryptocipher-types,
>>>> >> crypto-pubkey-types, and cryptohash?
>>>> >>
>>>> >> Or the set of libraries written by Thomas DuBuisson,
>>>> >> such as crypto-api, cipher-aes128, etc.?
>>>> >>
>>>> >> Here is an example of decoding for Victor's libraries.
>>>> >> Encoding would be similar using Put instead of Get.
>>>> >> Thomas' libraries would be similar using the other
>>>> >> API.
>>>> >>
>>>> >> Let's say you have a type like this:
>>>> >>
>>>> >> data MyCipher = MyAES | MyBlowfish | ...
>>>> >>
>>>> >> Then in your cereal code you would have a Get monad
>>>> >> expression something like this (assuming you have
>>>> >> written all of the functions called parseSomething):
>>>> >>
>>>> >> getStuff = do
>>>> >>   cipher <- parseCipher :: Get MyCipher
>>>> >>   clearText <- case cipher of
>>>> >>     MyAES -> do
>>>> >>       keyBS <- parseAESKey :: Get ByteString
>>>> >>       let key = either (error "bad AES key") id $ makeKey keyBS
>>>> >>           cipher = cipherInit key
>>>> >>       cipherText <- parseAESCipherText :: Get ByteString
>>>> >>       return $ ecbDecrypt cipher cipherText
>>>> >>     MyBlowfish -> do ...
>>>> >>
>>>> >> etc.
>>>> >>
>>>> >> Hope this helps,
>>>> >> Yitz
>>>> >
>>>> >
>>>> >
>>>> >
>>>> > --
>>>> > 竹密岂妨流水过
>>>> > 山高哪阻野云飞
>>>> >
>>>> > And for G+, please use magiclouds#gmail.com.
>>>> >
>>>> > _______________________________________________
>>>> > Haskell-Cafe mailing list
>>>> > Haskell-Cafe at haskell.org
>>>> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>>>> >
>>>>
>>>>
>>>>
>>>> --
>>>> Ivan Lazar Miljenovic
>>>> Ivan.Miljenovic at gmail.com
>>>> http://IvanMiljenovic.wordpress.com
>>>>
>>>
>>>
>>>
>>> --
>>> 竹密岂妨流水过
>>> 山高哪阻野云飞
>>>
>>> And for G+, please use magiclouds#gmail.com.
>>>
>>
>>
> -- 
> 竹密岂妨流水过
> 山高哪阻野云飞
> And for G+, please use magiclouds#gmail.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20150421/b68306df/attachment.html>


More information about the Haskell-Cafe mailing list