1

Is this the correct way of generating salts for passwords?

        SecureRandom random = new SecureRandom();
        byte[] salt = random.generateSeed(64);

        String decoded = new String(salt, "Cp1252");
        System.out.println(decoded);

I am trying to generate new passwords (SHA-512), so I will also need a salt.
The hashed password will be = user password + salt ... is this correct?
Wouldnt these strange characters "break" the DB (MySQL)? (Update: no, because salt should be encrypted/encoded/hashed and the result shoudnt use strange characters)

Few outputs:

ã2}wÑ»-ÄKÇæê®ƒzR4qÉÖÙÚ!ž0ÉW9;*Vß4x»)
àöˆ˜£¿{,J¼…HþTù#+Bv(Fp´G~Aò`^e_ElpíÜžS  A!­ñÛz‹y@`ý‡)‡ª€
5a£Æ.¥sgöfÈB:4-�y$Óx%Óâyý¾N¨…áq

Should these salts be also encripted as SHA-512? (Update: encoded using base64 library from apache commons encode, see below)

Update:

        SecureRandom random = new SecureRandom();
        byte[] saltArr = new byte[64];
        random.nextBytes(saltArr);

        String salt = new String(saltArr, "Cp1252");
        System.out.println("SALT:"+salt);


        byte[] encodedBytes = Base64.encodeBase64(saltArr);
        System.out.println("Encoded SALT:" + new String(encodedBytes));

        byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
        System.out.println("Decoded SALT:" + new String(decodedBytes, "Cp1252"));


        //SHA
        String target = "Test";
        MessageDigest sh = MessageDigest.getInstance("SHA-512");
        sh.update(target.getBytes());
        StringBuffer sb = new StringBuffer();
        for (byte b : sh.digest()) sb.append(Integer.toHexString(0xff & b));
        System.out.println("Hashed PWD:"+sb);

        //And then joining them together... 
Alpha2k
  • 2,212
  • 7
  • 38
  • 65
  • have a look at the following question http://stackoverflow.com/questions/18142745/how-do-i-generate-a-salt-in-java-for-salted-hash – sasankad Feb 23 '15 at 22:51

1 Answers1

3

First, it would be enough to use nextBytes (that actually calls the PRNG) instead of generateSeed. The latter uses the seed generation algorithm, which is a more complex operation since it needs an entropy source (800-90A p19-23)

The primary function of salts is to defend against dictionary attacks versus a list of password hashes and against pre-computed rainbow table attacks. (Wikipedia)

In other words, you need a different salt for each password, but that salt is not a secret (you will be storing it along with the digest output), and you should be fine with the output from the PRNG.

Also, since the salt (which may contain bytes in the full range 0x00-0xFF) will be persisted as a string, it should be encoded* in Base64 (or another charset-safe encoding, such as base 85, but base64 is much more usual).

*SHA is not an encryption function.

SecureRandom random = new SecureRandom();
byte[] salt = new byte[64];
random.nextBytes(salt);

String password="god";
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(password.getBytes(Charset.forName("UTF-8")));
md.update(salt);

byte[] digest = md.digest();
Community
  • 1
  • 1
Javier
  • 12,100
  • 5
  • 46
  • 57
  • oh yea sorry, sometimes I confuse hashing with encriptation... Update, can you check if it is correct, please? – Alpha2k Feb 24 '15 at 07:44
  • Yes. But note that `getBytes()` encodes the String into a sequence of bytes using the platform's default charset. If you migrate your app to another platform with a different default charset, the same password and salt could hash to a different value; so I used `getBytes(Charset)`. Note also that `Integer.toHexString(0xff & b)` does not always return two characters. – Javier Feb 24 '15 at 10:13