I've got a client/server app that I'm working on where I've got the
client and server successfully communicating over either standard
sockets, or SSL. I'd like to provide a third option for using a shared
secret, and to that end I'm trying to wrap socket-based I/O streams with
CipherInputStream and CipherOutputStream.
The only way to use a simple text string (the kind of thing that users
could easily type in) for encryption that I've found is
PBEWithMD5AndDES. I can't, however, seem to get that encryption scheme
to work with "NoPadding" as an option. My current conversational
text-based communication between client and server is done using
PrintWriter and BufferedReader, and it doesn't lend itself well to
filling messages out to particular block sizes.
If I can use PBEWithMD5AndDES without padding, how can I do it? If I
wanted to use something which I know works without padding, such as
"DES/CFB32/NoPadding", is there a way to generated a key based on a text
string that will work with such a scheme?
I'm trying to learn this Java crypto/security stuff on my own, with one
book so far ("Java Security" by Scott Oaks, from O'Reilly) and whatever
I can find on the web. I'm making some progress, but I know I'm still
stumbling around a lot too, so please be gentle even if you think my
questions are too confused or the wrong questions. :)
nobody - 07 Dec 2003 10:39 GMT
> If I can use PBEWithMD5AndDES without padding, how can I do it? If I
> wanted to use something which I know works without padding, such as
> "DES/CFB32/NoPadding", is there a way to generated a key based on a text
> string that will work with such a scheme?
byte[] bytes = password.getBytes("UTF-8");
bytes = MessageDigest.getInstance("MD5").digest(bytes);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(bytes));
This will take the MD5 digest of the password to get 16 bytes; the first
8 will be used as key material. For a more general approach you can do:
SecretKey key = new SecretKeySpec(bytes, "<algorithm name>");
You will have to trim the key material to the appropriate length for
<algorithm name> (e.g., 8 bytes for DES). If you need a key length >
128 bits, you could use SHA-1 (160 bits) or SHA-256 (256 bits) to
generate material from the password.
Eric
Kerry Shetline - 07 Dec 2003 14:13 GMT
Thanks!
I imagine a good idea might also be to use random "salt" such as I'd use
with PBEWithMD5AndDES, doing something like XORing the salt bytes with
the bytes I get from the password String, or perhaps something even more
elaborate.
Eric wrote:
> byte[] bytes = password.getBytes("UTF-8");
> bytes = MessageDigest.getInstance("MD5").digest(bytes);
> SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
> SecretKey key = factory.generateSecret(new DESKeySpec(bytes));
> ...
nobody - 07 Dec 2003 18:53 GMT
> Thanks!
>
> I imagine a good idea might also be to use random "salt" such as I'd use
> with PBEWithMD5AndDES, doing something like XORing the salt bytes with
> the bytes I get from the password String, or perhaps something even more
> elaborate.
Yes; the easiest way might be simply to send the salt through the digest
as well, e.g.:
byte[] bytes = password.getBytes("UTF-8");
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(bytes);
byte[] salt = <some random bytes>;
bytes = md5.digest(salt);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(bytes));
Eric
Pat Farrell - 08 Dec 2003 18:20 GMT
>PBEWithMD5AndDES. I can't, however, seem to get that encryption scheme
>to work with "NoPadding" as an option.
Why would you want no padding? Or maybe, what do you mean no padding?
DES is a block cipher. It only does 8 byte blocks. You must pad the
input stream to be an intergral number of 8 bytes (octets).
The DES key is defined as 56 bits taken from the high order
bits of a eight byte block. It also has to be padded out to
eight bytes.
The normal way to covert a user entered Ascii text string into
a decent DES key is to push it thru a hash, in the olden days, MD5
more recently SHA1.
A related question is why are you using DES? it is completely
obsolete. Use AES1. And use SHA1 for your hash.
Pat http://www.pfarrell.com/prc/