Skip to content

Latest commit

 

History

History
87 lines (59 loc) · 6.48 KB

aes_gcm_256_string_encryption.md

File metadata and controls

87 lines (59 loc) · 6.48 KB

Cross-platform cryptography

AES GCM mode 256 string encryption

The standard encryption algorithm is AES after it got choosen and standardized by NIST (National Institute of Standards and Technology). There are 3 main parameters that need to be equal when crossing the platforms to decrypt the ciphertext.

First parameter: the length of the key

An AES key has 3 "allowed" key lengths: 128 bit = 16 byte, 192 bit = 24 byte and 256 bits = 32 byte. Our programs will run with a fixed length of 32 byte for a maximum of security.

Second parameter: the mode of operation

There are several AES modes defined and here we are using the most secure one - the GCM mode (Galois Counter mode). This mode includes an authentication check (like a HMAC) encryption and detects any kind of tampering (see my article on AES CBC mode tampering). More information about GCM mode can be found on Wikipedia.

Third parameter: the padding of the data

The used CBC mode is a block algorithm means that the encryption (and decryption) is done in blocks of 16 bytes of data. There are only a few scenarios where you have to handle exact 16 bytes of data - in all other cases you have to fill up the plaintext to a length of multiple of 16. There are some padding algorithms available and our programs will use the PKCS#5 or PKCS#7 padding (Java names this padding PKCS#5, most other languages use PKCS#7).

Is this encryption secure?

The answer is easy - it is most secure AES mode available. It calculates a checksum (like a HMAC) and is often named as "tag" or "gcmTag". Some frameworks like Java append the tag to the ciphertext, others like PHP get the tag directly from the cipher engine. My programs always separate the tag from the ciphertext and transport it in an own (Base64 encoded) variable.

steps in the program

The program follows the usual sequence:

  1. generate a random encryption key and show the key in Base64 encoding for later usage
  2. convert the plaintext to a binary format (e.g. a byte array)
  3. starts the encryption process
  4. generate a random nonce
  5. set the encryption parameters
  6. encrypt the plaintext, prepends the nonce to the ciphertext, appends the gcmTag and show the result ( nonce:ciphertext:tag) in Base64 encoding
  7. start the decryption process
  8. Base64 decoding of the encryption key and the ciphertext
  9. split the complete ciphertext-string into nonce, ciphertext and gcmTag
  10. set the decryption parameters (same as used for encryption)
  11. decrypt the ciphertext and show the resulting plaintext

I don't provide a stand alone decryption only example because all parts are available in the full program.

Serious notice: although the program looks like simple there is NO CHANCE for recovering the original plaintext without the key used for encryption!

⚠️ Security warning ⚠️

This is a serious warning regarding the security of the programs shown in these article series. Always keep in mind my disclaimer regarding my programs: All programs are for educational purposes and are not intended to use in production or any other programs where a secure solution is needed. The programs do not have proper exceptional/error handling and in some cases they use insecure key lengths or other methods that are insecure. Never ever use the programs in real life unless checked by a qualified professional cryptographer.

The following links provide the solutions in code and an online compiler that runs the code. Unfortunately this mode is not so widely supported as the CBC mode. If you like to get a pure Javascript solution running in your browser kindly see my Webcrypto example in the article AES GCM mode PBKDF2 string encryption.

Language available Online-compiler
Java repl.it CpcJavaAesGCM256StringEncryption
PHP repl.it CpcPhpAesGCM256StringEncryption
C# *1) dotnetfiddle.net CpcCsharpAesGCM256StringEncryption
Javascript CryptoJs not available
NodeJS Crypto repl.it CpcNodeJsCryptoAesGCM256StringEncryption
NodeJS node-forge repl.it CpcNodeJsAesGCM256StringEncryption
Python *2) repl.it CpcPythonAesGCM256StringEncryption
Go *3) repl.it CpcGoAesGCM256StringEncryption
Dart no online compiler available

*1) C# needs dot.net 5 to run, so I changed my online compiler for this example.

*2) Python needs PyCryptodome

*3) Dart needs the external library pointycastle version 3.1.1

This is an output (as there are random elements your output will differ):

AES GCM 256 String encryption with random key
plaintext:  The quick brown fox jumps over the lazy dog
encryptionKey (Base64): 9EpOtX94bHDiEl3n32oBS2Q3g6PK706mxsxZeWgF7nc=

* * * Encryption * * *
ciphertext: MS6WBc0jteo/WlSv:IhnNAdqi/uff3WePSasi4EH6qSm5Dd38ZtuU4c1yEEeFg+hqImxqiyDY/g==:WxoZfgL539r+0JvBfn+DbQ==
output is (Base64) nonce : (Base64) ciphertext : (Base64) gcmTag

* * * Decryption * * *
decryptionKey (Base64): 9EpOtX94bHDiEl3n32oBS2Q3g6PK706mxsxZeWgF7nc=
ciphertext (Base64): MS6WBc0jteo/WlSv:IhnNAdqi/uff3WePSasi4EH6qSm5Dd38ZtuU4c1yEEeFg+hqImxqiyDY/g==:WxoZfgL539r+0JvBfn+DbQ==
input is (Base64) nonce : (Base64) ciphertext : (Base64) gcmTag
plaintext:  The quick brown fox jumps over the lazy dog

Last update: Nov. 06th 2021

Back to the main page: readme.md