Re: My own little replacement for the Unix crypt

From: Tom St Denis (tomstdenis_at_yahoo.com)
Date: 02/29/04


Date: 28 Feb 2004 15:51:34 -0800

beej <bj@con.sole> wrote in message news:<MPG.1aaa74047a18ee3e98a9f8@news.alt.net>...
> I wanted a simple, effective crypto program for *nix, and since 'crypt'
> is weak and everything else seems to be either commercial (expensive) or
> of questionable origin I decided to write my own. I'm not foolish
> enough to try to design a crypto algorithm, so I snagged the source for
> Skipjack and used that. Here are the basic steps my little prog
> employs. Does anyone notice any obvious or serious flaws here? How
> secure is this?

Yes. You didn't really state your goals or threat model. Therefore,
I have no idea if it's secure because I don't know what it's for.

> 1. Get the names of the source and destination files from the user.

Does it handle pipes?

> 2. Ask the user whether to encrypt or decrypt the source file.
>
> If we're encrypting...
>
> 3. Get a password from the user.

Do you echo the chars? How do you read it in? gets()? Can I specify
the password on the command line?

> 4. Run the password through SHA to create a 160-bit irreversible hash.
> 5. Use the hash to key a stream cipher.

Bad idea. Same password will always produce the same stream.

> 6. Call the stream cipher ten times, but instead of using the keystream
> to encrypt any data, use the bytes to form a key for Skipjack.

Now your skipjack key is the same for the same password.

> 7. Grab the system time and use it to initialize the stock random number
> generator that comes with Unix.

Um? rand()? What if I encrypt two files below the clock resolution?
[e.g. two processes with the same password?]

> 8. Call the stock Unix random number generator eight times, and use the
> bytes to form an initialization vector (for Cipher Block Chaining).

Ok so now I have two messages with the same CBC IV.

> 9. Read in the source file and encrypt it with Skipjack in Cipher Block
> Chaining mode, using the key and initialization vector created above.
> At the same time, form a 32-bit CRC value using the plaintext.

CRC? You already have SHA-1 handy right? [see below]

> 10. Dump the initialization vector, CRC value and ciphertext into the
> destination file.

Reasonable.

> My own thoughts:
>
> 1. The user could supply a weak password. The program doesn't directly
> use the password, so that offers a small degree of protection against a
> bad password, but it would still be possible for an attacker to guess
> passwords until the right one is found. I guess the only way to fix
> this is to have the prog enforce some password rules.

This is true of any program really. Though normally passwords don't
lead to keys (you'd randomly generate a key and use the password to
mask the password, or at least that's how I would do it).

> 2. The stock RNG routines that come with Unix are notoriously bad, but
> does that really matter for the initialization vector? The IV is
> basically meant to be "extra" data, and there's nothing random about
> data in general, so there's no point in trying to make the IV
> cryptographically strong.

I already "broke" your protocol. So yes, rand() isn't sufficient.

> 3. Can the CRC (based on the original plaintext and stored as plaintext
> with the encrypted data) be used to derive any of the original data? I
> don't see how it could... But then, I'm not a mathematician.

Yes it can. CRCs are linear so if I know plaintext blocks I can play
with them. You have SHA-1 why not make HMAC-SHA-1 out of it? That at
least is secure.

Also because your Key+IV generation is weak [so is your key
generation] I can easily make it encrypt two files with the same
key+IV.

First you should change your key generation. A simple trick is todo
the following

1. Generate a random 10 byte string, K
2. Hash the password and XOR it against K, call that MK [masked key]
3. Derive IV via IV = hash(MK || "IV")
4. Derive the HMAC key from K via HK = hash(K || "hmac")
5. Emit the MK to the dest
6. Encrypt the file with skipjack using K/IV/HK
7. Emit the HMAC-SHA-1 to the dest

This has the benefit of a stronger MAC and the IV/key are not as easy
to recycle. In fact all of the entropy [for a fixed password] comes
from K so you really only need 10 random bytes for the entire process.
 Comes with the added bonus that you don't need to store the IV
[though really MK just takes its place].

.... Or .... Just use gnupg as another poster suggested ;-)



Relevant Pages

  • Re: "incrementing" ecb mode
    ... > a block in the middle of the file without affecting the CRC. ... They would have to know the key used to encrypt the block and the key used ... The rekeying isn't a problem. ... cipher used to encrypt the plaintext. ...
    (sci.crypt)
  • Re: "incrementing" ecb mode
    ... >> to encrypt the crc. ... The crc is a crc of the plaintext, ... If they can stick chosen plaintext into the file, ... >> cipher used to encrypt the plaintext. ...
    (sci.crypt)
  • Re: Please suggest a simple 8-bit cipher
    ... >We need to encrypt short messages with only a very ... >1) The algorithm nor the keys will not be published. ... You could use eg. Skipjack in Counter ... Greg Rose ...
    (sci.crypt)