Question on cryptography
Hi
started looking at the doc and trying out the encryption proceess.
First I created a file that contains the secretkey .
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
DESedeKeySpec keyspec = (DESedeKeySpec)keyfactory.getKeySpec(key, DESedeKeySpec.class);
byte[] rawkey = keyspec.getKey();
FileOutputStream out =new FileOutputStream(f);
out.write(rawkey);
Read the key when I needed using the following code
DataInputStream in =new DataInputStream(new FileInputStream(f));
byte[] rawkey =newbyte[(int)f.length()];
in.readFully(rawkey);
in.close();
DESedeKeySpec keyspec =new DESedeKeySpec(rawkey);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyfactory.generateSecret(keyspec);
Encrypted and decrypted the values using the same key and Cipher.init and doFinal methods.
When I encrypt the same string multiple times the byte array is printing diff values and decrypt is not bringing the original value.
Is there anything I am missing here
Pls advise
Thanks
[1512 byte] By [
a_suna] at [2007-10-2 20:09:08]

There is nothing obviously wrong with your code but I would need to see the whole to be sure.
SabreThanks for the reply, after reading more threads from the forums I realized that I do not need encryption to store password in a database and my requirement is to store password. I can use the one way hashing to store the password right?
a_suna at 2007-7-13 22:49:37 >

> I can use the one way hashing to store the password> right?Yes! But you will most probably never be able to recover the plane text of the passwords.
I know , but may be we should not be able to display the plain text. We can always give the user the option to reset the password.
Out of curiosity
Why is the hashing so safe, the hashing mechanism appears to be the same , HashString that we get for a particular plain text will be same for you and me.
a_suna at 2007-7-13 22:49:37 >

what database type is required to store the hashed password.? Will a regular varchar do?
a_suna at 2007-7-13 22:49:37 >

> f curiosity
> Why is the hashing so safe, the hashing mechanism
> appears to be the same , HashString that we get for a
> particular plain text will be same for you and me.
A basic flaw with the use of hashing of passwords is that if two people have the same password then they will both have the same hash. If I can get access to a database of hashed passwords I can look to see which accounts have the same hash as mine and I will then know a password that will activate those accounts. A way round this is to hash the concatenation of users unique identity and his password. Since the identites are unique then the chance of a hash clash is small and even if it is there is little or no chance of constructing a password.
Another flaw with password hashing is that if a user forgets his password you have no way to recover it for him! You will have to allocate him a temporary password (possbly using a pin mailer sent through the post) and force him to change the password next time he logs on.
I prefer to use encryption but others prefer hashing.
The biggest flaw with encrypting passwords for storage on the server is
that if a hacker gets access to your server, he now has access to all
your users passwords-
When the data is hashed, if a hacker gains access to your server, he has
nothing but hashes. In order to get the passwords, he's faced with the
task of brute-forcing the hashes. Even when this is possible, it will take a
considerable amount of time and effort on the hackers end.
As far as password collisions for users with the same password,
wouldn't you have the same problem with encryption without some
similar salting technique? unless you're using a different key for each user...
I've never really thought of the inability to recover a user's password as a
flaw... It just needs to be reset. When's the last time you recovered a unix
user's forgotten password? without john the ripper ;)
> The biggest flaw with encrypting passwords for
> storage on the server is
> that if a hacker gets access to your server, he now
> has access to all
> your users passwords-
It is normal to place the encryption key in some form of key safe that is only accessed via password when the application is started. Yes, the key is stored in memory and a hacker could possbily find it by searching memory but a hacker could alse find passwords by just 'watching' as they are presented for verification.
>
> When the data is hashed, if a hacker gains access to
> your server, he has
> nothing but hashes. In order to get the passwords,
> he's faced with the
> task of brute-forcing the hashes. Even when this is
> possible, it will take a
> considerable amount of time and effort on the hackers
> end.
I have to assume that brute-force password attacks are infeasible (even with recent flaws being found in MD5 and SHA-1).
>
> As far as password collisions for users with the same
> password,
> wouldn't you have the same problem with encryption
> without some
> similar salting technique? unless you're using a
> different key for each user...
Just a ramdom IV stored proposed in section 9.3 of "Applied Cryptography* by Bruce Schneier. The IV can be stored in the clear as a prefix to the encrypted data. Schneier shows that this does not introduce any security holes.
>
> I've never really thought of the inability to recover
> a user's password as a
> flaw...
Maybe describing this as a 'flaw' is too strong. I should probably just have said that it could be a problem.
> It just needs to be reset. When's the last
> time you recovered a unix
> user's forgotten password? without john the ripper ;)
So what does one reset a password too? I'm thinking more of online applications where the user has to be informed of a change of password. Since e-mail is very insecure, security dictates that one should not just e-mail a new password or the original password it to a user ( even though some non-banking applications do just that).
Also, I would be very unhappy if my bank just reset my password to some default value based on a phone call, snail mail, email or web request. A PIN mailer containing the new password is about the only solution that works at the moment. Even then I think a password should be sent in two or more parts that have to be merged in some way.
Of course if we all had a well secured RSA key pair then much (but by no means all) of this problem would go away.
>
> It is normal to place the encryption key in some form
> of key safe that is only accessed via password when
> the application is started. Yes, the key is stored in
> memory and a hacker could possbily find it by
> searching memory but a hacker could alse find
> passwords by just 'watching' as they are presented
> for verification.
>
I dont know how normal this is. Everything Ive read indicates hashing the
is the standard way of storing passwords.
For example, especially note edsonw's post:
http://forum.java.sun.com/thread.jspa?forumID=9&threadID=532565
>
> So what does one reset a password too? I'm thinking
> more of online applications where the user has to be
> informed of a change of password. Since e-mail is
> very insecure, security dictates that one should not
> just e-mail a new password or the original password
> it to a user ( even though some non-banking
> applications do just that).
>
Im not sure how having the password encrypted in the
database solves the reset problem. How do you inform
the user of their old forgotten password if you cant email
it?
> Also, I would be very unhappy if my bank just reset
> my password to some default value based on a phone
> call, snail mail, email or web request. A PIN mailer
> containing the new password is about the only
> solution that works at the moment. Even then I think
> a password should be sent in two or more parts that
> have to be merged in some way.
>
even pin mailers arent so secure:
http://news.bbc.co.uk/1/hi/technology/4183330.stm
I remember reading somewhere that some bank was issuing
RSA SecureID key fobs to its clients... that would be nice.
> Of course if we all had a well secured RSA key pair
> then much (but by no means all) of this problem would
> go away.
I think verisign or thawte gives away 'personal' signed
keys for free...
(I hit post instead of preview)
Message was edited by:
cdelikat
thanks everyone for the replies
If we have to use a 'salt' for hashing , where would that be stored in the DB , Will it be in the same table where the username and hashed password is stored
A message digest function is an algorithm which takes a variable-length message and produces a fixed-length hash, 128 bits for MD5, 160 bits for SHA-1.
Does this mean the maximum length required for the col in database is 128/160 for MD5 /SHA-1
a_suna at 2007-7-13 22:49:37 >

