AES-256 Encryption Best Practices

William Prothero waprothero at gmail.com
Tue Jul 3 07:56:54 CEST 2018


Brian, thanks for the feedback.

I started by using random bytes, which was ok, but the php base64encode would only encode characters. So, I couldn’t get the return message to decode in LC correctly. I forget, it could have been the LC decode step, but the upshot was that I decided to go with valid ascii characters for iv because of this.

I don’t understand the problem with using the milliseconds to generate the random seed, though. The least significant digits of the milliseconds only depends on the random time the user first initiates the query. I assumed the milliseconds counts up to some maximum integer number, then repeats. Hmm, maybe I need to investigate how the counting goes. I had assumed it was just an integer number that counted until it overflowed, then started again from zero. I can investigate this.

What would the H(MAC) consist of? I haven’t heard of it.

Best,
Bill

William Prothero
http://earthlearningsolutions.org

> On Jul 2, 2018, at 9:57 PM, Brian Milby <brian at milby7.com> wrote:
> 
> I would suggest using "randombytes" instead of "random" on desktop/server (according to dictionary is isn't available in mobile, but I have not actually verified).  That uses the openssl library to generate random numbers.  The problem with using an IV based on a pseudorandom number generator seeded from something derived from the time means that it is potentially predictable.
> 
> I was playing around with a function to generate an IV that is guaranteed to not repeat.  The middle 4 bytes are the seconds, so it reduces the randomness by 4 bytes.  I'm not sure how much of an issue that would be.  It does avoid the birthday problem (which should not really be an issue with a good random number generator I would guess).  Maintaining your own counter would be another option.  Ensuring uniqueness and unpredictability is the goal.
> 
> One other thing that I was reading is that we should also include a (H)MAC after the encryption to ensure that the payload is not tampered with.  We would then only decrypt if the message had not been changed (and the IV would be included in the MAC calculation).
> 
> Below is the code that I was experimenting with:
> 
> function generateIV pLength
>    local tSeconds, tBytes
>    
>    put randomBytes(6) into tBytes
>    put the seconds into tSeconds
>    repeat until tSeconds < 256
>       put numToByte(tSeconds mod 256) after tBytes
>       put tSeconds div 256 into tSeconds
>    end repeat
>    put numToByte(tSeconds) after tBytes
>    
>    if pLength is empty then put 16 into pLength
>    subtract length(tBytes) from pLength
>    if pLength < 0 then
>       delete byte 1 to (- pLength) of tBytes
>    else
>       put randomBytes(pLength) after tBytes
>    end if
>    return tBytes
> end generateIV
> 
>> On Mon, Jul 2, 2018 at 10:37 PM, William Prothero via use-livecode <use-livecode at lists.runrev.com> wrote:
>> Folks:
>> I’ve been working on a sample stack to demonstrate encryption, best practices (as far as I can determine).
>> The online lessons are not adequate for a robust solution to this vital security issue. I’ve posted a demo stack at: http://earthlearningsolutions.org/google-static-maps-demo/ <http://earthlearningsolutions.org/google-static-maps-demo/>  This stack has benefited from feedback and ideas from folks on this list. Feedback is welcome.
>> 
>> This stack generates a random iv vector and uses AES-256 encryption to encode an array containing commands for interaction with a mySQL server. The server side php script that decodes the data and encodes the returned response is included.
>> 
>> On thing I am still unsure about is the best way to generate a random string of characters that I use for the random IV (initialization vector) that is used for the encryption. I’ve included some code below, which is used to encrypt and decrypt the data sent and returned from the server. The encode and decode scripts are put into the launcher, or stack that is created when a standalone or mobile version is built.
>> 
>> Here are the handlers. The encryption key will be more secure if it is obfuscated by putting it in as a property of a control or hidden in some way. I am wondering if the generation of the random seed is optimum.
>> 
>> Feedback welcome.
>> 
>> local theRandomSeed
>> 
>> function randomChrs n
>>    if theRandomSeed = "" then
>>       setRandomSeed
>>    end if
>>    put "" into tChars
>>    repeat with i=1 to n
>>       put random(256) into nChar
>>       put numToNativeChar(nChar) after tChars
>>    end repeat
>>    return tChars
>> end randomChrs
>> 
>> on setRandomSeed
>>    put (the milliseconds) into tMS
>>    put trunc(tMs/10000000) into tDiv
>>    put tMS mod tDiv into theRandomSeed
>>    set the randomseed to theRandomSeed
>> end setRandomSeed
>> 
>> function theRandomIV
>>    if theRandomSeed = "" then
>>       setRandomSeed
>>    end if
>>    put randomChrs(16) into tIVBytes
>>    return tIVBytes
>> end theRandomIV
>> 
>> --This handler encodes the data. First it generates a random
>> --initialization vector (iv), then encrypts the data and puts
>> --adds iv to the encoded data.
>> --tArray is an array that controls the action of the php script.
>> function theEncoded tArray
>>    put  theRandomIV() into tIV
>>    put base64Encode(tIV) into tB64IV
>>    put ArrayToJSON(tArray,"string”,”") into tJson
>>    put "AFBDDFCFBDBBDDCCFFACGHDFFFFEEDCC" into tEncryptionKey
>>    put "AES-256-CTR" into tCipher
>>    encrypt tJson using tCipher with key tEncryptionKey and iV tIV
>>    put base64encode(it) into tDataToSend
>>    --comment out next statement if iv not included in data
>>    put tB64IV&tDataToSend into tDataToSend
>>    return tDataToSend
>> end theEncoded
>> 
>> --This decodes the data that is returned by the php on the
>> --remote server.
>> --The iv is expected as the first 24 bytes of the returned data.
>> function theDecoded tData
>>    put byte 1 to 24 of tData into tIVB64
>>    put base64decode(tIVB64) into tIV
>>    put the number of bytes in tData into n
>>    put byte 25 to n of tData into tRetB64Data
>>    put base64decode(tRetB64Data) into tRetData
>>    put "AES-256-CTR" into tCipher
>>    put "AFBDDFCFBDBBDDCCFFACGHDFFFFEEDCC" into tEncryptionKey
>>    decrypt tRetData using tCipher with key tEncryptionKey and iV tIV
>>    put it into tReturn
>>    return tReturn
>> end theDecoded
>> -- End of handlers that should be in the main stack
>> 
>> _______________________________________________
>> use-livecode mailing list
>> use-livecode at lists.runrev.com
>> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
>> http://lists.runrev.com/mailman/listinfo/use-livecode
> 


More information about the use-livecode mailing list