JSP simple password encryption decryption - java

i need to encrypt password to insert in a database.Also when i need that password i need to decrypt this value.What is the simple way to do this?
Note : This operation have not to be very safe.

Please don't implement your current plans, instead you should use a MessageDigest to accomplish this. Apply a one way cryptographic hash function to the user's password (e.g. one of SHA-256, SHA-384, and SHA-512 [and there are others]) and a SALT to prevent rainbow table based attacks. Finally, for password resets, just replace the current password hash.
As an example,
// We need a bytesToHex method first. So, from -
// http://stackoverflow.com/a/9855338/2970947
final protected static char[] hexArray = "0123456789ABCDEF"
.toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
// Change this to something else.
private static String SALT = "123456";
// A password hashing method.
public static String hashPassword(String in) {
try {
MessageDigest md = MessageDigest
.getInstance("SHA-256");
md.update(SALT.getBytes()); // <-- Prepend SALT.
md.update(in.getBytes());
// md.update(SALT.getBytes()); // <-- Or, append SALT.
byte[] out = md.digest();
return bytesToHex(out); // <-- Return the Hex Hash.
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
System.out.println(hashPassword("Hello"));
System.out.println(hashPassword("Hello"));
System.out.println(hashPassword("Hello1"));
System.out.println(hashPassword("Hello2"));
}
Which should output
60C1E22D18D022F01EEF0CAF999E52FD44C0C8EFD2161E9F4D24120AB0AFC84D
60C1E22D18D022F01EEF0CAF999E52FD44C0C8EFD2161E9F4D24120AB0AFC84D
CAAC2288692DD57BADFAE0225A42E59E1979E0116D009EEF01912E8C75529515
E0A3963BFAF209A17422918CB1FC950A62858993CA9A7BA6F760B8D4688306FD
Demonstrating how tremendously different one character makes the resulting hash.

One more way is to use Encrypt class for encrypting your password with randomly generated keyvalue. But you need to store the keyvalue in your DB for encrypted password. Like this,
Integer randVal = random.nextInt();
Encrypt encrypt = new Encrypt();
// convert password to encrypted password
String encyppassword = encrypt.encryptText(
Integer.toString(randVal) + "",
your_password);
While decrypt you need to use keyvalue and encrypted password. Like this,
Decrypt decrypt = new Decrypt();
Integer randVal = keyvalue_from_db;
String decryptedPassword = decrypt.decryptText(
String.valueOf(randVal.toString()),
encrypted_password);
Hope this helps.

Related

Password cracking using a dictionary and hashing

I'm working on an assignment for school regarding security and how to crack passwords using a dictionary. We are provided six hashed passwords, a dictionary of words, and a salt hash value. Three of the passwords are not salted, I have already cracked those. I am having trouble finding the three salted passwords.
I have my code set up to iterate through the large dictionary and hash each word and then compare to the hashed passwords. I've tried to hash the salt value on to the front and/or back of each word that I am hashing for comparison, but I can't find any matches. We're using three different algorithms (MD-5, SHA-256, and SHA-1). My program checks the length of the password hash and routes it to which algorithm needs to be used for cracking.
Here's an example of what I have running for the salted MD-5 password:
MessageDigest md = MessageDigest.getInstance("MD5");
md.update((word + salt).getBytes());
byte[] bytes = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff)
+ 0x100, 16).substring(1));
}
return sb.toString();
"word" is the password sent in to be checked, "salt" is the salt hex in a string. This returns the value after hashing to a for loop that is running through my dictionary looking for a match. I can't understand why it can find the three unsalted versions but appending the salt to the front (or back) wont work. Obviously I'm misunderstanding something here. Any clarity is greatly appreciated. Thanks!
Try something like this:
MessageDigest md5 = MessageDigest.getInstance("MD5");
Base64.Encoder base64 = Base64.getEncoder();
ShadowRecord r = new ShadoRecord("username", "usedSalt", "hashedPassword");
if (test(r, "secret")) {
System.out.println("Password is 'secret'");
}
public class ShadowRecord {
public final String username;
public final String salt;
public final String hash; // result of hash(password + salt)
public ShadowRecord(String username, String salt, String hash) {
this.username = username;
this.salt = salt;
this.hash = hash;
}
}
public boolean test(ShadowRecord r, String pwd) {
String input = pwd + r.salt;
String result = hash(input);
return result.equals(r.hash);
}
// input = pwd + salt
public String hash(String input) {
byte[] result = md5.digest(pwd.getBytes(StandardCharsets.UTF_8));
byte[] hash = base64.encode(result);
return new String(hash, StandardCharsets.UTF_8);
}

