new line appending on my encrypted string - java

In Main:
public static void main(String[] args) throws NoSuchAlgorithmException {
System.out.println("encrypt:" + encryptPassword("superuser")+":" );
}
public static String encryptPassword(final String password) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hashPassword = md.digest(password.getBytes());
String encryPass = Base64.encodeBase64String(hashPassword);
return encryPass;
}
I'm getting this output:
encrypt:C66i8K4gFQ23j1jN2sRCqQ==:
But when I implemented the same thing in my application I'm getting the output below:
encrypt:C66i8K4gFQ23j1jN2sRCqQ==
:
Note: new line appending on my encrypted string.
application code:
public boolean authenticateUsernamePasswordInternal(UsernamePasswordCredentials credentials) {
try {
System.out.println("encrypt:" + getHash("superuser")+":" );
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new BadCredentialsAuthenticationException(ErrorConstants.CONNECTION_FAILED);
}
}
private String getHash(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException{
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hashPassword = md.digest(password.getBytes());
String encryPass = Base64.encodeBase64String(hashPassword);
return encryPass;
}
How I can remove that extra new line.
why this is happened, please help me what is the reason?

I may be late in answering this, but came across with same problem. Actually problem lies here
Base64.encodeBase64String(hashPassword)
Change that line to look like this it should work:
Base64.encodeBase64String(hashPassword,Base64.NO_WRAP)
By default the Android Base64 util adds a newline character to the end of the encoded string.
The Base64.NO_WRAP flag tells the util to create the encoded string without the newline character.
Check here

In case anyone needs this for any libraries using OkHttp, there's a Credentials class you can use for Base64 encoding your username/pass
String credentials = Credentials.basic("username", "password");
request.header(HttpHeaders.AUTHORIZATION, credentials);

Use:
String encryPass = Base64.encodeBase64String(hashPassword).trim();

A cleaner option without trimming:
String encryPass = BaseEncoding.base64().encode(hashPassword);

You just need to Use Base64 encoding in following way
Base64.encodeBase64String("Your data to encrypt in base64", Base64.DEFAULT)
Change above line with the followings
Base64.encodeBase64String("Your data to encrypt in base64",Base64.NO_WRAP)
It worked for me.

It depends on the implementation of Base64.encodeBase64String(). What is that method?
If it's from Apache commons, be aware that there are a few different classes that handle whitespace differently.
For example, org.apache.commons.net.util.Base64 chunks output, and it probably adds a CR-LF sequence to the final chunk.
The more common version, org.apache.commons.codec.binary.Base64, does not add whitespace.

Related

How to encode Japanese characters javamail

So basically I'm trying to send an email with Japanese characters, something like "𥹖𥹖𥹖" and then I got "???" what should I do to encode this? I have looked over a bunch of solutions but none of them have helped me solve this.
here's the method I've been trying to do the encode:
public String encoding(String str) throws UnsupportedEncodingException{
String Encoding = "Shift_JIS";
return this.changeCharset(str, Encoding);
}
public String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
if (str != null) {
byte[] jis = str.getBytes("Shift_JIS");
return new String(bs, newCharset);
}
return null;
}
You're making this too complicated...
First, make sure you have the Japanese text in a proper Java String object, using proper Unicode characters.
Then, set the content of the body part using this method:
htmlPart.setText(japaneseString, "Shift_JIS", "html");

SHA hash does not seem to be working correctly

