How to convert Base64 encoded string to UUID in java - java

this is the encoded string
YjRmYTJhMGEtYjI0ZC00ZjU4LTg2ZDktNTNiN2I2ODM4YjY3IzU1YjFjNGUzZTRiMGQ4OTUxMGM2YWEyNw
i want to generate UUID for this

You can convert as below using 2 functions. apache commons codec jar has some methods to encode and decode UUID using Base64.
Link to download apache commons codec jar: http://www.java2s.com/Code/JarDownload/apache-commons/apache-commons-codec-1.4.jar.zip
import java.nio.ByteBuffer;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
public class Solution1 {
public static void main(String[] args) {
String uuid_str = "YjRmYTJhMGEtYjI0ZC00ZjU4LTg2ZDktNTNiN2I2ODM4YjY3IzU1YjFjNGUzZTRiMGQ4OTUxMGM2YWEyNw";
String uuid_as_64 = uuidFromBase64(uuid_str);
System.out.println("as base64: "+uuid_as_64);
System.out.println("as uuid: "+uuidFromBase64(uuid_as_64));
}
private static String uuidToBase64(String str) {
Base64 base64 = new Base64();
UUID uuid = UUID.fromString(str);
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return base64.encodeBase64URLSafeString(bb.array());
}
private static String uuidFromBase64(String str) {
Base64 base64 = new Base64();
byte[] bytes = base64.decodeBase64(str);
ByteBuffer bb = ByteBuffer.wrap(bytes);
UUID uuid = new UUID(bb.getLong(), bb.getLong());
return uuid.toString();
}
}
Output:
as base64: 62346661-3261-3061-2d62-3234642d3466
as uuid: eb6df8eb-aeb5-fb7d-bad7-edf4eb5fb677
For more, you can follow the tutorial:
http://www.baeldung.com/java-base64-encode-and-decode
http://www.tutorialspoint.com/java8/java8_base64.htm
How can I convert a UUID to base64?
Storing UUID as base64 String

The above base64 string decodes to ASCII string "b4fa2a0a-b24d-4f58-86d9-53b7b6838b67#55b1c4e3e4b0d89510c6aa27", so:
import org.apache.commons.codec.binary.Base64;
public class Solution {
private static String uuidFromBase64(String str) {
Base64 base64 = new Base64();
byte[] bytes = base64.decodeBase64(str);
String s = new String(bytes);
String trimmed = s.split("#")[0];
return trimmed;
}
}

Related

Base64 Encoding: Illegal base64 character 3c

I am trying to decode data in an xml format into bytes base64 and I am having an issues. My method is in java which takes a String data and converts it into bytes like as bellow.
String data = "......"; //string of data in xml format
byte[] dataBytes = Base64.getDecoder().decode(data);
Which failed and gave the exception like bellow.
java.lang.IllegalArgumentException: Illegal base64 character 3c
at java.util.Base64$Decoder.decode0(Base64.java:714)
at java.util.Base64$Decoder.decode(Base64.java:526)
at java.util.Base64$Decoder.decode(Base64.java:549)
at XmlReader.main(XmlReader.java:61)
Is the xml format not compatible with base64?
Just use this method
getMimeDecoder()
String data = "......";
byte[] dataBytes = Base64.getMimeDecoder().decode(data);
I got this same error and problem was that the string was starting with data:image/png;base64, ...
The solution was:
byte[] imgBytes = Base64.getMimeDecoder().decode(imgBase64.split(",")[1]);
You should first get the bytes out of the string (in some character encoding).
For these bytes you use the encoder to create the Base64 representation for that bytes.
This Base64 string can then be decoded back to bytes and with the same encoding you convert these bytes to a string.
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Base64Example {
public static void main(String[] args) {
final String xml = "<root-node><sub-node/></root-node>";
final byte[] xmlBytes = xml.getBytes(StandardCharsets.UTF_8);
final String xmlBase64 = Base64.getEncoder().encodeToString(xmlBytes);
System.out.println(xml);
System.out.println(xmlBase64);
final byte[] xmlBytesDecoded = Base64.getDecoder().decode(xmlBase64);
final String xmlDecoded = new String(xmlBytesDecoded, StandardCharsets.UTF_8);
System.out.println(xmlDecoded);
}
}
Output is:
<root-node><sub-node/></root-node>
PHJvb3Qtbm9kZT48c3ViLW5vZGUvPjwvcm9vdC1ub2RlPg==
<root-node><sub-node/></root-node>
Thanks to #luk2302 I was able to resolve the issue. Before decoding the string, I need to first encode it to Base64
byte[] dataBytes = Base64.getEncoder().encode(data.getBytes());
dataBytes = Base64.getDecoder().decode(dataBytes);

