Encryption-Decryption AES-xxx-CBC

Want to talk about something that isn't covered by another category?

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
markclark
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6
Joined: Thu Jan 24, 2013 4:38 pm

Encryption-Decryption AES-xxx-CBC

Post by markclark » Fri May 13, 2022 10:49 pm

Hello all, I was sending some messages to the use list but figured that this topic isn't of general interest.

Sadly, crypto is one of the most often misrepresented topics on the internet, so google isn't always your friend. Hopefully we can avoid the typical camp replies of "it's dangerous! don't do it unless you are an expert!" or the old "you must use method x with cypher y", etc. :D

I am interested in discussion, feedback, tips, criticisms (gently, please) on the topic of encryption within LiveCode. Crypto libraries are the sort of plumbing most people don't think about until they need them. But it's sure useful to get some of the fundamentals down before you need them. When you have a nice toolkit like LiveCode a potential drawback is that not all the options you might find in less elegant alternatives aren't in our kit, or they are abstracted maybe a little too much, and certainly we might be able to get some thoughts together to help out our friends at hq with documentation-examples, etc.

My first foray is into the world of encrypting files, including arbitrarily large ones, that can be safely presumed to be properly "encrypted at rest" and which can also then be transported properly while "encrypted in flight." For this first case let's not get into the transport piece or even authentication (we can cover that in GBC and HMAC).

When both the encryptor and decryptor are your own LiveCode apps, everything is pretty simple. Things can get slowed down a bit when you want to create a pattern to be used on another system from which you can reliably decrypt in reasonable time within reasonable memory utilization on the LC end.

Regardless, here is a portion of the help text concerning the encrypt command:

encrypt source using cipher with {password|key} passorkey [and salt saltvalue] [and IV IVvalue] [at bitvalue bit]
and a simple example:
encrypt myData using "aes-256-cbc" with password "@&^2fy"

This certainly works, and it's an okay pattern to use if you are not re-using the same key to send the same message (we should talk about this). Otherwise you would want to use the IV or randomize some toss away bytes within the start of your message to encrypt.

LiveCode makes doing some relatively difficult things pretty darn easy. You don't even have to construct your key, just provide a password and it's done for you. Which begs the question, how is it done by LiveCode? If you never leave LiveCode for encrypt-decrypt this won't matter. But if you want to use LIveCode for decrypting someone else's stuff (even if they follow your "recipe") -- or you want to send them an encrypted message, then we need to get a little more information and hopefully make it handy for people who don't want to do all this digging.

If you don't provide the salt value with the passwords option then one is made for you. That's cool and very handy.

So here is my first q. If I send a file encrypted using the example value, how would someone using python decrypt this message?

Here's a generic sample python snippet. All aes has a 16 byte block length. We are using 256 so the key length is 32 bytes.

What values would we transmit to the python programmer at the other end of the line to decrypt our message? The default message digest varies depending on age and version of openssl you are using.


def decrypt(ciphertext, password):
blksz = 16
klen=32
maxlen = klen + blksz
salt = ciphertext[8:16] # 0-7 characters are Salted__
keyiv = sha256(password + salt).digest()
tmp = [keyiv]
while len(tmp) < maxlen:
tmp.append( sha256(tmp[-1] + password + salt).digest() )
keyiv += tmp[-1] # append the last byte
key = keyiv[:klen]
iv = keyiv[klen:maxlen]

cipher = AES.new(key, AES.MODE_CBC, iv)
return cipher.decrypt(ciphertext[blksz:])

stam
Posts: 2634
Joined: Sun Jun 04, 2006 9:39 pm
Location: London, UK

Re: Encryption-Decryption AES-xxx-CBC

Post by stam » Sat May 14, 2022 10:12 pm

Hi Mark,
I'm definitely no expert but think that if you don't apply salt in LC, it applies a default value. If you apply a salt value you can probably decrypt safely knowing the cypher used and the salt/password.
Unfortunately most here will not be conversant in python or other languages - does this not work for you?

S.

markclark
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6
Joined: Thu Jan 24, 2013 4:38 pm

Re: Encryption-Decryption AES-xxx-CBC

Post by markclark » Sun May 15, 2022 10:38 pm

Thanks for the response, Stam. Sure, this is all working for me, but my goal here is to explore a little farther than the docs and to also help enable users of LiveCode to have a place to look for thing like interop questions.

For instance, using the LiveCode simple encryption example above (with password option and the LC generated salt that gets done if you don't provide your own) produces a file that decrypts without issue using the shell and simplistic openssl command on most Macs

openssl aes-256-cbc - d -in pathtoencrypted -out pathtodecrypted

but causes an error on recent versions of Linux. A trivial decrypt fails with: *** WARNING : deprecated key derivation used.
> Using -iter or -pbkdf2 would be better.

I suggested my friend try the following openssl command instead, and it worked without issue--

openssl aes-256-cbc -d -md md5 -in /Users/yourpath/Desktop/stuff.txt.enc -out /Users/yourpath/Desktop/decrypted.txt

Notice that this sort of points to the q about the python snippet above (you don't have to do python to intuit the var names):
keyiv = sha256(password + salt).digest()

We don't seem to have the means to affect the key derivation function or determine which message digest to use. Guess that's okay, but I'm just trying to fill in some blanks on the docs we are provided.

Here is the link to the official openssl wiki page for key derivation: https://wiki.openssl.org/index.php/EVP_Key_Derivation

There are likely to be use cases for deriving keys from passwords for a long time into the future, but for machine to machine messaging I prefer to just use keys and no passwords.

Meantime if anyone has any comments re our KDF or possibly any future plans would love to learn more.

markclark
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 6
Joined: Thu Jan 24, 2013 4:38 pm

Re: Encryption-Decryption AES-xxx-CBC

Post by markclark » Fri May 20, 2022 6:24 pm

When using LiveCode to encrypt and no IV, if you run into a python user who is unsure what to use, it's just null

iv = blksz * b'\0'

To handle padding when decrypting, let them know that something like this should work:

unpad_algo = lambda s: s[:-ord(s[len(s) - 1:])]

Post Reply

Return to “Off-Topic”