RSA ENCRYPTION IN ANDROID AND DECRYPTION IN SERVER SIDE

I have made a https api request from android to server. The API request contains one parameter that needs to be encrypted before it is send (i.e. it's a password). RSA/ECB/PKCS1Padding is the encryption used in both end.
Encryption in android side does the following things:
/*Encrypt the password using public key.public key is obtained from generateRsaPublicKey(BigInteger modulus, BigInteger publicExponent) function)*/
public static String rsaEncrypt(String originalString, PublicKey key) {
try {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherByte = cipher.doFinal(original);
return bytesToHex(cipherByte);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//generate public key with given module and exponent value
public static PublicKey generateRsaPublicKey(BigInteger modulus, BigInteger publicExponent) {
PublicKey key = null;
try {
key = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, publicExponent));
return key;
} catch (Exception e) {
Log.e("error", e.toString());
// return null;
}
return key;
}
// Helper methods
final protected static char[] hexArray = "0123456789abcdef".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
// Log.d("byte array representaion","value in integrer"+v);
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
below is the source for decrypting the password on the server
// *** setup private key
RSAPrivateKeySpec privateRPKS
= new RSAPrivateKeySpec(new BigInteger(gModulusPlainS, 16), new BigInteger(privateExponentPlainS, 16));
KeyFactory keyFactoryKF = KeyFactory.getInstance("RSA");
RSAPrivateKey gPrivateKeyRPK = (RSAPrivateKey) keyFactoryKF.generatePrivate(privateRPKS);
// *** setup cipher
Cipher cipherC = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipherC.init(Cipher.DECRYPT_MODE, gPrivateKeyRPK);
// *** decrypt hex-encoded cipherTxS
byte[] baCipherText = hexToBin(cipherTxS.getBytes());
byte[] baPlainText2 = cipherC.doFinal(baCipherText);
String decryptedTextS = new String(baPlainText2);
But I got the following error log
javax.crypto.IllegalBlockSizeException: Data size too large
at com.ibm.crypto.provider.RSASSL.a(Unknown Source)
at com.ibm.crypto.provider.RSASSL.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Unknown Source)
javax.crypto.BadPaddingException: Not PKCS#1 block type 2 or Zero padding
But it is working on websight part. Why it isn't working in android?
Thank you for your kindness to looking my code.
You are sending the ciphertext as string, if cipherTxS.getBytes() is indeed a string to byte array conversion. Ciphertext should be either kept in binary or possibly encoded using base 64 encoding.
Thanks to Alex Klyubin, Android Security Engineer. I have got answer from Here
Developers who use JCA for key generation, signing or random number generation should update their applications to explicitly initialize the PRNG with entropy from /dev/urandom or /dev/random.Also, developers should evaluate whether to regenerate cryptographic keys or other random values previously generated using JCA APIs such as SecureRandom, KeyGenerator, KeyPairGenerator, KeyAgreement, and Signature.
Code comment: Install a Linux PRNG-based SecureRandom implementation as the default, if not yet installed.This is missing from jellybean onwards.
Sample code implementation

Exact same hashing in java as PHP with salt? (SHA-256)

