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

Ivan Lazar Miljenovic ivan.miljenovic at gmail.com
Wed Apr 22 04:01:05 UTC 2015


On 22 April 2015 at 13:58, Magicloud Magiclouds
<magicloud.magiclouds at gmail.com> wrote:
> Ah, sorry, the "encode" function is the one from cereal, not to "generate a
> particular encoding for a value".

I meant "encode" as in "use a specific representation rather than
directly converting it on a constructor-by-constructor basis as is the
default for Get/Put".

>
> On Wed, Apr 22, 2015 at 11:56 AM, Ivan Lazar Miljenovic
> <ivan.miljenovic at gmail.com> wrote:
>>
>> 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
>
>
>
>
> --
> 竹密岂妨流水过
> 山高哪阻野云飞
>
> And for G+, please use magiclouds#gmail.com.



-- 
Ivan Lazar Miljenovic
Ivan.Miljenovic at gmail.com
http://IvanMiljenovic.wordpress.com


More information about the Haskell-Cafe mailing list