I am trying to covert a c# encryption method to java. It is Triple DES with MD5 hash in ECB mode and I am having a hard time finding the java equivalent. The hashes do not match when I try to run them
Below is the c# code
public string Encrypt(string value, string key)
{
string encrypted;
var hashmd5 = new MD5CryptoServiceProvider();
var des = new TripleDESCryptoServiceProvider();
des.Key = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(key));
des.Mode = CipherMode.ECB; //CBC, CFB
var buff = ASCIIEncoding.ASCII.GetBytes(value);
encrypted = Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buff, 0, buff.Length));
return encrypted;
}
Here is the Java Code
public String encryptSession (String session, String sessionEncryptionKey) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = EncodingUtils.getAsciiBytes(sessionEncryptionKey);
byte[] digestOfPassword = md.digest(hash);
byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
SecretKey key = new SecretKeySpec(keyBytes, "DESede");
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] sessionBytes = EncodingUtils.getAsciiBytes(session);
byte[] buf = cipher.doFinal(sessionBytes);
byte[] base64Bytes = Base64.getEncoder().encode(buf);
String base64EncryptedString = new String(base64Bytes);
return base64EncryptedString;
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
String resultPassword = dc.profile.sipUsername + ":" + dc.profile.stunServer + ":" + passwd;
md.update(resultPassword.getBytes());
byte byteData[] = md.digest();
StringBuffer sb = new StringBuffer();
for (int j = 0; j < byteData.length; j++) {
sb.append(Integer.toString((byteData[j] & 0xff) + 0x100, 16).substring(1));
}
I have reached to that point
NSData *data = [resultPassword dataUsingEncoding:NSUTF16LittleEndianStringEncoding allowLossyConversion:NO];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5(data.bytes, data.length, digest);
NSData *hashData = [[NSData alloc] initWithBytes:digest length: sizeof digest];
But don't know am i going on right way.
I need to convert password to md5
Try the following:
#import <CommonCrypto/CommonHMAC.h>
NSString *calcMD5(NSString *aString, NSString *key)
{
const char *cKey = [key cStringUsingEncoding: NSUTF8StringEncoding];
const char *cData = [aString cStringUsingEncoding: NSUTF8StringEncoding];
// Berechnung der MD5-Signatur
unsigned char cHMAC[CC_MD5_DIGEST_LENGTH];
CCHmac(kCCHmacAlgMD5, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
length:sizeof(cHMAC)];
// Base64 encoded zurückliefern
return [HMAC base64EncodedStringWithOptions:0];
}
Or use the following if there is no key:
How do I create an MD5 Hash of a string in Cocoa?
I am using same MySQL table to store password from different program. One is written in Java and another is written in PHP.
I am saving password via PHP using this script:
encrypted_password= md5(md5('added_salt').md5(md5('plain_password')));
I need to encrypt password in Java using MD5 and salt like above. I write code in Java but it's output is different:
MessageDigest md = MessageDigest.getInstance("MD5");
String salts = "a,d,d,e,d,_,s,a,l,t";
String salttmps[] = salts.split(",");
byte salt[] = new byte[salttmps.length];
for (int i = 0; i < salt.length; i++) {
salt[i] = Byte.parseByte(salttmps[i]);
}
md.update(salt);
md.update(password.getBytes());
byte byteData[] = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
}
password = sb.toString();
I need to correct Java code and generate output same as PHP.
If you could post an example of output in your question, it would be better to reproduce the algorithm.
I guess you should do something like this:
public static void main(String[] args) {
try {
System.out.println(md5(md5("added_salt"), md5("plain_password")));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public static String md5(String plainText) throws NoSuchAlgorithmException {
return md5(null, plainText);
}
public static String md5(String salt, String plainText)
throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
if (salt != null) {
md.update(salt.getBytes());
}
md.update(plainText.getBytes());
byte byteData[] = md.digest();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < byteData.length; i++) {
sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16)
.substring(1));
}
return sb.toString();
}
md5(md5("added_salt"), md5("plain_password")) returns 3bd9e544ab1a3d3485f07af38cc1b415
I am using AES as an encryption technique. While decrypting my encrypted string I am facing this StringIndexOutOfBoundsException String index out of range : -3. Can you tell me why am I facing this? is it related BASE64 encoding that I used?
Code for decryption:
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
String salt = "some salt";
String dValue = null;
String valueToDecrypt = encryptedData;
for (int i = 0; i < 2; i++) {
byte[] decordedValue = Base64.decodeBase64(valueToDecrypt);
byte[] decValue = c.doFinal(decordedValue);
dValue = new String(decValue).substring(salt.length());
valueToDecrypt = dValue;
}
Code for Encryption :
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
String salt = "some salt";
String valueToEnc = null;
String eValue = Data;
for (int i = 0; i < 2; i++) {
valueToEnc = salt + eValue;
byte[] encValue = c.doFinal(valueToEnc.getBytes(UNICODE_FORMAT));
eValue =new String(Base64.encodeBase64(encValue));
}
Reference : http://www.digizol.com/2009/10/java-encrypt-decrypt-jce-salt.html
I understand how it works but if I want to print out the MD5 as String how would I do that?
public static void getMD5(String fileName) throws Exception{
InputStream input = new FileInputStream(fileName);
byte[] buffer = new byte[1024];
MessageDigest hash = MessageDigest.getInstance("MD5");
int read;
do {
read = input.read(buffer);
if (read > 0) {
hash.update(buffer, 0, read);
}
} while (read != -1);
input.close();
}
You can get it writing less:
String hex = (new HexBinaryAdapter()).marshal(md5.digest(YOUR_STRING.getBytes()))
String input = "168";
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] md5sum = md.digest(input.getBytes());
String output = String.format("%032X", new BigInteger(1, md5sum));
or
DatatypeConverter.printHexBinary( MessageDigest.getInstance("MD5").digest("a".getBytes("UTF-8")))
Try this
StringBuffer hexString = new StringBuffer();
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest();
for (int i = 0; i < hash.length; i++) {
if ((0xff & hash[i]) < 0x10) {
hexString.append("0"
+ Integer.toHexString((0xFF & hash[i])));
} else {
hexString.append(Integer.toHexString(0xFF & hash[i]));
}
}
You can also use Apache Commons Codec library.
This library includes methods public static String md5Hex(InputStream data) and public static String md5Hex(byte[] data) in the DigestUtils class.
No need to invent this yourself ;)
First you need to get the byte[] output of the MessageDigest:
byte[] bytes = hash.digest();
You can't easily print this though (with e.g. new String(bytes)) because it's going to contain binary that won't have good output representations. You can convert it to hex for display like this however:
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (byte b : bytes) {
sb.append("0123456789ABCDEF".charAt((b & 0xF0) >> 4));
sb.append("0123456789ABCDEF".charAt((b & 0x0F)));
}
String hex = sb.toString();
Shortest way:
String toMD5(String input) {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] raw = md.digest(input.getBytes());
return DatatypeConverter.printHexBinary(raw);
}
Just remember to handle the exception.
With the byte array, result from message digest:
...
byte hashgerado[] = md.digest(entrada);
...
for(byte b : hashgerado)
System.out.printf("%02x", Byte.toUnsignedInt(b));
Result (for example):
89e8a9f68ad3c4bba9b9d3581cf5201d
/**
* hashes:
* e7cfa2be5969e235138356a54bad7fc4
* 3c9ec110aa171b57bb41fc761130822c
*
* compiled with java 8 - 12 Dec 2015
*/
public static String generateHash() {
long r = new java.util.Random().nextLong();
String input = String.valueOf(r);
String md5 = null;
try {
java.security.MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
//Update input string in message digest
digest.update(input.getBytes(), 0, input.length());
//Converts message digest value in base 16 (hex)
md5 = new java.math.BigInteger(1, digest.digest()).toString(16);
}
catch (java.security.NoSuchAlgorithmException e) {
e.printStackTrace();
}
return md5;
}
FYI...
In certain situations this did not work for me
md5 = new java.math.BigInteger(1, digest.digest()).toString(16);
but this did
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
if ((0xff & digest[i]) < 0x10) {
sb.append("0").append(Integer.toHexString((0xFF & digest[i])));
} else {
sb.append(Integer.toHexString(0xFF & digest[i]));
}
}
String result = sb.toString();
Call hash.digest() to finish the process. It will return an array of bytes.
You can create a String from a byte[] using a String constructor, however if you want a hex string you'll have to loop through the byte array manually and work out the characters.
This is another version of #anything answer:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
if ((0xff & digest[i]) < 0x10) {
sb.append("0").append(Integer.toHexString((0xFF & digest[i])));
} else {
sb.append(Integer.toHexString(0xFF & digest[i]));
}
}
String result = sb.toString();