04: Learning Confidentiality with Symmetric Encryption

04: Learning Confidentiality with Symmetric Encryption

 
Symmetric Encryption
 
  • Symmetric encryption is used for encrypting data with 1 encryption key.
  • Encryption key is not the same as password, but the key can be derived from a password.
  • Encryption or encryption related alogirthm is also called a cipher.
  • Data to be encrypted is called plaintext.
  • The result of encryption on plaintext is called ciphertext.
  • In order to encrypt plaintext you need to:
    • Chose an encryption algorithm
    • Generate encryption Key
    • Generate initialization vector or IV
    • Chose cipher operation mode
    • Chose padding type
    • Encrypt plaintext with cipher, key and padding using the cipher operation mode.
 
Symmtric Encryption Type: Block Cipher
 
  • Operates on blocks of data
  • A popular cipher is AES or Advanced Encryption Standard
  • Block size of 128 bits
  • Cipher encrypts or decrypts in 128-bit blocks
  • If the plaintext is not a multiple of the block size, then the last block is usually padded up to the block size according to the chosen padding type.
 
Symmtric Encryption Type: Stream Cipher
 
  • Operate on single bytes or even bits of data
  • Do not need padding
  • Stream cipher generates a so-called pseudorandom cipher digit stream or keystream, based on the encryption key and the IV or nonce (number used once)
 
Symmetric Cipher Security Considerations
 
  • If an attacker needs to perform 2^256 computational operations to break the cipher then the cipher security is 256 bits.
  • Maximum amount of security bits a cipher can have is the length of the used encryption key.
  • If a cipher uses a 256-bit encryption key its strength is no more than 256 bits.
  • If the key length is 256 bits then there are 2^256 possible encryption keys that can be used with the current cipher.
  • A computational operation does not mean a very basic CPU operation, but a complete attempt at decrypting a small amount of ciphertext.
  • Computational complexity grows exponentially depending on the key length.
  • As of 2021 the recommendation of the NIST is
    • 112 bits of security should be enough until 2030
    • 128 bits of security should be enough until the next breakthrough in technology
 
Openssl to list all encryption algorithms
 
openssl list -cipher-algorithms
 
