0
$\begingroup$

I developed an application that stores large files. Those files are stored in plain text. Now the project owner wants those files be encrypted on storage, he wants confidentiality, integrity, and authenticity.

The application is written in C# using .NET Framework 4.8. There are no authenticated encryption stream cyphers in .NET Framework 4.8, so I need to create my homemade solution. I'm not a crypto guy, so I'm not sure if the solution is secure enough.

I have a secret RSA key pair acting as the master key. then I do the following to encrypt the source clear text file into the encrypted destination file (in pseudo-code):

aes_key = generate_random_number()
initial_iv = generate_random_number()
hmac_key = generate_random_number()
initial_nonce = generate_random_number()

header = aes_key || initial_iv || hmac_key || initial_nonce
cipher_header = rsa_encrypt(header)
write_to_file(encrypted_file, cipher_header)
header_signature = rsa_sign(header)
cipher_header_signature = rsa_encrypt(header_signature)
write_to_file(encrypted_file, cipher_header_signature)

chunk_number = 0

while not end of source_file
   clear_chunk = read_chunk_from_file(source_file)
   iv = initial_iv xor chunk_number
   cipher_chunk = aes_encrypt(aes_key, iv, clear_chunk)
   nonce = initial_nonce xor chunk_number
   tag = hmac(hmac_key, nonce || cipher_chunk)
   write_to_file(encrypted_file, tag)
   write_to_file(encrypted_file, cipher_chunk)
   chunk_number = chunk_number + 1
end while

Is this approach secure? What best practices I'm not following?

$\endgroup$
18
  • $\begingroup$ What does aes_encrypt do, as a 3-argument function? $\endgroup$
    – Mikero
    Dec 23, 2023 at 14:41
  • $\begingroup$ If authentication is important, why not implement AES-GCM or some other authenticated encryption mode instead of creating your own? Also take a look for any third-party libraries. $\endgroup$ Dec 23, 2023 at 14:51
  • $\begingroup$ @EugeneStyer AES-GCM is available in .NET core but not in.NET Fx 4.8. This is why I'm implementing my own. Also, I haven't found any third party .NET library that implements authentication encryption stream cipher. $\endgroup$ Dec 23, 2023 at 15:02
  • $\begingroup$ @Mikero aes_encrypt function encrypts the clear text (third parameter) using AES-256-CBC algorithm. It uses the first parameter as the key, the second parameter as the initialization vector, it returns the cipher text $\endgroup$ Dec 23, 2023 at 15:05
  • 1
    $\begingroup$ @MaartenBodewes. There is a question on code review codereview.stackexchange.com/questions/288754/… $\endgroup$ Jan 9 at 13:21

1 Answer 1

1
$\begingroup$

Aside from the code review, here are some high-level recommendations:

  1. Key generation: Make sure that random source follows NIST SP800-90* guidelines. In addition, for crypto keys it's good to apply an extractor to obtain uniform distribution on your key space. You may consult NIST SP800-133 for more detail, but HKDF-extract would be a good choice.

  2. For RSA encryption (i.e. key wrapping in this case), make sure you use an approved scheme RSA-OAEP. You may consult with RFC 8017 and FIPS 186-5 for more details.

  3. If you also want to sign the header, make sure you use a different RSA key than the one you used for encryption. Also, use a valid scheme for RSA signature like PSS

  4. The overall method: you encrypt the header, you sign the header, then you encrypt the signature. Please consult NIST SP 800-56B Rev. 2 for approved RSA-based methods of key wrapping. In short, you may simply encrypt/wrap the key. For authentication, you can add key confirmation by using a MAC

  5. Using AES-256-CBC encryption with HMAC integrity should be fine since you're using an encrypt-then-MAC composition per this paper. Just make sure padding is handled properly in CBC mode.

  6. Pay attention to key sizes. This may depend on your security-level needs and which standards you wish to follow. If you want to follow CNSA 1.0 for example (assuming you're not looking at PQ), they recommend a minimum of RSA-3072 and SHA-384.

$\endgroup$
4
  • 1
    $\begingroup$ Key generation: I will use HKDF as you suggested. $\endgroup$ Dec 24, 2023 at 9:36
  • 1
    $\begingroup$ RSA encryption: I'm using PKCS#1 v1.5 but I will use RSA-OAEP-SHA-512 $\endgroup$ Dec 24, 2023 at 9:41
  • $\begingroup$ The overall method. I don't understand NIST SP 800-56B Rev. 2. How to add key confirmation by using a MAC? I don't understand what should be MAC'ed. $\endgroup$ Dec 24, 2023 at 9:46
  • $\begingroup$ looking at your case, key confirmation w/ MAC may not be applicable to you. Usually, this happens between 2 separate parties where sending party wants to confirm that receiving party indeed got the right key. In your case, you're one and the same. $\endgroup$
    – hlayhel
    Dec 26, 2023 at 21:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.