• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

Calling all Cryptographers

Graze

Senior member
I want to encrypt a file and want to know what's the best method for going about this.

In steps:

1)I will be encrypting the message using Rijndael 256. The key would be created by a randomly generated salt, IV and random passphrase using PKCS#5.

2)Once that key is created, it and the IV used to create it is then encrypted by PKCS#5 with a randomly generated salt, IV and the passphrase supplied by the user. This would then be put in the file.

3)That IV and salted used in (2) are then encrypted using Rijndael 256 with the user supplied passphrase and randomly generated IV. This IV is embedded into the file header in plain text(basically).
How does this sound folks


The reason I did things like this is because I wanted the key use to created the message to have a very strong encryption so I had to created using PKCS#5 unfortunately that called for the use of a salt and those have to be used in the decryption so then it needs to be placed in the file.

I needed to embed the key and IV used to created the message encryption into the file so of course those needed to be encrypted before being embedded. I once again used PKCS#5 and therefore had to use an IV and salt again and the user passphrase. The salt and IV now needed to be secured so I then use Rijndael 256 to do this since all it needs is an IV and user passphrase. That IV I just embedded now as a plain text.



Does this sound secure albeit convoluted? I already have the program up running. I did the code in C# for Windows and Java for everything else. I just need to know if its worthy of deployment.
 
I have built some encryption packages and as long as the location and encryption algorithm of the key within the file is not exposed to external knowledge; it should be safe.
 
It is unnecessary to encrypt the IV - it can be included in plaintext. However, encrypting it won't hurt.

What block mode do you need for the encryption. There is a risk with using CBC, as any corruption of the encrypted file can completely destroy the data beyond recovery. The use of GCM mode may be better, as this will permit random access to the file contents, and corruption in the encrypted file will only corrupt that block of the file, not the entire file.

However, passwords need some form of expansion before they can be directly used as a key. PKCS #5 is OKish, but increasingly scrypt is regarded as significantly better.

You can put the salt for the scrypt in the file, together with the IV for the AES.

Make sure that you use a strong random number generator to generate all the keys and IVs.

I would also suggest some form of hash so that the user can tell whether the password entered is correct.

Summary:
To encrypt.

Generate AES message key Km
Generate AES header IV IVh and message IVm
Generate random salt S
Compute SHA-256 hash of Km + IVm call it H1
Compute HMAC-SHA-256 of H1 using password as salt - call this H2
Collect password and expand to 256 bits using scrypt with salt S - call this Kh
Encrypt Message Pm with Km/IVm to create encrypted message Em
Encrypt Km + IVm with Kh/IVh to call it Eh
Save the S + IVh + Eh + H2 + Em to the file

To decrypt reverse the process, checking the HMAC before attempting decryption of the message. If the HMAC doesn't match, then tell the user the password is wrong.
 
Last edited:
It is unnecessary to encrypt the IV - it can be included in plaintext. However, encrypting it won't hurt.

What block mode do you need for the encryption. There is a risk with using CBC, as any corruption of the encrypted file can completely destroy the data beyond recovery. The use of GCM mode may be better, as this will permit random access to the file contents, and corruption in the encrypted file will only corrupt that block of the file, not the entire file.

However, passwords need some form of expansion before they can be directly used as a key. PKCS #5 is OKish, but increasingly scrypt is regarded as significantly better.

You can put the salt for the scrypt in the file, together with the IV for the AES.

Make sure that you use a strong random number generator to generate all the keys and IVs.

I would also suggest some form of hash so that the user can tell whether the password entered is correct.

Summary:
To encrypt.

Generate AES header key Kh, and message key Km
Generate AES header IV IVh and message IVm
Generate random salt S
Compute SHA-256 hash of Km + IVm call it H1
Compute HMAC-SHA-256 of H1 using password as salt - call this H2
Collect password and expand to 256 bits using scrypt with salt S
Encrypt Message Pm with Km/IVm to create encrypted message Em
Encrypt Km + IVm with Kh/IVh to call it Eh
Save the S + IVh + Eh + H2 + Em to the file

