Initialization Vector for 3DES

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have written a simple cryptography utility using VS2005 that enccrypts
strings or files using RSA or 3DES. I have no idea how to deal with
remembering the initialization vector [iv] when using 3DES. I currently
generate the IV using the RNGCryptoServiceProvider I then write the IV, in
plain text, to the first line of the encrypted file. [To decrypt I read the
IV then stream all stream all remaining bytes]

How can I keep the IV a secret while not having to "remember it" [Ideally, I
would be able to derive it based on my passphrase]

Thanks for any help with this matter.
 
katzky said:
I have written a simple cryptography utility using VS2005 that enccrypts
strings or files using RSA or 3DES. I have no idea how to deal with
remembering the initialization vector [iv] when using 3DES. I currently
generate the IV using the RNGCryptoServiceProvider I then write the IV, in
plain text, to the first line of the encrypted file. [To decrypt I read the
IV then stream all stream all remaining bytes]

How can I keep the IV a secret while not having to "remember it" [Ideally, I
would be able to derive it based on my passphrase]

Thanks for any help with this matter.

Well, you could use the MD5 hash of your pass phrase easily enough...
 
Wouldn't the MD5 hash the passphrase to the same 128 bits everytime? My
understanding is that the point of the IV is to ensure that the first block
would always produce a unique value. [To help prevent know plain text
attacks against the data]

I thought maybe I could use the RandomBytes as the IV. Write the clear-text
IV in hex format + the cipher text created with the passphrase & iv. Then I
could re-encrypt the ciphertext using the passphrase and the IV=MD5 hash.
I suppose this would help alleviate the problems of the known-plain-text
attack since the first 128 bits would always be unique.

Does this make sense?

Jon Skeet said:
katzky said:
I have written a simple cryptography utility using VS2005 that enccrypts
strings or files using RSA or 3DES. I have no idea how to deal with
remembering the initialization vector [iv] when using 3DES. I currently
generate the IV using the RNGCryptoServiceProvider I then write the IV,
in
plain text, to the first line of the encrypted file. [To decrypt I read
the
IV then stream all stream all remaining bytes]

How can I keep the IV a secret while not having to "remember it"
[Ideally, I
would be able to derive it based on my passphrase]

Thanks for any help with this matter.

Well, you could use the MD5 hash of your pass phrase easily enough...
 
katzky said:
I have written a simple cryptography utility using VS2005 that
enccrypts
strings or files using RSA or 3DES. I have no idea how to deal with
remembering the initialization vector [iv] when using 3DES. I
currently
generate the IV using the RNGCryptoServiceProvider I then write the
IV, in
plain text, to the first line of the encrypted file. [To decrypt I
read the
IV then stream all stream all remaining bytes]

How can I keep the IV a secret while not having to "remember it"
[Ideally, I

There is no need to make the IV secret. It is just some random data used
to initialize the en/decryption routine. Making it public does not make
your routine less secure. The reason is that the default mode for secret
key cryptography in .NET is Cipher Block Chaining which means that the
data is split into blocks and each block is encrypted. Before the
encryption occurs a block is combined (using XOR) with the result of the
encryption of the previous block. This is done because some cleartext
can have repeated data which would show up as repeated data in the
encrypted data. Combining the cleartext with the last encrypted block
means that repeated ciphertext does not result from repeated cleartext.
Using the encrypted previous block and the XOR operation means that the
combination can be reversed in the decryption routine. However, there is
the problem of what to combine the first block with. This is what the IV
is used for.

Knowing the IV does not mean that an attacker can decrypt any of the
encrypted data. Think about it: decryption must start at the end, where
the last block and last-but-one block are known. The last block is
decrypted and then XORed with the last-but-one block to get the
cleartext. In other words, the 'IV' for the last block is there in the
ciphertext. And the same can be said for all blocks except the first
one, where the IV you provide is XORed with the decrypted block to get
the cleartext.

See section 10 of my security tutorial:

http://www.grimes.demon.co.uk/workshops/securityWS.htm

Richard
 
Kevin Richardson said:
Wouldn't the MD5 hash the passphrase to the same 128 bits everytime? My
understanding is that the point of the IV is to ensure that the first block
would always produce a unique value. [To help prevent know plain text
attacks against the data]

Ah, I thought you were only encrypting once for a given passkey. Sorry,
didn't read the question fully.
I thought maybe I could use the RandomBytes as the IV. Write the clear-text
IV in hex format + the cipher text created with the passphrase & iv. Then I
could re-encrypt the ciphertext using the passphrase and the IV=MD5 hash.
I suppose this would help alleviate the problems of the known-plain-text
attack since the first 128 bits would always be unique.

Well, I'm not sure how much benefit keeping the IV a secret actually
is, so long as it varies. I *believe* that anything which isn't secure
when just the key is unknown but using a varying IV is insecure in
general. I think writing the IV in plain text (having randomly
generated it) is reasonable.

I don't think adding the extra layer you describe above actually
improves things significantly.

My reading of http://en.wikipedia.org/wiki/Initialization_vector
suggests it's okay to have it in the clear, anyway - but I am *not* a
security expert.
 
Jon said:
My reading of http://en.wikipedia.org/wiki/Initialization_vector
suggests it's okay to have it in the clear, anyway - but I am *not* a
security expert.

I explained this in another posting. Basically since CBC is a chaining
mechanism it means that the IV for all blocks except the first one is
the last encrypted block, which you have anyway; since the first block
does not follow a previously encrypted block you have to have some
random data, and this is what the IV is used for. There are no security
implications in making the IV public.

Richard
 
Thanks for the advice. I am going to keep my current mesage format [with the
Iv in plain text]


Richard Grimes said:
katzky said:
I have written a simple cryptography utility using VS2005 that
enccrypts
strings or files using RSA or 3DES. I have no idea how to deal with
remembering the initialization vector [iv] when using 3DES. I
currently
generate the IV using the RNGCryptoServiceProvider I then write the
IV, in
plain text, to the first line of the encrypted file. [To decrypt I
read the
IV then stream all stream all remaining bytes]

How can I keep the IV a secret while not having to "remember it"
[Ideally, I

There is no need to make the IV secret. It is just some random data used
to initialize the en/decryption routine. Making it public does not make
your routine less secure. The reason is that the default mode for secret
key cryptography in .NET is Cipher Block Chaining which means that the
data is split into blocks and each block is encrypted. Before the
encryption occurs a block is combined (using XOR) with the result of the
encryption of the previous block. This is done because some cleartext
can have repeated data which would show up as repeated data in the
encrypted data. Combining the cleartext with the last encrypted block
means that repeated ciphertext does not result from repeated cleartext.
Using the encrypted previous block and the XOR operation means that the
combination can be reversed in the decryption routine. However, there is
the problem of what to combine the first block with. This is what the IV
is used for.

Knowing the IV does not mean that an attacker can decrypt any of the
encrypted data. Think about it: decryption must start at the end, where
the last block and last-but-one block are known. The last block is
decrypted and then XORed with the last-but-one block to get the
cleartext. In other words, the 'IV' for the last block is there in the
ciphertext. And the same can be said for all blocks except the first
one, where the IV you provide is XORed with the decrypted block to get
the cleartext.

See section 10 of my security tutorial:

http://www.grimes.demon.co.uk/workshops/securityWS.htm

Richard
 
Back
Top