It's for a desktop app, so only I want basic login security and I though to use one function to encrypt password and another which I pass pass password from UI and hash save into db and returns true o false depends on if matches or not.
I try to use pooled version from official jasypt website, and I can encrypt but I don't know how to decrypt it.
//Function to encrypt password
public static String cifrarClave(String clave) {
PooledStringDigester digester = new PooledStringDigester();
digester.setPoolSize(4);
digester.setAlgorithm("SHA-1");
digester.setIterations(50000);
digester.setSaltSizeBytes(32);
//String return is hash that I save into db
return digester.digest(clave);
}
//Function to decrypt password
//clave is old plain that user enter from UI and I want to compare from hash save it into db
public static boolean validarClave(String clave, String hash) {
PooledStringDigester digester = new PooledStringDigester();
digester.setPoolSize(4);
digester.setAlgorithm("SHA-1");
digester.setIterations(50000);
String digest = digester.digest(clave);
//Always fails at that point, I get different hash from compare clave
return digester.matches(digest, hash);
}
I'm a newbie in security, so I don't know much about security, I accept other suggestions or alternatives, I only want a working example.
You're using the jasypt's matches(message, digest) function incorrectly when you are calling it with two hash digests instead of the plaintext message and the previously computed digest.
In your validarClave(), you're first unnecessarily computing a digest from the user's plaintext password (clave) which you then pass to the matcher:
String digest = digester.digest(clave);
//Always fails at that point, I get different hash from compare clave
return digester.matches(digest, hash);
Your method will work correctly if you simply pass the plaintext password to the matcher, as follows:
digester.matches(clave, hash);
More info is available at jasypt's javadocs and code examples.
Related
Good day, I have used google/tink to encrypt a password for storing in a DB using these steps :
// 1. Generate the key material.
KeysetHandle keysetHandle =
KeysetHandle.generateNew(AeadKeyTemplates.AES128_GCM);
// 2. Get the primitive.
Aead aead = AeadFactory.getPrimitive(keysetHandle);
// 3. Use the primitive to encrypt a plaintext,
byte[] ciphertext = aead.encrypt(plaintext, aad);
It basically converts password into the bytes, but when i convert it into string to store into the DB, It stores the encrypted password in this format : -�#~�k�D߶{�.
But i want to store the password in the format like 11As7737Cs9ue9oo09 using tink encryption.
Is there any way to do it?
Manish, you might not want to encrypt the passwords. You want to hash them. Tink doesn't support password hashing yet, but we can add support if there's enough interest.
Could you please file for a feature request at https://github.com/google/tink/issues/new?
I agree with everyone here that you SHOULD NOT store passwords in the clear.
However, to answer your question because I think it's a common problem when you get some cipher text and the string is unreadable. Say you wanted to store non password data encrypted, and readable. You would need to Base64 encode your cipher text.
When you retrieve your Base64 encoded data back from the database, you would then need to Base64 decode the String and then run it through your decryption process. Building on your example,
String readable = new String(java.util.Base64.getEncoder().encode(cipherText));
byte[] bytesToDecrypt = java.util.Base64.getDecoder().decode(readable.getBytes());
In my java web app, admin account will create user account, where the password will be encrypted, using StandardPasswordEncoder class, that's easy. But how to encrypt the admin password, which i already stored in MySQL database?
how to encrypt the admin password, which i already stored in mysql
database?
You can edit your password :
UPDATE table_name SET pass = MD5(pass);
-- --------------------------^^^-------
-- This can be any Standard encryption algorithm, you can check the link above
You can take a look about Encryption and Compression Functions
how if i only want to encrypt only the admin password? the other users
password will be encrypted by admin in java controller class.
You can mark your password like a master admin for example you can add a column in your table that make difference between the admin and the ordinary users, consider you have a big enterprise in this case one admin account is not enough, you need many admin accounts, and in base of this column you can encrypt the admin account with an algorithm and the others with another algorithm.
Encrypt password using SHA-256
I managed to encrypt the admin password, but i can't log in to my web
app coz the StandardPasswordEncoder class in the web app is using
SHA-256 hashing algorithm
SHA-256 != MD5, this is clear so you have to use the same algothm in the both side code and database, in your case you are using SHA-256 i assume you are using a function like this :
CODE
public static String sha256(String base) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(base.getBytes("UTF-8"));
StringBuilder hexString = new StringBuilder();
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
} catch (UnsupportedEncodingException | NoSuchAlgorithmException ex) {
throw new RuntimeException(ex);
}
}
This will encrypt admin like this :
admin = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
DATABASE
So in your database you have to encrypt your password like this :
SELECT SHA2('admin', 256);
The update query should look like this :
UPDATE table_name SET pass = SHA2(pass, 256) WHERE admin_master = true;
-- -------------Field to check if it is admin or not ---^
So when you try to log in you have to check if it is admin or not, if admin encrypt your password with SHA-256 and check if the user exist or not, else if the user is ordanary user, check with your previouse algorithm.
Hope this can give you an idea.
I am currently creating application using Java, I googled password encryption with java but the results are so enormous I felt overwhelmed. How would I encrypt and decrypt a password using Java? And what is the best practice for encrypting and decrypting passwords? I am guessing MD5 is not a way to go since it is a one way hash. I am using struts2 as my framework, was wondering if they provide password encryption
Updated:
Try JBCrypt:
String password = "MyPassword123";
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
System.out.println(hashed); // $2a$12$QBx3/kI1SAfwBDFOJK1xNOXK8R2yC7vt2yeIYusaqOisYbxTNFiMy
Download jBCrypt-0.3 from here, check README file for more details.
Also I don't recommend to use MD5 because, it's already broken. Instead of that you can use SHA512 it's secure hashing method, you can use MessageDigest. Below code I am using in one of my project, which works perfectly
public String encode(String password, String saltKey)
throws NoSuchAlgorithmException, IOException {
String encodedPassword = null;
byte[] salt = base64ToByte(saltKey);
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.reset();
digest.update(salt);
byte[] btPass = digest.digest(password.getBytes("UTF-8"));
for (int i = 0; i < ITERATION_COUNT; i++) {
digest.reset();
btPass = digest.digest(btPass);
}
encodedPassword = byteToBase64(btPass);
return encodedPassword;
}
private byte[] base64ToByte(String str) throws IOException {
BASE64Decoder decoder = new BASE64Decoder();
byte[] returnbyteArray = decoder.decodeBuffer(str);
if (log.isDebugEnabled()) {
log.debug("base64ToByte(String) - end");
}
return returnbyteArray;
}
well, as I know we have following some algorithm to secure password.
MD5 -
PBKDF2 -
SHA -
BCrypt and SCrypt -
among this BCrypt and SCrypt are the more secure way for password security.
There is quite nice project dedicating to solving that problem in Java.
Essentially, it provides two ways of encrypting user passwords:
- MD5
- SHA1
Take a look to the link:
jasypt
for me i see that MD5 its the best way and you don't need to decrypt the password in case the user forgot his password you can give him a way to generate a new one and for the log in you can compare just the hash existing in the data base and the one entred by the user
Always use ONE WAY HASH ALGORITHM.
I would say GO with MD5 hashing. While storing password in DB, use MD5 hashing. So that if you have your password as pass, after hashing it will get stored as asjasdfklasdjf789asdfalsdfashdflasdf (32 character).
As you said, you want to de-crypt the password also. I would say don't do that. While checking the password against DB, what you can do is hash the password and compare that string with what you have in database.
if (DoHashMD5(myPass).equals(rs.getString(2))) {
System.out.print("You are registered user!!!");
} else {
System.out.print("Invalid user!!!");
}
here rs.getString(2) would be your query parameter.
Something in the back of my head is telling me I'm missing something obvious here.
I'm integrating an existing java project with a third-party api that uses an md5 hash of an api key for authentication. It's not working for me, and during debugging I realized that the hashes I'm generating don't match the examples that they've supplied. I've found some websites that create MD5 hashes from strings to check their examples, and as far as I can tell I'm wrong and they're right.
for example, according to this website, the string "hello" generates a hash of "5d41402abc4b2a76b9719d911017c592". (FWIW I don't know anything about this website except that it seems to correctly hash the examples that I have). When I run it through my code I get:
XUFAKrxLKna5cZ2REBfFkg==
Here is the simple method I'm using to generate the md5 hash/string.:
private String md5(String md5Me) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.reset();
md.update(md5Me.getBytes("UTF-8"));
return Base64.encodeBase64String(md.digest());
}
I used a very similar method to successfully authenticate a different API using the SHA1 algorithm last week. I'm wondering if the problem is related to the org.apache.commons.net.util.Base64.encodeBase64String... Any help is greatly appreciated, if only some tests to see if the byteArray is correct but the converted string is wrong.
for example, according to this website, the string "hello" generates a hash of "5d41402abc4b2a76b9719d911017c592". (FWIW I don't know anything about this website except that it seems to correctly hash the examples that I have). When I run it through my code I get:
XUFAKrxLKna5cZ2REBfFkg==
Both are correct ways of representing the same sixteen-byte hash. 5d41402abc4b2a76b9719d911017c592 represents each byte of the hash as two hexadecimal digits, whereas XUFAKrxLKna5cZ2REBfFkg== uses Base-64 to represent every three bytes of the hash as four characters.
To generate the hexadecimal-version that this third-party API is expecting, you can change this:
Base64.encodeBase64String(md.digest());
to this:
String.format("%032x", new BigInteger(1, md.digest()));
(mostly taken from this StackOverflow answer).
However, you might want to consider using an external library for this. Perception, in a comment above, mentions Apache Commons DigestUtils. If you use that, you'll want the md5hex method.
The md5 Hash algorithm is part of the core java API so there is no need for any external libraries. Here is the method I used to encrypt a password with MD5.
import java.security.MessageDigest;
/**
* Use to encrypt passwords using MD5 algorithm
* #param password should be a plain text password.
* #return a hex String that results from encrypting the given password.
*/
public static String encryptPassword(String password) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte byteData[] = md.digest();
StringBuffer hexString = new StringBuffer();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
catch(java.security.NoSuchAlgorithmException missing) {
return "Error.";
}
}
I would like to create a file protected by a password in JAVA.
What I mean is, once I launch the program, one file created by my program would be directly protected by previously determined password.
Is there an easy way to do it ?
Once again, my aim is not to create a file and then add it a password, but right during the creation protecting the file by a password.
Actually, I want the current runner program not having access in reading/editing the created file EXCEPT if he/she has the password previously set.
So anyway, if some of you know an easy way to protect files when writing them thanks to java, I would be most grateful.
Have a nice day!
You want to encrypt your file('s content) with a password. Here is a pretty well known library to do it: http://www.jasypt.org/
From their site:
..encrypting and decrypting a text...
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(myEncryptionPassword);
String myEncryptedText = textEncryptor.encrypt(myText);
...
String plainText = textEncryptor.decrypt(myEncryptedText);
You can read/write the encrypted content to your file.
When you want to encrypt files, strings, etc there are 2 main approaches.
You should start by building a class or method to convert ur string/file to an array of bytes. Build another method to convert the array of bytes back to the string/file.
You may encrypt a file using 2 approaches:
1 - Symmetric key - A secret word (usually a huge string of chars or a password set by the user) will encrypt your file and password, and the same password will be used to decrypt.
2 - Asymmetric key - You generate a pair of keys. One is called the public key and the other is called a private key. Public keys are used to encrypt files, private keys to decrypt.
This would be the more 'professional' approach.
If you want a really safe approach, you should download GnuPG. GnuPG is an executable that manages assymmetric encryption, you may build a class to work with GnuPG and let GnuPG manage ur encryption/decryption process.
Theres an unsafe approach that is 'native' to java (symmetric key) that may work out for you:
Encryption:
byte[] key = //... password converted to an array of bytes
byte[] dataToSend = ...
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k =
new SecretKeySpec(key, "AES");
c.init(Cipher.ENCRYPT_MODE, k);
byte[] encryptedData = c.doFinal(dataToSend);
Decryption:
byte[] key = //
byte[] encryptedData = //
Cipher c = Cipher.getInstance("AES");
SecretKeySpec k =
new SecretKeySpec(key, "AES");
c.init(Cipher.DECRYPT_MODE, k);
byte[] data = c.doFinal(encryptedData);
Hope this helps.
If the file is a plain text file, then not giving the user access to the file without a password in your program does not really password-protect the data, because the user can just open the file with some other program. So IF the file is a text file, then I think you must use encryption.
You can use the comment by #mazaneicha to help you get started in this direction. If you want to dive more into it, you can look at the Java Cryptography architectre and the javax.crypto java docs.
If your file is not human-readable, and only your program understands it, then I would make the first line or first n Bytes of the file a password. If you prefer, you could save another password file in the same directory and use that to authenticate the user before deciding if the user has the right to view the file. A common way to encrypt a password is with an MD5 hash function. The user enters a password, you compute the hash of it, then compare the computed hash with the hash value read from the file:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* Use to encrypt passwords using MD5 algorithm
* #param password should be a plain text password.
* #return a hex String that results from encrypting the given password.
*/
static String encryptPassword(String password) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte byteData[] = md.digest();
StringBuilder hexString = new StringBuilder();
for (int i=0;i<byteData.length;i++) {
String hex=Integer.toHexString(0xff & byteData[i]);
if(hex.length()==1)
hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
}
catch(java.security.NoSuchAlgorithmException missing) {
return password;
}
}