I can simply hash in PHP with a salt:
$orig_pw = "abcd";
$salt = 5f8f041b75042e56;
$password = hash('sha256', $orig_pw . $salt);
(This is not how I implement it, this is just an example. Salt is different for everyone)
And with this, the stored password is:
bc20a09bc9b3d3e1fecf0ed5742769726c93573d4133dbd91e2d309155fa9929
But if I try to do the same in Java, I get a different result. I tried String password = "abcd";
byte[] salt = hexStringToByteArray("5f8f041b75042e56");
try {
System.out.println(new String(getHash(password, salt)));
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
And the two methods:
public byte[] getHash(String password, byte[] salt) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(salt);
try {
return digest.digest(password.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
public byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
The result is:
/¬1¶ĆĽëüFd?[$?¶»_9ËZ»ç¶S‘Ęŗש
Which coded to hex is not even close to it:
2fac31b6434c14ebfc46643f5b243fb6bb5f39cb5abb10e7b65391454c97d7a90d0a
Can anyone help with this?
Apart from the order being swapped, it looks like in PHP you're treating the salt value as a literal string to be appended to the password, while in Java you do a hex conversion of the salt first and then use the resulting bytes to update the MessageDigest. This will obviously yield different results. Looking only at the salt:
PHP: Salt -> To bytes (literal) -> SHA-256
Java: Salt -> To bytes (unhex) -> SHA-256
I just tried your Java code, and it's absolutely fine. I also tried to hash the same value in PHP as in Java and it gave me identical results.
The Java equivalent to your PHP code would be:
String password = "abcd";
String salt = "5f8f041b75042e56";
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
return digest.digest((password + salt).getBytes("UTF-8"));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
return null;
}
After hexing the bytes it returns the following result:
60359BC8A0B09898335AA5A037B1E1B9CE3A1FE0D4CEF13514901FB32F3BCEB0
And in PHP doing:
<?
echo hash('sha256', "abcd"."5f8f041b75042e56");
?>
Returns exactly the same.
I think
digest.update(salt);
digest.digest(password.getBytes("UTF-8"));
is equivalent to:
hash('sha256', $salt . $orig_pw);
So the hash and salt are swapped. Can you confirm this?

hashing password using md5 and a control field

I want to hash a password using MD5 and I have given a string named MD5ControlHash
I found that I can hash a password in this way:
public static void main(String[] args)throws Exception
{
String password = "123456";
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
byte byteData[] = md.digest();
//convert the byte to hex format method 1
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println("Digest(in hex format):: " + sb.toString());
}
However I don't know where should I use MD5ContolHash. Can anyone help me?
Does this code work correctly?
Thanks
If MD5ControlHash is a string, where should be stored hash of the password, you need to replace this line of code:
System.out.println("Digest(in hex format):: " + sb.toString());
with
MD5ControlHash = sb.toString();
If this string called MD5ControlHash stores the source data to hash, just use MD5ControlHash instead of password
And if you doubt about correctness of the code, just try it out!

Need Java equvalent for 3DES decryption of PHP code

This is the PHP code I have.
function decrypt($s_input, $s_key, $s_iv) {
$s_decrypted = pack("H*" , $s_input); // Hex to binary
$s_decrypted = mcrypt_decrypt (MCRYPT_3DES, $s_key, $s_decrypted, MCRYPT_MODE_CBC, $s_iv); // 3des decryption
return $s_decrypted;
}
echo encrypt('c37551bb77f741d0bcdc16497b4f97b1','123456781234567812345678','12345678' );
what it basically does is to decrypt a 3des encrypted string (first it convert the hex string to binary using pack function and then does the actual decryption).
This perfectly works in PHP-4 and prints the "Hello World" message.
However, if I run the equivalent java code (jdk 1.6), it prints garbage output as - ¬ªmjV=7xl_ÓÄ^›*?.
Can someone help to troubleshoot this? Why Java is not properly decrypting the hex string.
private static String decrypt(String inputStr, String keyStr, String ivStr) throws Exception {
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
SecretKeySpec key = new SecretKeySpec(keyStr.getBytes(), "DESede");
inputStr = hexToString(inputStr, 2);
Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decrypted = cipher.doFinal(inputStr.getBytes());
return new String(decrypted);
}
private static String hexToString(String input, int groupLength) {
StringBuilder sb = new StringBuilder(input.length() / groupLength);
for (int i = 0; i < input.length() - groupLength + 1; i += groupLength) {
String hex = input.substring(i, i + groupLength);
sb.append((char) Integer.parseInt(hex, 16));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String decryptSignature = decrypt("c37551bb77f741d0bcdc16497b4f97b1", "123456781234567812345678", "12345678");
System.out.println(decryptSignature);
}
There are a few things you should check. You might find Encryption using AES-128 in Java to be of some assistance. There could be issues with differences between how you are handling keys in the PHP and Java code. Calling getBytes() on a String in Java without an encoding is almost always a bad idea. Plus the padding used could be a problem. From what I've seen PHP pads with null characters by default, which does not correspond to NoPadding in Java. Finally, the hexToString method should return a byte[] instead of a String. Add the result of calling Integer.parseInt(hex, 16) into an array:
byte[] results = new byte[input.length() / groupLength];
...
//inside the loop
results[i / groupLength] = (byte) Integer.parseInt(hex, 16);
...
return results;

Categories

Resources