To decrypt reverse the process, checking the HMAC before attempting decryption of the message. If the HMAC doesn't match, then tell the user the password is wrong.

Oh I do use a HMAC-SHA-256 in step 3 of my process. I also used a CBC cihper but I would look into GCM as you suggested.
The encrypted message has an HMAC-SHA1. I did this to ensure the integrity of the message(as it might have gotten corrupted when being transferred or tampered with). Unfortunately you can only tell the users of the corruption/ incorrect password after trying to decrypt the file.

I will take all this into consideration and update my program. My header includes a version number so I will make changes and have this as file version 2 or something and leave in backward compatible with the old algorithm decryption.

Thanks for the input folks
 
I want to encrypt a file and want to know what's the best method for going about this.

In steps:

1)I will be encrypting the message using Rijndael 256. The key would be created by a randomly generated salt, IV and random passphrase using PKCS#5.

2)Once that key is created, it and the IV used to create it is then encrypted by PKCS#5 with a randomly generated salt, IV and the passphrase supplied by the user. This would then be put in the file.

3)That IV and salted used in (2) are then encrypted using Rijndael 256 with the user supplied passphrase and randomly generated IV. This IV is embedded into the file header in plain text(basically).
How does this sound folks


The reason I did things like this is because I wanted the key use to created the message to have a very strong encryption so I had to created using PKCS#5 unfortunately that called for the use of a salt and those have to be used in the decryption so then it needs to be placed in the file.

I needed to embed the key and IV used to created the message encryption into the file so of course those needed to be encrypted before being embedded. I once again used PKCS#5 and therefore had to use an IV and salt again and the user passphrase. The salt and IV now needed to be secured so I then use Rijndael 256 to do this since all it needs is an IV and user passphrase. That IV I just embedded now as a plain text.



Does this sound secure albeit convoluted? I already have the program up running. I did the code in C# for Windows and Java for everything else. I just need to know if its worthy of deployment.


Sounds like security through obscurity to me. I would keep it simple via aes-256 with a private key.

If different private keys per file are needed, then I would generate the key with random string/number generator.
 
Last edited:
OK. I've thought about this some more, and have come up with a better, simpler idea.

1. Obtain user passphrase (P).
2. Randomly generate 32 bytes of salt (S) and 16 bytes of IV.
3. Use your chosen Password expansion function to generate 96 bytes of expanded data (X) from P and S.
4. Define the AES Key (K) as X[0..31]
5. Compute the HMAC-SHA-256 of S + IV using X[32..63] as HMAC key - call this H1.
6. Encrypt message M using K and IV to yield encrypted message E
7. Compute HMAC-SHA-256 of IV + E using X[64..95] as HMAC key - call this H2.
8. Save S, IV, H1, E, H2 to the output file.

Before decrypting, verify that H1 matches. This will allow you to detect if the password is wrong.
After decrypting, verify that H2 matches, this will detect corrupted files.

IVs and Salts MUST be regenerated with a secure random number generator for every file. If salts are not regenerated for each file, it will be obvious which files use the same passphrase.

When performing the main encryption, use PKCS 7 padding, not Zero fill or ISO padding.

It is not necessary to use multiple layers of encryption; there is very little point in encrypting a 256 bit AES key with another 256 bit AES key. There is no point in encrypting an IV. The IV does not prevent breaking the encryption, it only makes it difficult to tell if a message is a duplicate.

The key derivation function is a matter of personal choice. PKCS5 (PBKDF2) is OK, but as I said earlier, scrypt is better; as you aren't intending to make a compliant PKCS5 application, then I would recommend using scrypt (suggest starting with 16384 iterations) as it is stronger.

Note that the file validation HMAC (H2) is computed on the *encrypted* data, not the plaintext. Performing HMAC on the plaintext (whether the HMAC is encrypted or not) is not optimal for security.
 