See openssl code example
#openssl list -cipher-algorithms Legacy: AES-128-CBC id-aes128-CCM AES-128-CFB AES-128-CFB1 AES-128-CFB8 AES-128-CTR AES-128-ECB id-aes128-GCM AES-128-OCB AES-128-OFB AES-128-XTS AES-192-CBC id-aes192-CCM AES-192-CFB AES-192-CFB1 AES-192-CFB8 AES-192-CTR AES-192-ECB id-aes192-GCM AES-192-OCB AES-192-OFB AES-256-CBC id-aes256-CCM AES-256-CFB AES-256-CFB1 AES-256-CFB8 AES-256-CTR AES-256-ECB id-aes256-GCM AES-256-OCB AES-256-OFB AES-256-XTS aes128 => AES-128-CBC aes128-wrap => id-aes128-wrap aes128-wrap-pad => id-aes128-wrap-pad aes192 => AES-192-CBC aes192-wrap => id-aes192-wrap aes192-wrap-pad => id-aes192-wrap-pad aes256 => AES-256-CBC aes256-wrap => id-aes256-wrap aes256-wrap-pad => id-aes256-wrap-pad ARIA-128-CBC ARIA-128-CCM ARIA-128-CFB ARIA-128-CFB1 ARIA-128-CFB8 ARIA-128-CTR ARIA-128-ECB ARIA-128-GCM ARIA-128-OFB ARIA-192-CBC ARIA-192-CCM ARIA-192-CFB ARIA-192-CFB1 ARIA-192-CFB8 ARIA-192-CTR ARIA-192-ECB ARIA-192-GCM ARIA-192-OFB ARIA-256-CBC ARIA-256-CCM ARIA-256-CFB ARIA-256-CFB1 ARIA-256-CFB8 ARIA-256-CTR ARIA-256-ECB ARIA-256-GCM ARIA-256-OFB aria128 => ARIA-128-CBC aria192 => ARIA-192-CBC aria256 => ARIA-256-CBC bf => BF-CBC BF-CBC BF-CFB BF-ECB BF-OFB blowfish => BF-CBC CAMELLIA-128-CBC CAMELLIA-128-CFB CAMELLIA-128-CFB1 CAMELLIA-128-CFB8 CAMELLIA-128-CTR CAMELLIA-128-ECB CAMELLIA-128-OFB CAMELLIA-192-CBC CAMELLIA-192-CFB CAMELLIA-192-CFB1 CAMELLIA-192-CFB8 CAMELLIA-192-CTR CAMELLIA-192-ECB CAMELLIA-192-OFB CAMELLIA-256-CBC CAMELLIA-256-CFB CAMELLIA-256-CFB1 CAMELLIA-256-CFB8 CAMELLIA-256-CTR CAMELLIA-256-ECB CAMELLIA-256-OFB camellia128 => CAMELLIA-128-CBC camellia192 => CAMELLIA-192-CBC camellia256 => CAMELLIA-256-CBC cast => CAST5-CBC cast-cbc => CAST5-CBC CAST5-CBC CAST5-CFB CAST5-ECB CAST5-OFB ChaCha20 ChaCha20-Poly1305 des => DES-CBC DES-CBC DES-CFB DES-CFB1 DES-CFB8 DES-ECB DES-EDE DES-EDE-CBC DES-EDE-CFB des-ede-ecb => DES-EDE DES-EDE-OFB DES-EDE3 DES-EDE3-CBC DES-EDE3-CFB DES-EDE3-CFB1 DES-EDE3-CFB8 des-ede3-ecb => DES-EDE3 DES-EDE3-OFB DES-OFB des3 => DES-EDE3-CBC des3-wrap => id-smime-alg-CMS3DESwrap desx => DESX-CBC DESX-CBC id-aes128-CCM id-aes128-GCM id-aes128-wrap id-aes128-wrap-pad id-aes192-CCM id-aes192-GCM id-aes192-wrap id-aes192-wrap-pad id-aes256-CCM id-aes256-GCM id-aes256-wrap id-aes256-wrap-pad id-smime-alg-CMS3DESwrap idea => IDEA-CBC IDEA-CBC IDEA-CFB IDEA-ECB IDEA-OFB rc2 => RC2-CBC rc2-128 => RC2-CBC rc2-40 => RC2-40-CBC RC2-40-CBC rc2-64 => RC2-64-CBC RC2-64-CBC RC2-CBC RC2-CFB RC2-ECB RC2-OFB RC4 RC4-40 RC4-HMAC-MD5 seed => SEED-CBC SEED-CBC SEED-CFB SEED-ECB SEED-OFB sm4 => SM4-CBC SM4-CBC SM4-CFB SM4-CTR SM4-ECB SM4-OFB Provided: ChaCha20-Poly1305 @ default { 2.16.840.1.101.3.4.1.4, AES-128-CFB } @ default { 1.2.410.200046.1.1.38, ARIA-192-CCM } @ default { 1.2.410.200046.1.1.1, ARIA-128-ECB } @ default { 2.16.840.1.101.3.4.1.2, AES-128-CBC, AES128 } @ default { 2.16.840.1.101.3.4.1.24, AES-192-CFB } @ default { 1.2.392.200011.61.1.1.1.2, CAMELLIA-128-CBC, CAMELLIA128 } @ default { 1.2.392.200011.61.1.1.1.4, CAMELLIA-256-CBC, CAMELLIA256 } @ default { 1.2.410.200046.1.1.35, ARIA-192-GCM } @ default { 2.16.840.1.101.3.4.1.42, AES-256-CBC, AES256 } @ default { 2.16.840.1.101.3.4.1.28, AES-192-WRAP-PAD, AES192-WRAP-PAD, id-aes192-wrap-pad } @ default { 1.2.410.200046.1.1.36, ARIA-256-GCM } @ default { 1.3.111.2.1619.0.1.2, AES-256-XTS } @ default { 2.16.840.1.101.3.4.1.8, AES-128-WRAP-PAD, AES128-WRAP-PAD, id-aes128-wrap-pad } @ default { 1.2.840.113549.1.9.16.3.6, DES3-WRAP, id-smime-alg-CMS3DESwrap } @ default { 2.16.840.1.101.3.4.1.48, AES-256-WRAP-PAD, AES256-WRAP-PAD, id-aes256-wrap-pad } @ default { 1.2.156.10197.1.104.3, SM4-OFB, SM4-OFB128 } @ default { 2.16.840.1.101.3.4.1.25, AES-192-WRAP, AES192-WRAP, id-aes192-wrap } @ default { 2.16.840.1.101.3.4.1.41, AES-256-ECB } @ default { 0.3.4401.5.3.1.9.49, CAMELLIA-256-CTR } @ default { 1.2.410.200046.1.1.2, ARIA-128-CBC, ARIA128 } @ default { 2.16.840.1.101.3.4.1.6, aes-128-gcm, id-aes128-GCM } @ default { 0.3.4401.5.3.1.9.41, CAMELLIA-256-ECB } @ default { 2.16.840.1.101.3.4.1.44, AES-256-CFB } @ default { 1.2.156.10197.1.104.4, SM4-CFB, SM4-CFB128 } @ default { 0.3.4401.5.3.1.9.4, CAMELLIA-128-CFB } @ default { 1.2.410.200046.1.1.39, ARIA-256-CCM } @ default { 1.2.410.200046.1.1.14, ARIA-256-OFB } @ default { 2.16.840.1.101.3.4.1.46, aes-256-gcm, id-aes256-GCM } @ default { 0.3.4401.5.3.1.9.9, CAMELLIA-128-CTR } @ default { 2.16.840.1.101.3.4.1.23, AES-192-OFB } @ default { 1.2.156.10197.1.104.1, SM4-ECB } @ default { 2.16.840.1.101.3.4.1.7, aes-128-ccm, id-aes128-CCM } @ default { 2.16.840.1.101.3.4.1.47, aes-256-ccm, id-aes256-CCM } @ default { 1.2.410.200046.1.1.7, ARIA-192-CBC, ARIA192 } @ default { 2.16.840.1.101.3.4.1.45, AES-256-WRAP, AES256-WRAP, id-aes256-wrap } @ default { 1.2.410.200046.1.1.15, ARIA-256-CTR } @ default { 1.2.410.200046.1.1.3, ARIA-128-CFB } @ default { 1.2.410.200046.1.1.34, ARIA-128-GCM } @ default { 1.2.410.200046.1.1.6, ARIA-192-ECB } @ default { 2.16.840.1.101.3.4.1.26, aes-192-gcm, id-aes192-GCM } @ default { 0.3.4401.5.3.1.9.29, CAMELLIA-192-CTR } @ default { 0.3.4401.5.3.1.9.43, CAMELLIA-256-OFB } @ default { 1.2.156.10197.1.104.2, SM4, SM4-CBC } @ default { 1.2.410.200046.1.1.37, ARIA-128-CCM } @ default { 2.16.840.1.101.3.4.1.22, AES-192-CBC, AES192 } @ default { 2.16.840.1.101.3.4.1.27, aes-192-ccm, id-aes192-CCM } @ default { 1.3.14.3.2.17, DES-EDE, DES-EDE-ECB } @ default { 1.2.410.200046.1.1.11, ARIA-256-ECB } @ default { 1.3.111.2.1619.0.1.1, AES-128-XTS } @ default { 2.16.840.1.101.3.4.1.5, AES-128-WRAP, AES128-WRAP, id-aes128-wrap } @ default { 2.16.840.1.101.3.4.1.3, AES-128-OFB } @ default { 0.3.4401.5.3.1.9.3, CAMELLIA-128-OFB } @ default { 0.3.4401.5.3.1.9.1, CAMELLIA-128-ECB } @ default { 1.2.840.113549.3.7, DES-EDE3-CBC, DES3 } @ default { 0.3.4401.5.3.1.9.44, CAMELLIA-256-CFB } @ default { 1.2.410.200046.1.1.10, ARIA-192-CTR } @ default { 0.3.4401.5.3.1.9.23, CAMELLIA-192-OFB } @ default { 0.3.4401.5.3.1.9.24, CAMELLIA-192-CFB } @ default { 1.2.410.200046.1.1.9, ARIA-192-OFB } @ default { 1.2.410.200046.1.1.13, ARIA-256-CFB } @ default { 2.16.840.1.101.3.4.1.1, AES-128-ECB } @ default { 1.2.410.200046.1.1.8, ARIA-192-CFB } @ default { 1.2.156.10197.1.104.7, SM4-CTR } @ default { 2.16.840.1.101.3.4.1.43, AES-256-OFB } @ default { 1.2.410.200046.1.1.4, ARIA-128-OFB } @ default { 1.2.392.200011.61.1.1.1.3, CAMELLIA-192-CBC, CAMELLIA192 } @ default { 0.3.4401.5.3.1.9.21, CAMELLIA-192-ECB } @ default { 1.2.410.200046.1.1.5, ARIA-128-CTR } @ default { 2.16.840.1.101.3.4.1.21, AES-192-ECB } @ default NULL @ default AES-128-CBC-CTS @ default AES-192-CBC-CTS @ default AES-256-CBC-CTS @ default AES-256-CFB1 @ default AES-192-CFB1 @ default AES-128-CFB1 @ default AES-256-CFB8 @ default AES-192-CFB8 @ default AES-128-CFB8 @ default AES-256-CTR @ default AES-192-CTR @ default AES-128-CTR @ default AES-256-OCB @ default AES-192-OCB @ default AES-128-OCB @ default AES-128-SIV @ default AES-192-SIV @ default AES-256-SIV @ default AES-128-GCM-SIV @ default AES-192-GCM-SIV @ default AES-256-GCM-SIV @ default { AES-256-WRAP-INV, AES256-WRAP-INV } @ default { AES-192-WRAP-INV, AES192-WRAP-INV } @ default { AES-128-WRAP-INV, AES128-WRAP-INV } @ default { AES-256-WRAP-PAD-INV, AES256-WRAP-PAD-INV } @ default { AES-192-WRAP-PAD-INV, AES192-WRAP-PAD-INV } @ default { AES-128-WRAP-PAD-INV, AES128-WRAP-PAD-INV } @ default ARIA-256-CFB1 @ default ARIA-192-CFB1 @ default ARIA-128-CFB1 @ default ARIA-256-CFB8 @ default ARIA-192-CFB8 @ default ARIA-128-CFB8 @ default CAMELLIA-128-CBC-CTS @ default CAMELLIA-192-CBC-CTS @ default CAMELLIA-256-CBC-CTS @ default CAMELLIA-256-CFB1 @ default CAMELLIA-192-CFB1 @ default CAMELLIA-128-CFB1 @ default CAMELLIA-256-CFB8 @ default CAMELLIA-192-CFB8 @ default CAMELLIA-128-CFB8 @ default { DES-EDE3, DES-EDE3-ECB } @ default DES-EDE3-OFB @ default DES-EDE3-CFB @ default DES-EDE3-CFB8 @ default DES-EDE3-CFB1 @ default DES-EDE-CBC @ default DES-EDE-OFB @ default DES-EDE-CFB @ default { 1.2.156.10197.1.104.8, SM4-GCM } @ default { 1.2.156.10197.1.104.9, SM4-CCM } @ default { 1.2.156.10197.1.104.10, SM4-XTS } @ default ChaCha20 @ default { 1.2.410.200046.1.1.12, ARIA-256-CBC, ARIA256 } @ default
 
