Forum Discussion
Kevin_Stewart
Mar 14, 2008Employee
AES functions
Hello Devcentral gurus,
Does anyone know the specifics of the AES functions and how they work. Specifically, look at the following code snippet:
set testkey "test"
set testdata "blah"
log local0. "aes output -> [AES::encrypt $testkey $testdata]"
I've searched and searched through the forum and perhaps I just don't understand it. The above code delivers a different result every time a new browser window is opened. I have to assume that internally AES is pulling some additional information to "seed" the result, but then why the key? I would have thought that since the AES::key function delivers a random key, everything else would be static, and entering a static key would give the same result every time. What am I missing? Say for example I am strongly encrypting something that is being sent to the user in a file-based cookie. When they come back to the site later, I would like to be able to decrypt that data. Again, am I missing something? As it stands, the AES functions don't allow that.
Thank you for your help.
Kevin
- hooleylistCirrostratusI think that the key you're testing with is invalid. For 128 bit encryption you need to use a key with 32 hexidecimal characters (Click here)
when RULE_INIT { Check if $::key is already defined and has a length if {[info exists ::key] and [string length $::key]}{ log local0. "using existing AES key: $::key" } else { The key didn't exist, so create a new 128 bit key set ::key [AES::key 128] } The key is actually a list of three elements: "AES" "key" "key_string" log local0. "list length of key: [llength $::key]" Test the encryption of a string, encoding it with base64 encoding, decode it and decrypt it. This verifies that the current version of software isn't susceptible to CR68290 / SOL7603. log local0. "Encrypt & encode test: [AES::decrypt $::key [b64decode [b64encode [AES::encrypt $::key "This should be logged in clear text"]]]]" Encrypt and encode a few test strings. The first two test strings are the same and result in the same encrypted/encoded string. set ::b64_encoded_encrypted_string_1 [b64encode [AES::encrypt $::key "test1"]] log local0. "\$::b64_encoded_encrypted_string_1: $::b64_encoded_encrypted_string_1" set ::b64_encoded_encrypted_string_2 [b64encode [AES::encrypt $::key "test1"]] log local0. "\$::b64_encoded_encrypted_string_2: $::b64_encoded_encrypted_string_2" set ::b64_encoded_encrypted_string_3 [b64encode [AES::encrypt $::key "test3"]] log local0. "\$::b64_encoded_encrypted_string_3: $::b64_encoded_encrypted_string_3" Decrypt the test strings set ::decrypted_1 [AES::decrypt $::key [b64decode $::b64_encoded_encrypted_string_1]] log local0. "\$::decrypted_1: $::decrypted_1" set ::decrypted_2 [AES::decrypt $::key [b64decode $::b64_encoded_encrypted_string_2]] log local0. "\$::decrypted_2: $::decrypted_2" set ::decrypted_3 [AES::decrypt $::key [b64decode $::b64_encoded_encrypted_string_3]] log local0. "\$::decrypted_3: $::decrypted_3" }
Rule : using existing AES key: AES 128 f97612f8dd24836405a9d9e7f69e7979 Rule : Encrypt & encode test: This should be logged in clear text Rule : list length of key: 3 Rule : $::b64_encoded_encrypted_string_1: P+SosLjL2NO1+souRy3zi0g2d3BZkd5Ire8LNveJTaQ= Rule : $::b64_encoded_encrypted_string_2: P+SosLjL2NO1+souRy3zi0g2d3BZkd5Ire8LNveJTaQ= Rule : $::b64_encoded_encrypted_string_3: P+SosLjL2NO1+souRy3ziSVAl60N6ojmK181jqBzqEw= Rule : $::decrypted_1: test1 Rule : $::decrypted_2: test1 Rule : $::decrypted_3: test3
when RULE_INIT { Cookie, which the application sets, to encrypt/decrypt set ::cookie_name "test_cookie" Log debug messages to /var/log/ltm? 1=yes, 0=no. set ::cookie_debug 1 Check if $::key is already defined and has a length if {[info exists ::key] and [string length $::key]}{ if {$::cookie_debug}{log local0. "Using existing AES key: $::key"} } else { The key didn't exist, so create a new 128 bit key set ::key [AES::key 128] if {$::cookie_debug}{log local0. "Created new AES key: $::key"} } } when HTTP_REQUEST { If the cookie exists with any value, for any requested object, try to decrypt it if {[string length [HTTP::cookie value $::cookie_name]]}{ if {$::cookie_debug}{log local0. "Original error cookie value: [HTTP::cookie value $::cookie_name]"} URI decode the value (catching any errors that occur when trying to URI decode the cookie value and save the output to cookie_uri_decoded) if {not ([catch {URI::decode [HTTP::cookie value $::cookie_name]} cookie_uri_decoded])}{ Log that the cookie was URI decoded if {$::cookie_debug}{log local0. "\$cookie_uri_decoded was set successfully"} Decrypt the value if {not ([catch {AES::decrypt $::aes_key $cookie_uri_decoded} cookie_decrypted])}{ Log the decrypted cookie value if {$::cookie_debug}{log local0. "\$cookie_decrypted: $cookie_decrypted"} } else { if {$::cookie_debug}{log local0. "Couldn't decrypt cookie: [HTTP::cookie value $::cookie_name"} } } else { if {$::cookie_debug}{log local0. "Couldn't URI decode cookie: [HTTP::cookie value $::cookie_name"} } } } when HTTP_RESPONSE { Check if response contains an error cookie with a value if {[string length [HTTP::cookie value $::cookie]] > 0}{ Log the original error cookie value from the app if {$::cookie_debug}{log local0. "Response from app contained error cookie: [HTTP::cookie value $::cookie_name]"} Encrypt the cookie value so the client can't change the value HTTP::cookie value $::cookie_name [URI::encode [AES::encrypt $::aes_key [HTTP::cookie value $::cookie_name]]] Log the encoded and encrypted error cookie value if {$::cookie_debug}{log local0. "Encrypted error cookie to: [URI::encode [AES::encrypt $::aes_key [HTTP::cookie value $::cookie_name]]]"} } }
- Kevin_StewartEmployeeAaron,
when RULE_INIT { set ::key [AES::key "128"] } when HTTP_REQUEST { set text "this is a test" log local0. "AES key: $::key" log local0. "Encrypted text: [b64encode [AES::encrypt $::key $text]] }
- hooleylistCirrostratusHi Kevin,
when RULE_INIT { set ::key [list AES 128 eaa18b3c04c914f9e2fb8a6c9e479f4f] log local0. "list length of key: [llength $::key]" log local0. "\$::key: $::key" set ::b64_encoded_encrypted_string "TLkDvsXpttnYyJBMuQO+xem22djIkDLR5Xl32d9syl8l4t+LCI+WuG4VvVKQt/b4jSOtBA==" log local0. "\$::b64_encoded_encrypted_string: $::b64_encoded_encrypted_string" log local0. "Decrypted string: [AES::decrypt $::key [b64decode $::b64_encoded_encrypted_string]]" set ::b64_encoded_encrypted_string "hhNtFA/zVoJhJz6GE20UD/NWgmEnPof2Nalx2gy6lrsFUxRsiR+bA/ivrV+zjwANgc8Hrw==" log local0. "\$::b64_encoded_encrypted_string: $::b64_encoded_encrypted_string" log local0. "Decrypted string: [AES::decrypt $::key [b64decode $::b64_encoded_encrypted_string]]" set ::b64_encoded_encrypted_string "JzTGR0I2AL+G0dYnNMZHQjYAv4bR1mAUL1SMYguNEE29thMEzliMW74hgEFQ5iu5X9ctUw==" log local0. "\$::b64_encoded_encrypted_string: $::b64_encoded_encrypted_string" log local0. "Decrypted string: [AES::decrypt $::key [b64decode $::b64_encoded_encrypted_string]]" }
Rule : list length of key: 3 Rule : adh $::key: AES 128 eaa18b3c04c914f9e2fb8a6c9e479f4f Rule : $::b64_encoded_encrypted_string: TLkDvsXpttnYyJBMuQO+xem22djIkDLR5Xl32d9syl8l4t+LCI+WuG4VvVKQt/b4jSOtBA== Rule : Decrypted string: This is a test Rule : $::b64_encoded_encrypted_string: hhNtFA/zVoJhJz6GE20UD/NWgmEnPof2Nalx2gy6lrsFUxRsiR+bA/ivrV+zjwANgc8Hrw== Rule : Decrypted string: This is a test Rule : $::b64_encoded_encrypted_string: JzTGR0I2AL+G0dYnNMZHQjYAv4bR1mAUL1SMYguNEE29thMEzliMW74hgEFQ5iu5X9ctUw== Rule : Decrypted string: This is a test
- Kevin_StewartEmployeeThanks again Aaron. I think you nailed it. I hadn't investigated the decrypt after your first response, but you're right, it does decrypt correctly despite the different encrypted message. I guess my next quest is to figure out why.
- hooleylistCirrostratusYeah, I did some quick reading on AES and encryption in general, but didn't find anything that clearly spelled out what could be happening here. If you end up figuring this out, or if someone with more cryptographic knowledge is out there, I'd like to know.
- spark_86682Historic F5 AccountAES::encrypt (and ::decrypt, naturally) uses CWC mode with both a random IV and a random salt. So it is fully expected that the same plaintext could encrypt to multiple ciphertexts. I think that answers the original question, too.
- kuhn_52743NimbostratusHi,
- spark_86682Historic F5 AccountWe've had several requests for the information needed to interact with the AES::encrypt format that we use, and will very likely be publishing this information. However, it will not be available for at least a month.
- kuhn_52743NimbostratusHi spark,
- habeebaslam_348NimbostratusHi,
Recent Discussions
Related Content
Â
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects