AES Algorithms
This is a quick chat of mine with Bing AI. I reckoned it might be useful to others too. Enjoy.
AES Algorithms
There are different modes of operation for AES-256, which is a symmetric-key encryption algorithm that uses a 256-bit key. The choice of mode depends on the security and performance requirements of the application. Some of the common modes are:
- CBC (Cipher Block Chaining): This mode encrypts each block of plaintext by XORing it with the previous ciphertext block. It requires an initialization vector (IV) to start the process. It provides confidentiality but not integrity or authentication¹.
- CTR (Counter): This mode converts AES-256 into a stream cipher by generating a keystream from a nonce and a counter. It XORs the keystream with the plaintext to produce the ciphertext. It allows parallel encryption and decryption, and random access to the ciphertext. It also provides confidentiality but not integrity or authentication¹.
- GCM (Galois/Counter Mode): This mode is an authenticated encryption mode that combines CTR mode with a message authentication code (MAC) based on Galois field arithmetic. It provides confidentiality, integrity and authentication, and is widely used in secure communication protocols¹².
- XTS (XEX-based Tweaked-codebook mode with Ciphertext Stealing): This mode is designed for disk encryption and encrypts each sector of data with a different key derived from the original key and the sector number. It provides confidentiality and preserves the length of the plaintext. It also allows random access to the ciphertext¹³.
- OCB (Offset Codebook): This mode is another authenticated encryption mode that combines a tweakable block cipher with a MAC. It provides confidentiality, integrity and authentication, and has high efficiency and low overhead. However, it is patented and may require a license to use¹⁴.
There is no definitive answer to which mode is the best, as different modes have different advantages and disadvantages. However, some general criteria to consider are:
- Security: The mode should resist known attacks and provide the desired level of security services (such as confidentiality, integrity, authentication, etc.).
- Performance: The mode should have low computational cost, memory usage, and latency, and high throughput and parallelism.
- Compatibility: The mode should be compatible with the existing standards, protocols, and platforms that are used by the application.
- Usability: The mode should be easy to use correctly and hard to use incorrectly, and should not impose unrealistic requirements on the users (such as generating random IVs or nonces, managing keys, etc.).
Based on these criteria, some possible rankings of the modes are:
- If security and performance are the main concerns, and compatibility and usability are not issues, then OCB might be the best choice, followed by GCM, CTR, CBC, and XTS.
- If security and compatibility are the main concerns, and performance and usability are not issues, then GCM might be the best choice, followed by CTR, CBC, XTS, and OCB.
- If security and usability are the main concerns, and performance and compatibility are not issues, then GCM might be the best choice, followed by CBC, CTR, XTS, and OCB.
These rankings are not definitive, and may vary depending on the specific application and context. Therefore, it is advisable to consult the relevant standards, guidelines, and experts before choosing a mode of operation for AES-256.
Source: Conversation with Bing, 08/11/2023 (1) How to choose an AES encryption mode (CBC ECB CTR OCB CFB)?. stackoverflow.com/questions/1220751/how-to-... (2) How should we implement encryption? | ICO. ico.org.uk/for-organisations/uk-gdpr-guidan... (3) Understanding AES and RSA Encryption Algorithms. section.io/engineering-education/aes-rsa-en... (4) AES128 vs AES256 | Difference between AES 128 and AES 256. rfwireless-world.com/Terminology/Difference...
To implement AES-256 encryption and decryption in Node + TypeScript, you can use the built-in crypto module of Node. Here are some examples of how to use different modes of operation for AES-256:
- CBC (Cipher Block Chaining): You can use the
createCipheriv
andcreateDecipheriv
methods of the crypto module to create a cipher and a decipher object, respectively. You need to provide the algorithm name ('aes-256-cbc'
), the key (a 32-byte Buffer), and the initialization vector (a 16-byte Buffer) as arguments. You can then use theupdate
andfinal
methods of the cipher and decipher objects to encrypt and decrypt the data (a Buffer or a string). You can also prepend the initialization vector to the ciphertext and split it during decryption. For example¹:
import crypto from 'crypto';
const algorithm = 'aes-256-cbc';
const key = crypto.randomBytes(32); // generate a random 32-byte key
const iv = crypto.randomBytes(16); // generate a random 16-byte initialization vector
const encrypt = (data: Buffer | string) => {
const cipher = crypto.createCipheriv(algorithm, key, iv);
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
return iv.toString('hex') + ':' + encrypted.toString('hex'); // prepend the iv to the ciphertext
};
const decrypt = (data: string) => {
const [iv, encrypted] = data.split(':').map(part => Buffer.from(part, 'hex')); // split the iv and the ciphertext
const decipher = crypto.createDecipheriv(algorithm, key, iv);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
return decrypted.toString();
};
- CTR (Counter): You can use the same methods as CBC mode, but with a different algorithm name (
'aes-256-ctr'
). You also need to provide a nonce (a 12-byte Buffer) instead of an initialization vector. You can also prepend the nonce to the ciphertext and split it during decryption. For example²:
import crypto from 'crypto';
const algorithm = 'aes-256-ctr';
const key = crypto.randomBytes(32); // generate a random 32-byte key
const nonce = crypto.randomBytes(12); // generate a random 12-byte nonce
const encrypt = (data: Buffer | string) => {
const cipher = crypto.createCipheriv(algorithm, key, nonce);
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
return nonce.toString('hex') + ':' + encrypted.toString('hex'); // prepend the nonce to the ciphertext
};
const decrypt = (data: string) => {
const [nonce, encrypted] = data.split(':').map(part => Buffer.from(part, 'hex')); // split the nonce and the ciphertext
const decipher = crypto.createDecipheriv(algorithm, key, nonce);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
return decrypted.toString();
};
- GCM (Galois/Counter Mode): You can use the same methods as CTR mode, but with a different algorithm name (
'aes-256-gcm'
). You also need to get and set the authentication tag (a 16-byte Buffer) using thegetAuthTag
andsetAuthTag
methods of the cipher and decipher objects, respectively. You can also provide an additional authenticated data (AAD) Buffer as an argument to theupdate
method of the cipher and decipher objects. You can also prepend the nonce and the authentication tag to the ciphertext and split them during decryption. For example⁵:
import crypto from 'crypto';
const algorithm = 'aes-256-gcm';
const key = crypto.randomBytes(32); // generate a random 32-byte key
const nonce = crypto.randomBytes(12); // generate a random 12-byte nonce
const aad = Buffer.from('additional authenticated data'); // optional
const encrypt = (data: Buffer | string) => {
const cipher = crypto.createCipheriv(algorithm, key, nonce);
cipher.setAAD(aad); // optional
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
const tag = cipher.getAuthTag(); // get the authentication tag
return nonce.toString('hex') + ':' + tag.toString('hex') + ':' + encrypted.toString('hex'); // prepend the nonce and the tag to the ciphertext
};
const decrypt = (data: string) => {
const [nonce, tag, encrypted] = data.split(':').map(part => Buffer.from(part, 'hex')); // split the nonce, the tag, and the ciphertext
const decipher = crypto.createDecipheriv(algorithm, key, nonce);
decipher.setAuthTag(tag); // set the authentication tag
decipher.setAAD(aad); // optional
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
return decrypted.toString();
};
- XTS (XEX-based Tweaked-codebook mode with Ciphertext Stealing): You can use the same methods as CBC mode, but with a different algorithm name (
'aes-256-xts'
). You also need to provide a double-length key (a 64-byte Buffer) and a tweak value (a 16-byte Buffer) instead of an initialization vector. You can also prepend the tweak value to the ciphertext and split it during decryption. For example³:
import crypto from 'crypto';
const algorithm = 'aes-256-xts';
const key = crypto.randomBytes(64); // generate a random 64-byte key
const tweak = crypto.randomBytes(16); // generate a random 16-byte tweak value
const encrypt = (data: Buffer | string) => {
const cipher = crypto.createCipheriv(algorithm, key, tweak);
const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
return tweak.toString('hex') + ':' + encrypted.toString('hex'); // prepend the tweak value to the ciphertext
};
const decrypt = (data: string) => {
const [tweak, encrypted] = data.split(':').map(part => Buffer.from(part, 'hex')); // split the tweak value and the ciphertext
const decipher = crypto.createDecipheriv(algorithm, key, tweak);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
return decrypted.toString();
};
- OCB (Offset Codebook): This mode is not supported by the built-in crypto module of Node, as it is patented and may require a license to use. However, you can use a third-party library such as node-ocb to implement it. You need to install the library using
npm install node-ocb
and then import it in your code. You can then use theencrypt
anddecrypt
methods of the library to encrypt and decrypt the data (a Buffer or a string). You need to provide the key (a 32-byte Buffer), the nonce (a 15-byte Buffer), and optionally the AAD (a Buffer) as arguments. The methods return an object with the ciphertext and the tag properties. You can also prepend the nonce and the tag to the ciphertext and split them during decryption. For example⁴:
import ocb from 'node-ocb';
const key = crypto.randomBytes(32); // generate a random 32-byte key
const nonce = crypto.randomBytes(15); // generate a random 15-byte nonce
const aad = Buffer.from('additional authenticated data'); // optional
const encrypt = (data: Buffer | string) => {
const { ciphertext, tag } = ocb.encrypt(key, nonce, data, aad); // encrypt the data and get the ciphertext and the tag
return nonce.toString('hex') + ':' + tag.toString('hex') + ':' + ciphertext.toString('hex'); // prepend the nonce and the tag to the ciphertext
};
const decrypt = (data: string) => {
const [nonce, tag, encrypted] = data.split(':').map(part => Buffer.from(part, 'hex')); // split the nonce, the tag, and the ciphertext
const { plaintext } = ocb.decrypt(key, nonce, encrypted, tag, aad); // decrypt the ciphertext and get the plaintext
return plaintext.toString();
};
Source: Conversation with Bing, 08/11/2023 (1) How to encrypt using crypto AES in nodejs? - Stack Overflow. stackoverflow.com/questions/62299732/how-to... (2) Am I doing AES 256 encryption and decryption Node.js correctly?. stackoverflow.com/questions/52212430/am-i-d... (3) AES 256 GCM encryption decryption in nodejs - Stack Overflow. stackoverflow.com/questions/53269132/aes-25... (4) AES Encryption for NodeJS with Typescript · GitHub. gist.github.com/wish4129/f6deb23452af71f820... (5) aes256 - npm. npmjs.com/package/aes256. (6) undefined. tools.ietf.org/html/rfc3602.
what are IV, key, nonce, authtag, aad,double-length key, teak value, ciphertext, plaintext? which ones should be randomly generated and which ones should be static? which ones should be stored with the encrypted data? which ones should be securely stored? what should be the size of each? which algothim uses which ones?
Here are the definitions and properties of the terms you asked:
- IV: An initialization vector (IV) is a random or pseudo-random value that is used to start the encryption process in some modes of operation, such as CBC. It ensures that the same plaintext will not produce the same ciphertext if encrypted with the same key. It should be randomly generated and stored with the encrypted data. It does not need to be securely stored, as it is not a secret. The size of the IV depends on the block size of the cipher, which is 128 bits for AES. ¹
- Key: A key is a secret value that is used to encrypt and decrypt the data. It should be randomly generated and securely stored. It should not be stored with the encrypted data, as it would compromise the security of the encryption. The size of the key depends on the key length of the cipher, which can be 128, 192 or 256 bits for AES. ¹
- Nonce: A nonce is a number used once, which means it is a random or pseudo-random value that is used only once for encryption. It is similar to an IV, but it is used in some modes of operation, such as CTR or GCM, that do not require chaining of blocks. It ensures that the same plaintext will not produce the same ciphertext if encrypted with the same key. It should be randomly generated and stored with the encrypted data. It does not need to be securely stored, as it is not a secret. The size of the nonce depends on the mode of operation, which can be 12 or 16 bytes for CTR or GCM, respectively. ¹²
- AuthTag: An authentication tag (AuthTag) is a value that is used to verify the integrity and authenticity of the encrypted data. It is generated by some modes of operation, such as GCM or OCB, that provide authenticated encryption. It ensures that the ciphertext has not been tampered with or modified by an attacker. It should be stored with the encrypted data. It does not need to be securely stored, as it is not a secret. The size of the AuthTag depends on the mode of operation, which can be 16 bytes for GCM or OCB. ¹²⁴
- AAD: Additional authenticated data (AAD) is a value that is used to provide additional information that is not encrypted but is authenticated by the AuthTag. It is optional and can be used to provide context or metadata for the encrypted data. It should be stored with the encrypted data. It does not need to be securely stored, as it is not a secret. The size of the AAD depends on the application, but it should not be too large to avoid performance issues. ¹²⁴
- Double-length key: A double-length key is a key that has twice the length of the normal key for the cipher. It is used in some modes of operation, such as XTS, that require two independent keys for encryption. It should be randomly generated and securely stored. It should not be stored with the encrypted data, as it would compromise the security of the encryption. The size of the double-length key depends on the key length of the cipher, which can be 64, 96 or 128 bytes for AES. ¹³
- Tweak value: A tweak value is a value that is used to modify the encryption process for each block or sector of data. It is used in some modes of operation, such as XTS, that are designed for disk encryption. It ensures that the same plaintext will not produce the same ciphertext if encrypted with the same key and different sectors. It should be randomly generated and stored with the encrypted data. It does not need to be securely stored, as it is not a secret. The size of the tweak value depends on the block size of the cipher, which is 128 bits for AES. ¹³
- Ciphertext: A ciphertext is the result of encrypting a plaintext with a key and a mode of operation. It is the encrypted data that is stored or transmitted. It should not be decrypted without the proper key and mode of operation. The size of the ciphertext depends on the size of the plaintext and the mode of operation, but it is usually the same or slightly larger than the plaintext. ¹
- Plaintext: A plaintext is the original data that is encrypted with a key and a mode of operation. It is the data that is intended to be protected from unauthorized access or modification. It should not be exposed or revealed without the proper key and mode of operation. The size of the plaintext depends on the application, but it should not be too large to avoid performance issues. ¹
The following table summarizes which algorithm uses which terms:
Algorithm | IV | Key | Nonce | AuthTag | AAD | Double-length key | Tweak value | Ciphertext | Plaintext |
AES-256-CBC | Yes | Yes | No | No | No | No | No | Yes | Yes |
AES-256-CTR | No | Yes | Yes | No | No | No | No | Yes | Yes |
AES-256-GCM | No | Yes | Yes | Yes | Yes | No | No | Yes | Yes |
AES-256-XTS | No | No | No | No | No | Yes | Yes | Yes | Yes |
AES-256-OCB | No | Yes | Yes | Yes | Yes | No | No | Yes | Yes |
Here is a table that compares the terms you asked by the questions you asked:
Term | Definition | Random or static | Stored with encrypted data | Securely stored | Size | Used by |
IV | A random or pseudo-random value that is used to start the encryption process in some modes of operation, such as CBC. | Random | Yes | No | 128 bits | AES-256-CBC |
Key | A secret value that is used to encrypt and decrypt the data. | Random | No | Yes | 128, 192 or 256 bits | All algorithms |
Nonce | A number used once, which means it is a random or pseudo-random value that is used only once for encryption. It is similar to an IV, but it is used in some modes of operation, such as CTR or GCM, that do not require chaining of blocks. | Random | Yes | No | 12 or 16 bytes | AES-256-CTR, AES-256-GCM, AES-256-OCB |
AuthTag | A value that is used to verify the integrity and authenticity of the encrypted data. It is generated by some modes of operation, such as GCM or OCB, that provide authenticated encryption. | Generated | Yes | No | 16 bytes | AES-256-GCM, AES-256-OCB |
AAD | Additional authenticated data that is used to provide additional information that is not encrypted but is authenticated by the AuthTag. It is optional and can be used to provide context or metadata for the encrypted data. | Static or dynamic | Yes | No | Variable | AES-256-GCM, AES-256-OCB |
Double-length key | A key that has twice the length of the normal key for the cipher. It is used in some modes of operation, such as XTS, that require two independent keys for encryption. | Random | No | Yes | 64, 96 or 128 bytes | AES-256-XTS |
Tweak value | A value that is used to modify the encryption process for each block or sector of data. It is used in some modes of operation, such as XTS, that are designed for disk encryption. | Random | Yes | No | 128 bits | AES-256-XTS |
Ciphertext | The result of encrypting a plaintext with a key and a mode of operation. It is the encrypted data that is stored or transmitted. | Generated | Yes | No | Same or slightly larger than plaintext | All algorithms |
Plaintext | The original data that is encrypted with a key and a mode of operation. It is the data that is intended to be protected from unauthorized access or modification. | Static or dynamic | No | No | Variable | All algorithms |
Source: Conversation with Bing, 08/11/2023 (1) Advanced Encryption Standard - Wikipedia. en.wikipedia.org/wiki/Advanced_Encryption_S... (2) Cyber security glossary - NHS Digital. digital.nhs.uk/cyber-and-data-security/abou... (3) AES 256-bit encryption - Avira Glossary of Terms in IT Security. avira.com/en/security-wordbook/aes-256-bit-... (4) AES 256 Encryption: What Is AES 256 Encryption - Kiteworks. kiteworks.com/risk-compliance-glossary/aes-... (5) AES-256 Encryption - Everything You Need to Know - AppSealing. appsealing.com/aes-256-encryption.