I am trying to build a simple password authenticator where passwords that have been hashed using SHA-256 .
I found a couple calculators online (http://onlinemd5.com/) that hashed "password" to "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
I tried a couple other passwords with expected results.
So I tried to implement a fairly straight forward set of code (or so I thought)
String pswd="password";
String storedPswd="5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
//first as a byte[]
Arrays.equals(hashWord(pswd),storedPswd.getBytes("UTF-8") );
...
private byte[] hashWord(String word) {
try {
return MessageDigest.getInstance("SHA-256").digest(word.getBytes("UTF-8"));
} catch (Exception e) {
throw new BadCredentialsException("Could not hash supplied password", e);
}
}
I also tried without success.
return storedPswd.toUpperCase().equals(DigestUtils.sha256Hex(password));
The Apache codec library (v1.10) and Java 1.6 gives me :
113459EB7BB31BDDEE85ADE5230D6AD5D8B2FB52879E00A84FF6AE1067A210D3
instead of
5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8
What am I missing ??
The Solution (wrong inputs):
updated Test Code:
String passwordSHA="5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8";
String complexSHA="8849fb9b221ddec0117e2796d16929179accf3a6012f738e1ed6c11af9cc2081";
#Test
public void testDigest() throws InterruptedException{
System.out.println("Starting Digest test");
String complexPassword = "a7$h1UC8";
try {
Assert.assertTrue(authenticateUser(complexPassword, complexSHA));
Assert.assertTrue(authenticateUser("password", passwordSHA));
Assert.assertTrue( hashWord(complexPassword).equals(complexSHA) );
} catch (Exception e) {
Assert.fail();
}
}
public boolean authenticateUser(String word, String stored) throws Exception {
String apache2Pswd = hashApache(word);
System.out.println(apache2Pswd);
return stored.equals(apache2Pswd);
}
private String hashApache(String pswd){
return DigestUtils.sha256Hex(pswd);
}
public static String hashWord(String word) throws Exception{
byte[] digest = MessageDigest.getInstance("SHA-256").digest(word.getBytes("UTF-8"));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
System.out.println(sb.toString());
return sb.toString();
}
With Results:
Starting Digest test
8849fb9b221ddec0117e2796d16929179accf3a6012f738e1ed6c11af9cc2081
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
8849fb9b221ddec0117e2796d16929179accf3a6012f738e1ed6c11af9cc2081
The hashWord method that you posted is not correct, it does not compile (is this your actual code?); it's not returning a value.
With this:
byte[] digest = MessageDigest.getInstance("SHA-256").digest("password".getBytes("UTF-8"));
for (byte b : digest) {
System.out.printf("%02x", b);
}
I do get the expected output:
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
The output 113459eb7bb31bddee85ade5230d6ad5d8b2fb52879e00a84ff6ae1067a210d3 is what you get when you calculate the SHA-256 hash over the string 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 instead of the original string password.
You are calculating the hash over the hex string containing the hash, instead of the hash of the original password.
An online resource that does not carefully document how it converts user input to binary before hashing is worthless for the purpose of comparing hashes.
It ultimately doesn't matter if your encoding method produces hashes compatible with anything else. What matters is that you get the same hash for the same input consistently (i.e. the hash procedure must be deterministic).

PHP's hash() in Java

I am currently trying to get Java to generate the same hash for a string as PHP's hash algorithm does.
I have come close enough:
hash('sha512', 'password');
outputs:
b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
Java code:
public static void main(String[] args) {
hash("password");
}
private static String hash(String salted) {
byte[] digest;
try {
MessageDigest mda = MessageDigest.getInstance("SHA-512");
digest = mda.digest(salted.getBytes("UTF-8"));
} catch (Exception e) {
digest = new byte[]{};
}
String str = "";
for (byte aDigest : digest) {
str += String.format("%02x", 0xFF & aDigest);
}
return str;
}
This outputs the same.
My problem is when I use the third argument within PHP's hash function. On PHP's site it's described as following:
raw_output
When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.
I am not quite sure how to implement this extra parameter. I think mainly my question would be, how do I convert a String object into a binary String object? Currently, running it with PHP generates the following: http://sandbox.onlinephpfunctions.com/code/a1bd9b399b3ac0c4db611fe748998f18738d19e3
This should reproduce the outcome from your link:
String strBinary = null;
try {
strBinary = new String(digest, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
and you'll need these imports at the top of your file:
import java.nio.charset.Charset;
import java.io.UnsupportedEncodingException;
I hope I understood your issue correctly.

printing results of base64_decode gives unexpected output

For a class, I was given a file of base64 encoded salted sha-256 hashed passwords.
the file is in the form:
username:base64 encoded sha256 password:salt
My original thought was to base64 decode the hash so I would be left with:
username:salted hashed password:salt
then run it through JTR or hashcat to crack the passwords.
My problem is in the base64 decoding process.
my code looks like:
public static byte[] decode(String string) {
try {
return new BASE64Decoder().decodeBuffer(string);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void splitLine(String strLine)
throws Exception {
StringTokenizer st = new StringTokenizer(strLine, ":");
if (st.hasMoreTokens())
userName = st.nextToken();
if (st.hasMoreTokens())
password = st.nextToken();
if (st.hasMoreTokens())
salt = st.nextToken();
}
public static void main(String[] argv) {
String line = null;
String pwdFile = null;
int count = 0;
try {
pwdFile = argv[0];
BufferedReader br = new BufferedReader(new FileReader(pwdFile));
line = br.readLine();
while (line != null) {
splitLine(line);
/* alternative #1: generates a lot of non-printable characters for the hash */
System.out.println(userName+":"+new String(decode(password))+":"+salt);
/* alternative #2: gives a list of the decimal values for each byte of the hash */
System.out.println(userName+":"+Arrays.toString(decode(password))+":"+salt);
count++;
line = br.readLine();
}
br.close();
System.err.println("total lines read: " + count);
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
With alternative #1, I end up with 50,000 more lines in my output file than were in the input file, so i assume some of the decoded strings contain newline characters which I need to fix as well.
How do I get back to and print the original hash value for the password in a format that either hashcat or JTR will recognize as salted sha256?
Problem: You are trying to to work with Base64 encoded password hashes and when they are decoded, there are unprintable characters
Background: When a value is hashed, the bytes are all changed according to a hashing algorithm and the resulting bytes are often beyond the range of printable characters. Base64 encoding is simply an alphabet that maps ALL bytes into printable characters.
Solution: work with the bytes that Base64 decode returns instead of trying to make them into a String. Convert those raw bytes to Hex representations (Base16) before you print them or give them to Hashcat or JTR. In short, you need to do something like the following (it happens to use Guava library):
String hex = BaseEncoding.base16().encode(bytesFromEncodedString);
This is condensed from a longer answer I posted

SHA-256-encrypted string as directory name

I need to use a SHA-256-'encrypted' string as a part of a path in a filesystem (ext3, fat, ntfs, ...).
I try to encode it with Base64, but that does not work in all cases, because the Base64-encoded string may contain '/', '\' or other invalid chars.
Is there an (easy) way to get a file-system-safe name of an SHA-256-'encrypted'-string? I do not like to use String.replaceAll() for all possible invalid chars.
Thanks in advance for any help
I am not allowed to write comments ... so I try an answer.
You should really use UUIDs. It must not be longer than an SHA-hash. If so, you have IMHO done something wrong.
try something like
https://gist.github.com/avilches/750151
import java.security.*;
public static String hash256(String data) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(data.getBytes());
return bytesToHex(md.digest());
}
public static String bytesToHex(byte[] bytes) {
StringBuffer result = new StringBuffer();
for (byte byt : bytes) result.append(Integer.toString((byt & 0xff) + 0x100, 16).substring(1));
return result.toString();
}

Categories