Well after analyzing the options pointed out by you, I implemented my solution using Pbkdf2 which was the following:
In C#, I followed this example thus getting my implementation:
// este retorna em bytes (byte[])
public static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes)
{
Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt);
pbkdf2.IterationCount = iterations;
return pbkdf2.GetBytes(outputBytes);
}
// Esse retorna em Base64 (que é o que uso no fim)
public static string PBKDF2ToBase64(string password, byte[] salt, int iterations, int outputBytes)
{
return Convert.ToBase64String(PBKDF2(password, salt, iterations, outputBytes));
}
In Java, I followed this and this example thus getting my implementation:
private static final int KEYLENGTH_MULTIPLIER = 8;
// este retorna em bytes (byte[])
public static byte[] PBKDF2(String password, byte[] salt, int iterations,
int outputBytes) throws NoSuchAlgorithmException,
InvalidKeySpecException {
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations,
outputBytes * KEYLENGTH_MULTIPLIER);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
return f.generateSecret(spec).getEncoded();
}
// Esse retorna em Base64 (que é o que uso no fim)
public static String PBKDF2ToBase64(String password, byte[] salt, int iterations,
int outputBytes){
try {
return new String(Base64.encodeBase64(PBKDF2(password, salt, iterations, outputBytes)), "UTF-8");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
The library I’m using to convert to Base64 in Java is that one, and in Android the method encodeBase64String
, does not work and I made an adaptation with the method encodeBase64
in accordance with that one suggestion.
Apparently everything is working perfectly, both in C#, as in Java (Android), if you notice any improvement, she is welcome. Thank you all for your help.
Explanation of parameters:
The parameters salt
, iterations
, outputBytes
are settings parameters of the Hash method, and can be used as secret keys of your application.
Where:
salt
: Or salt in Portuguese
iterations
: Number of iterations to calculate the hash, the higher the hash processing time;
outputBytes
: Amount of hash output bytes;
Example of use:
C#:
private int LengthOutputBytes = 32;
private byte[] Salt = new byte[] { 0x20, 0x23, 0x65, 0x46, 0x43, 0x24, 0x55, 0x23, 0x31, 0x33, 0x32, 0x34, 0x72, 0x18, 0x67, 0x68 };
private int HashIterations = 10;
private string password = "123";
string hash = PBKDF2ToBase64(password, Salt, HashIterations, LengthOutputBytes);
Java:
private byte[] SALT = { 0x20, 0x23, 0x65, 0x46, 0x43, 0x24,
0x55, 0x23, 0x31, 0x33, 0x32, 0x34, 0x72, 0x18, 0x67, 0x68 };
private int ITERATIONS = 10;
private int OUTPUTBYTES = 32;
private String password = "123";
String hash = PBKDF2ToBase64(password, SALT, ITERATIONS, OUTPUTBYTES);
Not with the intention of answering the question, but to give a general idea, I recommend reading: http://answall.com/questions/2402/comort-hash-hash-de-passwords-safe. As for the functions used, implementations for various languages are common. Storing some bcrypt output in the offline version, for example, would solve. MD5, on the other hand, will not help you much.
– Bacco