Openssl to list all public key algorithms
 
openssl list -public-key-algorithms
 
See openssl code example
# openssl list -public-key-algorithms Legacy: Name: OpenSSL RSA method Type: Builtin Algorithm OID: rsaEncryption PEM string: RSA Name: rsa Alias for: rsaEncryption Name: OpenSSL PKCS#3 DH method Type: Builtin Algorithm OID: dhKeyAgreement PEM string: DH Name: dsaWithSHA Alias for: dsaEncryption Name: dsaEncryption-old Alias for: dsaEncryption Name: dsaWithSHA1-old Alias for: dsaEncryption Name: dsaWithSHA1 Alias for: dsaEncryption Name: OpenSSL DSA method Type: Builtin Algorithm OID: dsaEncryption PEM string: DSA Name: OpenSSL EC algorithm Type: Builtin Algorithm OID: id-ecPublicKey PEM string: EC Name: OpenSSL RSA-PSS method Type: Builtin Algorithm OID: rsassaPss PEM string: RSA-PSS Name: OpenSSL X9.42 DH method Type: Builtin Algorithm OID: X9.42 DH PEM string: X9.42 DH Name: OpenSSL X25519 algorithm Type: Builtin Algorithm OID: X25519 PEM string: X25519 Name: OpenSSL X448 algorithm Type: Builtin Algorithm OID: X448 PEM string: X448 Name: OpenSSL ED25519 algorithm Type: Builtin Algorithm OID: ED25519 PEM string: ED25519 Name: OpenSSL ED448 algorithm Type: Builtin Algorithm OID: ED448 PEM string: ED448 Name: sm2 Alias for: id-ecPublicKey Provided: Key Managers: Name: OpenSSL CMAC via EVP_PKEY implementation Type: Provider Algorithm IDs: CMAC @ default Name: OpenSSL PKCS#3 DH implementation Type: Provider Algorithm IDs: { 1.2.840.113549.1.3.1, DH, dhKeyAgreement } @ default Name: OpenSSL DSA implementation Type: Provider Algorithm IDs: { 1.2.840.10040.4.1, 1.2.840.10040.4.3, 1.3.14.3.2.12, 1.3.14.3.2.13, 1.3.14.3.2.27, DSA, DSA-old, DSA-SHA, DSA-SHA1, DSA-SHA1-old, dsaEncryption, dsaEncryption-old, dsaWithSHA, dsaWithSHA1, dsaWithSHA1-old } @ default Name: OpenSSL EC implementation Type: Provider Algorithm IDs: { 1.2.840.10045.2.1, EC, id-ecPublicKey } @ default Name: OpenSSL RSA-PSS implementation Type: Provider Algorithm IDs: { 1.2.840.113549.1.1.10, RSA-PSS, RSASSA-PSS, rsassaPss } @ default Name: OpenSSL X9.42 DH implementation Type: Provider Algorithm IDs: { 1.2.840.10046.2.1, dhpublicnumber, DHX, X9.42 DH } @ default Name: OpenSSL X25519 implementation Type: Provider Algorithm IDs: { 1.3.101.110, X25519 } @ default Name: OpenSSL X448 implementation Type: Provider Algorithm IDs: { 1.3.101.111, X448 } @ default Name: OpenSSL ED25519 implementation Type: Provider Algorithm IDs: { 1.3.101.112, ED25519 } @ default Name: OpenSSL ED448 implementation Type: Provider Algorithm IDs: { 1.3.101.113, ED448 } @ default Name: OpenSSL SM2 implementation Type: Provider Algorithm IDs: { 1.2.156.10197.1.301, SM2 } @ default Name: OpenSSL TLS1_PRF via EVP_PKEY implementation Type: Provider Algorithm IDs: TLS1-PRF @ default Name: OpenSSL HKDF via EVP_PKEY implementation Type: Provider Algorithm IDs: HKDF @ default Name: OpenSSL SCRYPT via EVP_PKEY implementation Type: Provider Algorithm IDs: { 1.3.6.1.4.1.11591.4.11, id-scrypt, SCRYPT } @ default Name: OpenSSL HMAC via EVP_PKEY implementation Type: Provider Algorithm IDs: HMAC @ default Name: OpenSSL SIPHASH via EVP_PKEY implementation Type: Provider Algorithm IDs: SIPHASH @ default Name: OpenSSL POLY1305 via EVP_PKEY implementation Type: Provider Algorithm IDs: POLY1305 @ default Name: OpenSSL RSA implementation Type: Provider Algorithm IDs: { 1.2.840.113549.1.1.1, 2.5.8.1.1, RSA, rsaEncryption } @ default
 
