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

Ivan Lazar Miljenovic ivan.miljenovic at gmail.com
Wed Apr 22 03:56:14 UTC 2015


On 22 April 2015 at 13:52, Magicloud Magiclouds
<magicloud.magiclouds at gmail.com> wrote:
> Say the data structure is:
>
> data Person = Person { name :: String
>                        , gender :: Gender
>                        , age :: Int }
>
> Then the process to generate the binary is:
>
> msum $ map (encrypt . encode) [ length $ name person, name person, gender
> person, age person ]
>
> Above process is just persudo in Haskell, the actual is not coded in
> Haskell.

Except that binary and cereal are for serializing Haskell values
directly; you seem to be wanting to parse and generate a particular
encoding for a value.  In which case, I don't think binary or cereal
is really appropriate.

>
> On Wed, Apr 22, 2015 at 11:44 AM, Andrey Sverdlichenko <blaze at ruddy.ru>
> wrote:
>>
>> Could you describe encrypted data format? I can't understand problem with
>> decryption.
>>
>>
>>
>> On Tue, Apr 21, 2015 at 8:41 PM, Magicloud Magiclouds
>> <magicloud.magiclouds at gmail.com> wrote:
>>>
>>> That is the ugliness of the original binary data. The encryption is not
>>> by fixed block size. So decrypt cannot be run before the get* helpers. So
>>> decrypt-runGetPartial-decrypt-runGetPartial loop would not work.
>>>
>>> I need a "post process" in Get. For example, "portNumber <- liftM decrypt
>>> getWord16be; return $ MyDataType portNumber". But currently I could not pass
>>> decrypt into get function.
>>>
>>> On Wed, Apr 22, 2015 at 11:26 AM, Andrey Sverdlichenko <blaze at ruddy.ru>
>>> wrote:
>>>>
>>>> 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.
>>>>
>>>>
>>>
>>>
>>>
>>> --
>>> 竹密岂妨流水过
>>> 山高哪阻野云飞
>>>
>>> And for G+, please use magiclouds#gmail.com.
>>
>>
>
>
>
> --
> 竹密岂妨流水过
> 山高哪阻野云飞
>
> 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


More information about the Haskell-Cafe mailing list