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;
}
}
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());
I'm developping an Android app and i wanna do encryption with AES-128.
I use secret key and text with hexadecimal.
I use this website : http://testprotect.com/appendix/AEScalc to compute the AES encryption with the following key : "c4dcc3c6ce0acaec4327b6098260b0be" and my text to encrypt is : "6F4B1B252A5F0C3F2992E1A65E56E5B8" (hexadecimal).
So the result from this website give me "859499d0802de8cc6ba4f208da648a8f" and that's the result i wanna get.
http://hpics.li/d89105a
I find some code on the net, but a lot uses seed to generate random secret key and i wanna fix the secret key.
Actually i'm using the following code, i think it's the code i need but the result gives me D/resultdebug: 72adc67b6d11e1c5fb89ddf5faeb0e030686b91f8bfaf6c41335f08955343f87
and it's not the same result than the website, that i want.
String text16 = "6F4B1B252A5F0C3F2992E1A65E56E5B8";
String secret16 = "c4dcc3c6ce0acaec4327b6098260b0be";
SecretKeySpec sks = new SecretKeySpec(secret16.getBytes(),"AES");
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, sks);
c.update(text16.getBytes());
byte[] ciphertext = c.doFinal();
Log.d("resultdebug",new String(Hex.encode(ciphertext), "ASCII"));
Could you please tell me what's wrong, thanks.
You are not converting the hex to binary, you are getting the binary of the characters not the value that is hex encoded.
Thanks zaph, it solved my problem
I added these two lines on my code :
byte[] text = stringhextobyte(text16);
byte[] secret = stringhextobyte(secret16);
And the function stringhextobyte permit me to transform my hex string to byte array and i get the result needed.
I want to encrypt and decrypt password with high security .
First, the string password with be converted to SHA1 , then i also want to add base64 encode and lastly add SALT to it.
Is this doable in java?
I have sample code to encode in base64 and sha1 but i am not sure how to combine them all.
Here is snippet:
String password = "password";
BASE64Encoder encoder = new BASE64Encoder();
encryptedPassword = encoder.encode(password.getBytes());
Using SHA1:
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.reset();
md.update(password.getBytes());
System.out.println(new String(md.digest()));
Please suggest .
These are the things you have to think of when playing around with salts:
Generate a long random salt using a CSPRNG.
Prepend the salt to the
password and hash it with a standard cryptographic hash function
such as SHA256.
You need to append your generated Salt (generated with a Cryptographically Secure Pseudo-Random Number Generator) to the password and then hash it with SHA-1.
Since SHA-1 is a hash Algorithm, you can't decode it. If you need to encrypt the password, you may read something about AES or RSA
I suggest you reading this article, Salted Password Hashing - Doing it Right, especially the part The RIGHT Way: How to Hash Properly, if you still want to hash your password properly.
I'm writing an Server/Client application with encrypted communication in Java (Client is on Android).
What is the best way to save the SecretKeySpec, so I don't have to generate it each time I want to encode/decode a message?
I'm using this method, taken from this site (german):
String keyStr = "secret";
byte[] key = (keyStr).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("MD5");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
String text = "Some text"
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encrypted = cipher.doFinal(text.getBytes());
Should I store it in a static variable? Or should I try a completely different approach?
EDIT: To clarify my question, my main problem is with the server program, how should I do it in the server program?
to permanently save those little things I would recommend to use the Shared Preferences.
But if you want to you could use the Internal Storage.
The main different is that the Shared Preferences only save primitive datatypes (such as int, byte, String) and in the Internal Storage you can wirte whole files (like savegames or temp files)
With both types the user can't access the data.
To easily access the saved information you could write a class that handels that for you, so you don't have to instantiate the whole Classes from the ADK.
Greetings
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.