To see the parameters that you can use with an algorithm
 
openssl list -options <cipher>
 
See openssl code example
# openssl list -options aes-256-cbc help - list - ciphers - e - d - p - P - engine s in < k s kfile < out > pass s v - a - base64 - A - nopad - salt - nosalt - debug - bufsize s K s S s iv s md s iter p pbkdf2 - none - saltlen p rand s writerand > provider-path s provider s propquery s - -
 
Reviewing Different Types Of Cipher
 
  • AES Cipher
    • Most popular modern symmetric cipher
    • Fast and secure
    • Block cipher
    • Block size of
      • 128 → AES-128
      • 192 → AES-192
      • 256 → AES-256
    • The modern x86 and x86_64 CPUs have hardware accelration for AES called Advanced Encryption Standard New Instructions (AES-NI), making AES very fast.
    • AES uses encryption algorithm called Rijndael supporting more key sizes and block sizes than the standard AES discussed before.
  • RC4 Cipher
    • Old stream cipher that can use kley lengths from 40 to 2048 bits
    • Very popular in the past.
    • But currently many flaws were discovered
    • One of the flaws reduces the security of RC4 with 128 bit keys to just 26 bits
    • In 2013,RC4 was used as the main SSL/TLS cipher as all block cipher used in SSL 3.0 was targeted by the infamous Browser Exploit Against SSL/TLS (BEAST) attack, but RC4 being a stream cipher was not affected.
  • ChaCha20 cipher
    • Modern Stream Cipher
    • Secure and fast
    • Can be used with 128-bit or 256-bit key
    • OpenSSL supports only the 256-bit key
    • This cipher became famous when Google started to use it in their Chrome browser
    • Then support was also added to OpenSSH
    • Successor of RC4
    • ChaCha20 is faster than AES
    • Encryption of network data streams
    • One disadvantage of ChaCha20 is that it uses a block counter which is only 32-bit.
    • Secure on contiguos plaintexts that do not exceed 256 GB of data.
    • Is enough for network data streams but not enough for large files.
  • Other Well Known Ciphers
    • Blowfish → 64 bits
    • CAST5 or CAST-128 → 64 bits (Developed by Canada)
    • GOST5 → 64 bits
    • GOST89 → 64 bits (Developed By Russia)
    • IDEA → 64 bits
    • RC2 → 64 bits
    • RC5 → 64 bits
    • ARIA → 128 bit blocks (Developed By South Korea)
    • Camellia → 128 bit block
    • SEED → 128 bit block (Developed By South Korea)
    • SM4 → 128 bit block (Developed By China)
 