Issue while converting byte[] to string

I have a problem with converting byte[] to string.
I have encrypted using encryptText(), it returns byte[]. And then I'm passing byte[] to convert to string using byteToString().
Converting byte[] to String:
s = bytesToString(cipherText); //junk value getting here, i'm expecting
same encrypted value here even after converting byte[] to string
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.prefs.Preferences;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
public class Test {
private Test() { }
/**
* gets the AES encryption key.
* #return
* #throws Exception
*/
public static SecretKey getSecretEncryptionKey() throws Exception
{
KeyGenerator generator = KeyGenerator.getInstance("AES");
generator.init(128);
SecretKey secKey = generator.generateKey();
return secKey;
}
/**
* Encrypts password in AES using the secret key.
* #param passWord
* #param secKey
* #return
* #throws Exception
*/
public static byte[] encryptText(String passWord,SecretKey secKey) throws Exception
{
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
byte[] byteCipherText = aesCipher.doFinal(passWord.getBytes());
return byteCipherText;
}
/**
* Decrypts encrypted byte array using the key used for encryption.
* #param byteCipherText
* #param secKey
* #return
* #throws Exception
*/
public static String decryptText(byte[] byteCipherText, SecretKey secKey) throws Exception
{
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE, secKey);
byte[] bytePlainText = aesCipher.doFinal(byteCipherText);
return new String(bytePlainText);
}
//converting byte[] to string
private static String bytesToString(byte[] bytesArray)
{
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < bytesArray.length; i++) {
stringBuffer.append((char) bytesArray[i]);
}
return stringBuffer.toString();
}
public static void main(String args[]) throws Exception
{
SecretKey secKey = getSecretEncryptionKey();
String s = null;
String Username = null;
String Password = null;
String value = null;
try
{
if(args[0] != null)
Username = args[0];
if(args[1] != null)
Password = args[1];
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException caught");
}
finally {
}
byte[] cipherText = encryptText(Password, secKey);
s = bytesToString(cipherText); //junk value getting here, i'm expecting same encrypted value here even after converting byte[] to string
System.out.println("Encrypted cipherText = " + cipherText);
System.out.println("Encrypted Password = " + s);
System.out.println("Done." );
}
}
Short answer: use new String(bytes, "utf8") (or any other charset bytes of which you have).
But in your case bytes returned by encryption function may be impossible to convert to utf8-string. You can't just take arbitrary bytes and convert it to string because some byte sequences could not be interpreted as valid utf8.
You may want to use some single-byte charset to solve the problem. But I generally recommend not to convert to string bytes that are not meant to be string.
An encrypted content is not meant to be read by a human being it is a pure binary content, but if you really need to make it readable you should encode it to an hexadecimal value using Apache Commons Codec
Your method would then be:
private static String bytesToString(byte[] bytesArray){
return Hex.encodeHexString(bytesArray);
}
Another approach could be to append each byte directly to stringBuffer instead of casting them as a char first as next:
private static String bytesToString(byte[] bytesArray) {
StringBuilder stringBuffer = new StringBuilder();
for (int i = 0; i < bytesArray.length; i++) {
stringBuffer.append(bytesArray[i]);
}
return stringBuffer.toString();
}
s = new String(cipherText, "utf8"); is not working!
It cannot work because cipherText is not the UTF8 encoded version of a given String but an array of bytes corresponding to an encrypted content. In other words it is somehow equivalent to encode your String with a given algorithm and try to decode it using the decode function of a totally different algorithm, it simply cannot work.

Java Base64 Decoding/Encoding rountrip doesn't come up with same result