The 128/160 values you mention are the number of bits. With eight bits
in a byte, the byte-length would be 16 and 20 bytes. Though Id steer clear
of MD5 and probably SHA1 if you can. Try SHA256 (32 bytes).
But wait, the byte length will not be the length your database column needs.
You should not store raw bytes in your database. Ive seen this cause
all kinds of headaches. You need to convert your bytes to a string before
inserting it into the database. For this, you'll need to use Base64 encoding.
The problem with Base64 encoding is it expands the size of the data it
encodes.
ie:
16 bytes = 24 chars base64 encoded.
24 bytes = 32 chars, base64encoded.
etc.
Hang on...
You could store the salt prepended to the hash value in the database.
prng() = pseudo random number generator function
digest() = message digest (hash) function
base64.encode() = standard way of storing bytes as strings
salt = prng()
hash = digest("password", salt)
dbstring =base64.encode(salt + hash)
store dbstring in database varchar.
You'll need to keep the size of the salt static so your code knows how much
to trim off when hashing the user-entered password.
saltLength = constant value
bytes = base64.decode(dbstring)
salt = bytes[0 - saltLength]
hash = bytes[saltLength - bytes.length]
hash2 = digest("password", salt)
cmp(hash, hash2)
if you had a 16-byte salt combined with a 32 byte hash = 48 bytes.
48 bytes base64encoded = 64 char database column.
cdelikat
Thanks for the very detailed reply, read it couple of times already .
To make myself clear
salt = prng()
hash = digest("password", salt)
dbstring =base64.encode(salt + hash)
We make the hash with the salt and then concat the salt with the generated hash right? and then do the Base64 encoding and store it in the DB as a string (varchar)
a_suna at 2007-7-13 22:49:37 >

Yes-
You've got to store the salt with the hash because you need it at login
time when you hash the user-entered password for comparison with your
stored hash.
In other words, you'll never be able to recreate the stored hash without the salt
so you've gotta make sure you store the salt with the hash. It doesnt
necessarily need to be concat'ed to the hash, but that seems to be the
most straight-forward thing to do.
So yes, I think you've got it.
Thanks a lot. Is it ok to use the "sun.misc.base64encoder"Message was edited by: a_sun
a_suna at 2007-7-13 22:49:37 >

>> even pin mailers arent so secure:> http://news.bbc.co.uk/1/hi/technology/4183330.stm:-( So even my views on PIN mailers are suspect!It is a good thing I have retired!
a_sun-
Yeah. Sun warns against using stuff in the sun.misc package- supposedly
it can be yanked at any time... But Im using it in various places in production
and Im sure others are too (the class has been there probably since java's
inception).
If you're really worried about the future, I know Bouncy Castle has their own
Base64 impl, and I think Apache has one too.