Different Encryption Modes For Block Cipher
 
  • This specifies how the blocks of data are chained together
  • ECB or Electronic Code Book
    • Each plaintext block is encrypted into a cipher text block using only encryption key
    • Ciphertext blocks are concatenated
    • Same plaintext always produces the same cipehrtext
    • Security issue since the patterns are preserved and can be reverse-engineered
  • CBC or Cipher Block Chain
    • The ciphertext of the current block depends on the ciphertext of the previous block
    • The 1st block is XOR-ed with an IV or a nonce
    • The rest of the blocks use the ciphertext of the previous block
    • The IV must be unpredictable for a given message to resist the Chosen Plaintext Attack
  • CTR Mode
    • Plaintext is not processed by encryption algorithm
    • Sequence of counter blocks is encrypted by the block cipher
    • Then the encrypted counter blocks are XOR-ed with the plaintext blocks. The result is our ciphertext.
    • CTR mode converts a block cipher into a stream cipher where the sequence of encrypted counter blocks is the keystream
    • The IV used in CTR mode must never be reused wit hthe same encryption key for another message. If you reuse it then the same keystream will be generated for encrypting mutiple messages.
    • Plaintext padding is not required.
    • Different plaintext blocks can be encrypted or decrypted in parallel using pre-calculated keystream
  • GCM Mode
    • Ciphertext is produced in the same way as in CTR Mode
    • Counter blocks are enrypted with block cipher forming the keystream
    • The keystream is then XOR-ed with the plaintext, producing the ciphertext.
    • Difference is GCM not only encrypts the plaintext but also authenticates the ciphertext.
    • Knowledge of the encryption key allows us to verify the integrity of the ciphertext. Basically it can detect unauthorized changes to the the ciphertext if the verification fails.
    • Each ciphertext block is converted into a number and is used in the finite field arithmetic over the Galois field together with an initial block which depends on the encryption key
    • The output of encryption in GCM mode contains IV, ciphertext, authentication tag.
    • Just like CTR, the GCM IV also needs to be unique.
    • Works on 128-bit block sizes and requires 96-bit IV.
    • To respond to this weakness Advanced Encryption Standard in Galois/Counter Mode with a Synthetic Initialization Vector was invented or AES-GCM-SIV
      • It does not take IV as a part of the input data.
      • This algorithm takes a second secret key for authentication
      • The authetnication tag is based on plaintext, additional autheticated data, authentication key. This is called the SIV.
    • This is called Authenticated Encryption or AE.
    • Can combine encrypted and unencrypted data for authentication. It is called Authenticated Encryption with Associated Data or AEAD. GCM is an AEAD.
 