import org.junit.Test;
import java.util.Base64;
import org.junit.Assert.*;
import java.util.Random;
...
#Test
public void testEncoding(){
byte[] data = new byte[32];
new Random().nextBytes(data);
String base64 = Base64.getEncoder().encodeToString(data);
assertEquals(data, Base64.getDecoder().decode(base64));
}
#Test
public void testDecoding(){
String base64 = "ABCDEFGHIJKLRMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/A==";
byte[] data = Base64.getDecoder().decode(base64);
assertEquals(base64, Base64.getEncoder().encodeToString(data));
}
The testEncoding test fails with an AssertionError:
Expected :[B#6bf2d08e
Actual :[B#5eb5c224
And I can't see why.
The flaw is in then Assertion not in the code.
assertEquals will compare the address of the byte array in memory
assertArrayEquals will compare the content of the byte array
Try this. You should encode a normal String, and decode a normal String, not a byte-array:
#Test
public void verify() throws Exception {
String normalString = "ABCDEFGHIJKLRMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/A==";
byte[] asBytes = normalString.getBytes();
String encoded = Base64.getEncoder().encodeToString(asBytes);
byte[] decodedBytes = Base64.getDecoder().decode(encoded);
String decoded = new String(decodedBytes);
assertEquals(normalString , decoded);
}

Base64 Java encode and decode a string [duplicate]

This question already has answers here:
Encoding as Base64 in Java
(19 answers)
Closed 7 years ago.
I want to encode a string into base64 and transfer it through a socket and decode it back.
But after decoding it gives different answer.
Following is my code and result is "77+9x6s="
import javax.xml.bind.DatatypeConverter;
public class f{
public static void main(String a[]){
String str = new String(DatatypeConverter.parseBase64Binary("user:123"));
String res = DatatypeConverter.printBase64Binary(str.getBytes());
System.out.println(res);
}
}
Any idea about how to implement this?
You can use following approach:
import org.apache.commons.codec.binary.Base64;
// Encode data on your side using BASE64
byte[] bytesEncoded = Base64.encodeBase64(str.getBytes());
System.out.println("encoded value is " + new String(bytesEncoded));
// Decode data on other side, by processing encoded data
byte[] valueDecoded = Base64.decodeBase64(bytesEncoded);
System.out.println("Decoded value is " + new String(valueDecoded));
Hope this answers your doubt.
Java 8 now supports BASE64 Encoding and Decoding. You can use the following classes:
java.util.Base64, java.util.Base64.Encoder and java.util.Base64.Decoder.
Example usage:
// encode with padding
String encoded = Base64.getEncoder().encodeToString(someByteArray);
// encode without padding
String encoded = Base64.getEncoder().withoutPadding().encodeToString(someByteArray);
// decode a String
byte [] barr = Base64.getDecoder().decode(encoded);
The accepted answer uses the Apache Commons package but this is how I did it using Java's native libraries
Java 11 and up
import java.util.Base64;
public class Base64Encoding {
public static void main(String[] args) {
Base64.Encoder enc = Base64.getEncoder();
Base64.Decoder dec = Base64.getDecoder();
String str = "77+9x6s=";
// encode data using BASE64
String encoded = enc.encodeToString(str.getBytes());
System.out.println("encoded value is \t" + encoded);
// Decode data
String decoded = new String(dec.decode(encoded));
System.out.println("decoded value is \t" + decoded);
System.out.println("original value is \t" + str);
}
}
Java 6 - 10
import java.io.UnsupportedEncodingException;
import javax.xml.bind.DatatypeConverter;
public class EncodeString64 {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "77+9x6s=";
// encode data using BASE64
String encoded = DatatypeConverter.printBase64Binary(str.getBytes());
System.out.println("encoded value is \t" + encoded);
// Decode data
String decoded = new String(DatatypeConverter.parseBase64Binary(encoded));
System.out.println("decoded value is \t" + decoded);
System.out.println("original value is \t" + str);
}
}
The better way would be to try/catch the encoding/decoding steps but hopefully you get the idea.
For Spring Users , Spring Security has a Base64 class in the org.springframework.security.crypto.codec package that can also be used for encoding and decoding of Base64.
Ex.
public static String base64Encode(String token) {
byte[] encodedBytes = Base64.encode(token.getBytes());
return new String(encodedBytes, Charset.forName("UTF-8"));
}
public static String base64Decode(String token) {
byte[] decodedBytes = Base64.decode(token.getBytes());
return new String(decodedBytes, Charset.forName("UTF-8"));
}
The following is a good solution -
import android.util.Base64;
String converted = Base64.encodeToString(toConvert.toString().getBytes(), Base64.DEFAULT);
String stringFromBase = new String(Base64.decode(converted, Base64.DEFAULT));
That's it. A single line encoding and decoding.
import javax.xml.bind.DatatypeConverter;
public class f{
public static void main(String a[]){
String str = new String(DatatypeConverter.printBase64Binary(new String("user:123").getBytes()));
String res = DatatypeConverter.parseBase64Binary(str);
System.out.println(res);
}
}

Encrypting and decrypting String with special character

I am trying to encrypt a Client' name (string format) storing it in a database and then retrieving it and decrypting it. As i need to avoid any third part libraries, i have used classes which are readily available with Java distribution.
The process was working fine, until I encountered a name with a special character (Ascii : 48910). This was geting displayed as a question mark(?). The encryption and descryption went fine, but after the decryption the special character was replaced with the question mark.
So i changed the Encoding format from 'UTF-8' to 'ISO-8859-1'. This solved the display problem, but still the special character gets replaced after decryption.
The code being used and the output is given below (i have removed the unnecessary code):
package crypt;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.xml.bind.DatatypeConverter;
public class SecretKeyEncryptionExample {
private static final String FORMAT = "ISO-8859-1";
public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
private KeySpec ks;
private SecretKeyFactory skf;
private Cipher cipher;
SecretKey key;
public SecretKeyEncryptionExample() throws Exception {
String myEncryptionKey = "4A144BEBF7E5E7B7DCF26491AE79C54C768C514CF1547D23";
ks = new DESedeKeySpec(myEncryptionKey.getBytes(FORMAT));
skf = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
key = skf.generateSecret(ks);
}
public String encrypt(String unencryptedString) throws Exception {
String encryptedString = null;
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(FORMAT);
byte[] encryptedText = cipher.doFinal(plainText);
encryptedString = DatatypeConverter.printBase64Binary(encryptedText);
return encryptedString;
}
public String decrypt(String encryptedString) throws Exception {
String decryptedText = null;
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = DatatypeConverter.parseBase64Binary(encryptedString);
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText = new String(plainText);
return decryptedText;
}
public static void main(String args[]) throws Exception {
SecretKeyEncryptionExample td = new SecretKeyEncryptionExample();
String target = "Expendable" + getSpecialCharacter(49810) + "s Pte Ltd";
String encrypted = td.encrypt(target);
String decrypted = td.decrypt(encrypted);
PrintStream out = new PrintStream(System.out, true, FORMAT);
out.println("String To Encrypt: " + target);
out.println("Encrypted String: " + encrypted);
out.println("Decrypted String: " + decrypted);
}
public static String getSpecialCharacter(int code) {
Charset charSet = Charset.forName(FORMAT);
String specialCharacter = new String(new byte[] { (byte) code }, charSet);
specialCharacter = String.format("%s", specialCharacter);
return specialCharacter;
}
}
OUTPUT:
String To Encrypt: Expendable’s Pte Ltd
Encrypted String: TAAJuF7KOmBZHBXFHsW0FB9YBwH7Tcif
Decrypted String: Expendable?s Pte Ltd
Please let know how the decryption can be attained, without getting the special character replaced.
I think you should specify your encoding every time you go from a string to a byte array and back. In particular, this line:
decryptedText = new String(plainText);
should read:
decryptedText = new String(plainText, FORMAT);
Otherwise you rely on your environment's encoding, which in all likelihood differs from FORMAT and result in the special character being printed as "?".
Some things which may be useful to know.
System.out.println((int) getSpecialCharacter(49810).charAt(0));
prints
146
This is the character you are actually creating here.
System.out.println("The Falcon" + (char) 146 + "s Hangar Pte Ltd");
prints
The Falcon’s Hangar Pte Ltd
I think the problem is that you get the bytes using the ISO-8859-1 character set with
byte[] plainText = unencryptedString.getBytes(FORMAT);
but when you turn it back into a String you use the system default.
decryptedText = new String(plainText);
I suspect this should be
decryptedText = new String(plainText, FORMAT); // use the same Charset

Categories

Resources