I used Apache library for hash password for two application in Linux. One of them is Pure-Ftp and another is my Application. I manually save hashed password in Pure-Ftp passwd file, It works fine and user can use Ftp with given user/password.
In my Application I want to authenticat user, But there is not any checkPassword(clearTextPassword, hashedPassword) function.
import org.apache.commons.codec.digest.Crypt;
...
...
...
String hashedValue = Crypt.crypt(clearTextPassword);
..
To verifying password, You can hash given simple password with savedHashedPassword as salt:
private static boolean checkPassword(String password, String hashedPassword) {
String tmpHashedPassword = Crypt.crypt(password, hashedPassword);
return hashedPassword.equalsIgnoreCase(tmpHashedPassword);
}
Crypt.crypt(password) Calculates the digest using the strongest crypt(3) algorithm. A random salt and the default algorithm (currently SHA-512) are used.
Related
This is a banking system and I have to create two user levels, Manager and Cashier. I have to provide username and password for manager and manager has to provide username and password for a cashier. I am not really sure how to code validation for cahsier login. This has to be coded in Java in Netbeans IDE (GUI)
My point is just a concern as your question needs you to have a basic understanding of Java. I am not sure whether you are storing your login details in a database or in a text file. If you store the data in a database, then you can just use the normal java validation techniques described below:
Get a username and a password from the cashier.
Select the records that match the user name and password you've entered above from the database.
Print a message if the number of records that you match is zero.
Login the cashier if the entered records match the ones stored in the database.
Please refer to here for more information on connecting to the database and storing/retrieving user data using java.
Also, note that banking applications should be more secure and therefore the best practice is to store seeded hashes of the passwords and use a cryptographically strong hashing function.
In case you are saving your data in a text file, then you can refer to this sample code . You can read more about the Java Scanner Class here. You can also decide to use a map to map all users on registering and then just check the map to confirm the login details.
N/B: In all of these cases, check if the username and password fields are empty before you submit the details.
If this were a real application, you would store usernames and hashed-and-salted versions of the passwords on disk (or you would query them over a network), ideally using bcrypt, pbkdf2, or another strong and upgrade-able password-hashing scheme. There are multiple open-source libraries that implement those for you.
Since this appears to be a programming exercise, the question of how you store them is probably mandated by whoever wrote it, and security may therefore be minimal.
The easiest way (which is not secure at all) of implementing this is to keep a password file around. You could, for example, use something similar to the following code:
public class InsecurePasswordStore {
private Map<String, String> passwords = new HashMap<>();
public void setPassword(String user, String password) {
passwords.put(user, password);
}
public boolean isPasswordCorrect(String user, String password) {
return passwords.get(user) != null && passwords.get(user).equals(password);
}
public void save(File file) throws IOException {
try (PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file)))) {
for (Map.Entry<String, String> e: passwords.entrySet()) {
writer.println(e.getKey());
writer.println(e.getValue());
}
}
}
public void load(File file) throws IOException {
passwords.clear();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
boolean finished = false;
while ( ! finished) {
String user = reader.readLine();
String password = reader.readLine();
if (user == null || password == null) {
finished = true;
} else {
passwords.put(user, password);
}
}
}
}
public static void main(String[] args) throws IOException {
InsecurePasswordStore store = new InsecurePasswordStore();
File passwordFile = new File("secrets.txt");
// create initial password file before first run
store.setPassword("manager", "12345");
store.save(passwordFile);
// load file when the app is launched
store.load(passwordFile);
// check password for a user
String badGuess = "2345";
System.out.println("Is " + badGuess
+ " the correct password for the manager? " + store.isPasswordCorrect("manager", badGuess));
String goodGuess = "12345";
System.out.println("Is " + goodGuess
+ " the correct password for the manager? " + store.isPasswordCorrect("manager", goodGuess));
// if the password was correct, set another username-password pair
if (store.isPasswordCorrect("manager", goodGuess)) {
store.setPassword("cashier", "abcde");
}
store.save(passwordFile);
}
}
My answer is more a series of questions and suggestions to get you to think about how to do it. Also, I cannot be very specific because you have provided very little detail in your question.
Question 1, after your manager enters the cashier details, where do you store them? In memory? In a file? In a database? Something else?
Question 2, when validating the cashier login, why would you not validate the cashier details against that database/file/memory store? The answer is you should validate your cashier logins against the place where they are stored.
Also for whatever it is worth, you should never hardcode a logon (e.g. the manager) into an application (not even for testing). Why?
There is no way to get rid of it without releasing a new version of the software.
It is a security risk (because of reason 1).
If you do it in testing, it is entirely possible that you will forget to remove it before the code is released. Then reason 2 applies.
There is no need for it - you can simply "seed" your user store with a single record representing the manager's login and default password (ideally with a "password has expired" indication) in your distribution or if you have an installer, prompt the person doing the setup to create the manager login during the installation process.
Therefore, the way you validate the manager's credentials will be exactly the same as everybody else.
This will (should) have the advantage of a simpler program which will be easier to maintain.
And just in case, the way you tell the difference between the manager, the cashier, a supervisor or whatever other user types that you might have (or need in the future) is via a role. In your user data store have a field that define which role the user is in (e.g. manager, cashier etc). Another model is "muliple fields" where you indicate that a user has that role (and thus access to the associated function or not). For example, you might have manager, supervisor, cashier, backoffice etc roles. Then just put a true/false in your user record that indicates whether that user can access the functions associated with a particular role.
Finally, your program becomes simpler because your logic is now simply
if user has manager role then display manager menu
if user has supervisor role then display supervisor menu"
etc
Note that there is no else in the above psuedo code.
I want to use bcrypt to hash the app password. But I could not get the result about use that in android java. How can I use bcrypt hashing in android?
There is a Java implementation of the BCrypt algorithm here, I even use a modified version of it in my BCryptGenerator project.
Usage of the BCrypt class is as follows:
import com.whatever-domain.BCrypt
private String generateHashedPass(String pass) {
// hash a plaintext password using the typical log rounds (10)
return BCrypt.hashpw(pass, BCrypt.gensalt());
}
private boolean isValid(String clearTextPassword, String hashedPass) {
// returns true if password matches hash
return BCrypt.checkpw(clearTextPassword, hashedPass);
}
I want to make register page in php and make the password hashed with bcrypt and put in database.
I also want to make a login system in Java, and get the password in the same password, using jbcrypt.
How can I make jbcrypt and bcrypt in php compatible, with the same salt.
you can check out this:
https://github.com/ircmaxell/password_compat/issues/49
that's worked for me:
public static void main(String[] args) {
//Laravel bcrypt out
String hash_php = "$2y$10$ss9kwE8iSIqcJOAPhZR0Y.2XdYXJTFJ1/wGq6SUv74vULE7uhKUIO".replaceFirst("2y", "2a");
System.out.println("hash php " + hash_php);
//String a_hash = BCrypt.hashpw("123456", BCrypt.gensalt());
//System.out.println("Encrypt " + a_hash);
if (BCrypt.checkpw("123456", hash_php)) {
System.out.println("It matches");
} else {
System.out.println("It does not match");
}
//mtPruebaRecuperarClave();
}
Console - OutPut
I hope that's help You.
The problem is that PHP with it's password_hash() has it's own version scheme due to the fact that previous implementations had breaking bugs and it should be possible to recognize the old hashes.
So the version used by OpenBSD is $2a$ (will be $2b$ in future releases) and password_hash() uses $2y$ (previously $2x$), so of course the has will not match e.g.
$2y$10$ss9kwE8iSIqcJOAPhZR0Y.2XdYXJTFJ1/wGq6SUv74vULE7uhKUIO
vs
$2a$10$ss9kwE8iSIqcJOAPhZR0Y.2XdYXJTFJ1/wGq6SUv74vULE7uhKUIO
(see the wikipedia article about more info on the versions)
Currently jBcrypt (0.4) only supports $2a$.
There are 2 possibilities:
1. Replace the version identifier manually before passing it to jBcrypt (hack)
String hash_php = "$2y$10$ss9kwE8iSIqcJOAPhZR0Y.2XdYXJTFJ1/wGq6SUv74vULE7uhKUIO".replaceFirst("$2y$", "$2a$");
2. Using a different implemention supporting custom version identifier
This is the reason I implemented a new library for bcrypt (based on jBcrypt). https://github.com/patrickfav/bcrypt
Just use it like this (it does not verify for version per default, you can use verifyStrict() in that case)
BCrypt.Result result = BCrypt.verifyer().verify(password.toCharArray(), "$2y$10$ss9kwE8iSIqcJOAPhZR0Y.2XdYXJTFJ1/wGq6SUv74vULE7uhKUIO")
if(result.verified) {...}
If you want bcrypt to create $2y$ hashes:
String bcryptHash = BCrypt.with(BCrypt.Version.VERSION_2Y).hashToString(6, password.toCharArray());
// $2y$10$ss9kwE8iSIqcJOAPhZR0Y.2XdYXJTFJ1/wGq6SUv74vULE7uhKUIO
Full Disclaimer: Im the author of bcrypt
If you remove the first 7 chars from the hashes ($2y$10$ / $2a$10$) the rest should be the same regardless of the programming language you have used. The first characters of the generated hash is a prefix that tells more about the hash algorithm.
In your example, the $2y$ and $a2$ are defining the algorithm of the hash, and the 10$ is the "cost" of the hash generation (how many times the hash algorithm was repeatedly applied or something like this).
If you want to learn more about the prefixes in the bcrypt generated hashes, read this article.
I have a MySQL database where one column is used to store password.
It is implemented in PHP, using password_hash() to salt and hash the original password on registering, and retrieving the MySQL row of the logging-in user and then password_verify() its password.
But I need to move it in Java. So are there Java equivalents for password_hash() and password_verify()?
You can use the implementation by mindrot:
https://www.mindrot.org/projects/jBCrypt/
To replicate the password_hash you can use:
String hash = BCrypt.hashpw("password");
And to replicate password_verify use:
boolean s = BCrypt.checkpw("password", hash);
This works great with my Laravel project.
I made a few tweaks to the lib, to allow the use of a random salt, instead of passing a new one each time you call hashpw method, and to support multiple versions of salt.
You can find it here: https://github.com/promatik/jBCrypt
Use this:
https://mvnrepository.com/artifact/at.favre.lib/bcrypt
Code example:
import at.favre.lib.crypto.bcrypt.*;
import at.favre.lib.bytes.Bytes;
import java.nio.charset.StandardCharsets;
...
String pw = "candidate_password";
String hash = "<hash from users table>";
BCrypt.Result result = BCrypt.verifyer(BCrypt.Version.VERSION_2Y)
.verifyStrict(pw.getBytes(StandardCharsets.UTF_8), hash.getBytes(StandardCharsets.UTF_8));
if (result.verified) {
System.out.println(" It matches");
} else {
System.out.println(" It does not match");
}
...
So i look for simple answer, how to generate hash and salt for word protection option with docx4j library?
I got this method :
public static void setUpReadOnlyDocumentWithPassword(DocumentSettingsPart documentSettingsPart, String password) {
final CTSettings settings = Context.getWmlObjectFactory().createCTSettings();
final CTDocProtect protection = Context.getWmlObjectFactory().createCTDocProtect();
protection.setEdit(STDocProtect.READ_ONLY);
protection.setFormatting(true);
protection.setEnforcement(true);
protection.setCryptProviderType(STCryptProv.RSA_FULL);
protection.setCryptAlgorithmClass(STAlgClass.HASH);
protection.setCryptAlgorithmType(STAlgType.TYPE_ANY);
protection.setCryptAlgorithmSid(new BigInteger("4"));
protection.setCryptSpinCount(new BigInteger("100000"));
protection.setHash(?????);
protection.setSalt(?????);
settings.setDocumentProtection(protection);
documentSettingsPart.setJaxbElement(settings);
}
I really try everything, even translate C# code from http://social.msdn.microsoft.com/Forums/vstudio/en-US/63588f50-354f-43ba-b080-e0e6c51a0fb5/hash-and-saltdocumentprotection .
I want to full automate setting password to docx files.
These days, see https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/DocumentSettingsPart.java#L333
Usually this is driven by https://github.com/plutext/docx4j/blob/master/src/main/java/org/docx4j/openpackaging/packages/ProtectDocument.java