What is Padding?
 
  • In CBC, block ciphers pad up the last block size, which is usually lower than the block size, to the recommended block size.
  • OpenSSL can automatically add the padding and remove the padding during encryption and decryption
  • For symmetric encryption, OpenSSL only supports PKCS7 padding.
  • It pads each remaining bytes with the value ‘N’ or 0x06
  • If the block size also matches the exact block a padding block with value 0x10 is added anyway.
  • Susceptible to padding oracle attacks.
 
Using OpenSSL To Encrypt A File in Binary Format
 
  • To achieve confidentiality we would need encryption keys.
  • Symmetric encryption uses one key for encryption and de-cryption.
  • These kind of keys are also often referred to as Secret Keys
  • Let’s generate a secret key
openssl rand -hex -out encryption.key 32
 
  • This will create a 32 bytes of randomly generated data in hex format and save it in a file called encryption.key
  • Now since we have saved this data in a file we can use it to encrypt any data you want.
    • We need to save this data because every time you use the openssl rand command to generate it will generate a new set of data. Since in symmetric encryption you need to use the same key for encryption and decryption we need to save the key so that we can use it later.
    • notion image
       
 
  • Let’s create a text file to use as example to encrypt intro.txt
notion image
 
 
  • Now let’s use openssl command to encrypt a file using Symmetric Encryption