Last edited:
OK. I've thought about this some more, and have come up with a better, simpler idea.

1. Obtain user passphrase (P).
2. Randomly generate 32 bytes of salt (S) and 16 bytes of IV.
3. Use your chosen Password expansion function to generate 96 bytes of expanded data (X) from P and S.
4. Define the AES Key (K) as X[0..31]
5. Compute the HMAC-SHA-256 of S + IV using X[32..63] as HMAC key - call this H1.
6. Encrypt message M using K and IV to yield encrypted message E
7. Compute HMAC-SHA-256 of IV + E using X[64..95] as HMAC key - call this H2.
8. Save S, IV, H1, E, H2 to the output file.

Before decrypting, verify that H1 matches. This will allow you to detect if the password is wrong.
After decrypting, verify that H2 matches, this will detect corrupted files.

IVs and Salts MUST be regenerated with a secure random number generator for every file. If salts are not regenerated for each file, it will be obvious which files use the same passphrase.

When performing the main encryption, use PKCS 7 padding, not Zero fill or ISO padding.

It is not necessary to use multiple layers of encryption; there is very little point in encrypting a 256 bit AES key with another 256 bit AES key. There is no point in encrypting an IV. The IV does not prevent breaking the encryption, it only makes it difficult to tell if a message is a duplicate.

The key derivation function is a matter of personal choice. PKCS5 (PBKDF2) is OK, but as I said earlier, scrypt is better; as you aren't intending to make a compliant PKCS5 application, then I would recommend using scrypt (suggest starting with 16384 iterations) as it is stronger.

Note that the file validation HMAC (H2) is computed on the *encrypted* data, not the plaintext. Performing HMAC on the plaintext (whether the HMAC is encrypted or not) is not optimal for security.


My message is encrypted using a randomly generated password/passphrase(in the event that someone wanted to share that encrypted file with another person they would not have to give up their password) and the key is then encrypted by the user's password/phrase and placed in the file. I didn't want the salt(I know the IV is useless to someone)placed in plain text hence the encryption of that using Rijndael 256 again since that doesn't need a salt.

I am using Zero padding but that is a non issue I spent plenty of time making it so too given the fact that I am saving my Hmac at the end of the file/message(I could have done things better here but its works for now)
My Hmac.... is not performed on an encrypted message...damn. I Didn't think it would have been an issue since the Hmac is encrypted with the message itself so if you got to one you got to the other.
 
My message is encrypted using a randomly generated password/passphrase(in the event that someone wanted to share that encrypted file with another person they would not have to give up their password) and the key is then encrypted by the user's password/phrase and placed in the file. I didn't want the salt(I know the IV is useless to someone)placed in plain text hence the encryption of that using Rijndael 256 again since that doesn't need a salt.

I am using Zero padding but that is a non issue I spent plenty of time making it so too given the fact that I am saving my Hmac at the end of the file/message(I could have done things better here but its works for now)
My Hmac.... is not performed on an encrypted message...damn. I Didn't think it would have been an issue since the Hmac is encrypted with the message itself so if you got to one you got to the other.

Ah. I see. You want 2 different passphrases to have access. Your technique would work but does a lot of unnecessary work.

You don't need to encrypt the salt, if you are using a reasonable key derivation function. Like the IV, the salt doesn't contribute to security, except to ensure that the same password is not recognisable as the same.

If I were doing it, I'd choose a random binary AES key (Km), binary HMAC key (Kh) and IV. For each password, I'd include: a salt, Km encrypted with a key derived from the password, Kh encrypted with a derived key, and an appropriate HMAC for password validation

Technically, this sort of process is supported by PKCS7. However, .NET has no support for password based keys in PKCS 7, and even add on libraries like bouncy castle do not support "authenticated encryption" which would avoid the need for a separate HMAC by using AES in an "authenticating" mode.
 
Back
Top