openssl aes-256-cbc -in <plain-text-file> -out <encrypted-file> -e -kfile <encryption-key-file> openssl aes-256-cbc -in intro.txt -out intro.enc -e -kfile encryption.key
 
notion image
 
 
  • As you can see if I try to view the encrypted file intro.enc it spits out gibberish because it is encrypted and you can’t see the true contents before decrypting it.
  • Using the same Encryption Key we will now decrypt the encrypted file.
openssl aes-256-cbc -in <encrypted-file> -out <decrypted-file> -d -kfile <encryption-key> openssl aes-256-cbc -in intro.enc -out intro.dec -d -kfile encryption.key
 
notion image
 
  • You can see that the decrypted file intro.dec and the original plaintext file intro.txt are the same which means the decryption worked.
  • You can even use the diff command to make sure that the text remained and there was no loss.
 
What happens if we used cipher operation mode that did not require padding - like CTR?
 
# Generate a 128-bit IV the same length as the block size openssl rand -hex 16 63e204ba5e1f34b785be5abd218fc216 openssl enc -aes-256-ctr -K 6744471107b6238b3a8b173f119117649d51c3410545c3f8466201b00a8c99ac -iv 63e204ba5e1f34b785be5abd218fc216 -d -in intro.txt.enc -out intro.txt.dec ls -l rw-r--r-- 1 boredtoolbox staff 3 KiB Sun Feb 11 22:18:36 2024  intro.txt rw-r--r-- 1 boredtoolbox staff 3 KiB Sun Feb 11 22:48:36 2024  intro.txt.dec rw-r--r-- 1 boredtoolbox staff 3 KiB Sun Feb 11 22:20:31 2024  intro.txt.enc diff intro.txt intro.txt.dec Binary files plaintext.txt and plaintext.txt.dec differ shasum -a 256 intro.txt.dec b67eda76485fe249e4d5cce4226b62bcee7224a3d35931a652be94c889bb2a4d plaintext.txt.dec shasum -a 256 intro.txt 67d4ff71d43921d5739f387da09746f405e425b07d727e4c69d029461d1f051f plaintext.txt
 
There was no error even though we tried to decrypt using the wrong key and in the wrong mode. The checksums of the decrypted and the original file are clearly different. So what happened?
 
We were decrypting in CTR mode. Thus all the wrongly decrypted data was considered plaintext without padding. The padding was neither checked nor was it removed.
 
Thus we can see that it is quite useful to have some checksum or message digest in order to check the decryption result.
 
Using OpenSSL To Encrypt A File in Base64 Format
 
  • In the above example you could see that the encrypted file intro.enc was written in binary format.
  • You can ask openssl to write the data in base64 format using the -a option.
  • Also if you do not specify a key file openssl is going to ask you for a password to encrypt the file. It will use the same password to decrypt.
  • To Encrypt:
openssl <encryption-algorithm> -in <plain-text> -out <encrypted-file> -e -a
 
  • To Decrypt:
openssl <encryption-algorithm> -in <encrypted-file> -out <decrypted-file> -d -a
 
 
 
What is “pbkdf2”?
 
  • PBKDF2, or Password-Based Key Derivation Function 2, is a key derivation function that is commonly used for securely deriving cryptographic keys from passwords.
  • It's specifically designed to make it computationally expensive and slow to perform brute-force attacks against hashed passwords.
  • PBKDF2 applies a pseudorandom function, such as a cryptographic hash function, iteratively to the input password along with a salt.
  • A balance must be struck between making the derivation slow enough to resist brute-force attacks and making it fast enough for practical use.
  • Additionally, using a unique salt for each password ensures that even users with the same password will have different derived keys.
 
Using OpenSSL to Encrypt Data using “pbkdf2”
 
  • To Encrypt:
    • openssl aes-256-cbc -in intro.txt -out intro.enc -e -a -kfile encryption.key -pbkdf2
 
  • To Decrypt:
    •  
      openssl aes-256-cbc -in intro.enc -out intro.dec -d -a -kfile encryption.key -pbkdf2
       
      notion image
 
  • You will notice that the previous warnings have also gone.
  • OpenSSL wants you to use pbkdf2 wherever possible.
  • Also to specify the number of iterations to pbkdf2 you can use the -iter option. By default openssl uses 100k iterations.
 
Using OpenSSL to Encrypt Data using “pbkdf2” with custom iterations
 
  • To Encrypt:
openssl aes-256-cbc -in intro.txt -out intro.enc -e -a -kfile encryption.key -pbkdf2 -iter 100
 
  • To Decrypt:
openssl aes-256-cbc -in intro.enc -out intro.dec -d -a -kfile encryption.key -pbkdf2 -iter 100
 
  • The number of iterations you mentioned at the time of decryption needs to match the number of iterations at the time encryption. If it doesn’t it creates an error like:
openssl aes-256-cbc -in intro.enc -out intro.dec -d -a -kfile encryption.key -pbkdf2 -iter 500 bad decrypt 00937CE701000000:error:1C800064:Provider routines:ossl_cipher_unpadblock:bad decrypt:providers/implementations/ciphers/ciphercommon_block.c:107: