byte[] to String {100,25,28,-122,-26,94,-3,-26} - java

How can I convert this byte[] to String :
byte[] mytest = new byte[] {100,25,28,-122,-26,94,-3,-26};
i get this : "d��^�" when I use :
new String( mytest , "UTF-8" )
Here is code java for creation of key :
m_key = new javax.crypto.spec.SecretKeySpec(new byte[] {100,25,28,-122,-26,94,-3,-26}, "DES");
Thanks.

In order to decode the byte array into something like ASCII, you need to know its original encoding. Otherwise you would need to treat it as binary.
Note: Base64 is intended for transferring binary data across networks.
I would suggest Base64 encoding your byte array. Then in your PHP code decoding the Base64 string back into a UTF-8 string.
In Java, here's how to Base64 encode your byte array and then decode it back to UTF-8:
import org.apache.commons.codec.binary.Base64;
public class MyTest {
public static void main(String[] args) throws Exception {
byte[] byteArray = new byte[] {100,25,28,-122,-26,94,-3,-26};
System.out.println("To UTF-8 string: " + new String(byteArray, "UTF-8"));
byte[] base64 = Base64.encodeBase64(byteArray);
System.out.println("To Base64 string: " + new String(base64, "UTF-8"));
byte[] decoded = Base64.decodeBase64(base64);
System.out.println("Back to UTF-8 string: " + new String(decoded, "UTF-8"));
/* the decoded byte array is the same as the original byte array */
for (int i = 0; i < decoded.length; i++) {
assert byteArray[i] == decoded[i];
}
}
}
The output from the above code is:
To UTF-8 string: d��^�
To Base64 string: ZBkchuZe/eY=
Back to UTF-8 string: d��^�
So if you wanted to use the same binary data in your PHP code, cut and paste the Base64 string into your PHP code and decode it back to UTF-8. Something like this:
<?php
$str = 'ZBkchuZe/eY=';
$key = base64_decode($str);
echo $key;
?>
I don't code in PHP, but you should be able to decode Base64 using this method:
http://php.net/manual/en/function.base64-decode.php
The above code should echo back the original binary data as UTF-8 (albeit with funny characters). The point is that the funny-looking string in the $key variable is representing the same binary data you had in the Java byte array:
d��^�
You should be able to pass the $key variable into your PHP encryption method.

with the way you are doing it makes no sense imo. you are creating a new string with the byte[] as an argument. i dont think that function is suppose to parse. so what you end up with is a lot of junk. but a little bit of googling got me this: http://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/

Would m_key.getEncoded() give you the desired result.
Javadocs - SecretKeySpec
If not, you have to identify the Key provider that was used for the encoding (which resulted in the byte array that you have now) and decode.

Related

Java Base64 Encode function the same as PHP Base64 Encode function?

I'm trying to test a Soap Security header in PHP with values supplied by the client.
They are supplying a value like...
wTAmCL9tmg6KNpeAQOYubw==
...and saying it's a Base64 encoded value.
However, when I run it through PHP's Base64 decode function...
base64_decode("wTAmCL9tmg6KNpeAQOYubw==");
it translates it as: �0&�m6#�.o
If I decode it in Java...
import java.util.Base64;
import java.util.Arrays;
/**
* hello
*/
public class hello {
public static void main(String[] args) {
Base64.Decoder decoder = Base64.getDecoder();
Base64.Encoder encoder = Base64.getEncoder();
String stringEncoded = "wTAmCL9tmg6KNpeAQOYubw==";
System.out.println("This is a decoded value: " + decoder.decode(stringEncoded));
System.out.println("This is a re-coded value: " + encoder.encode(decoder.decode(stringEncoded)));
}
}
I get a decoded string like this: [B#7229724f
But then if I try to re-encode that string, I get this: [B#4c873330
What am I missing here?
What you are missing is that the result of decoding the Base 64 value is not intended to be printed as a String. In fact, you see this in the output of the Java println. That [B#7229724f is not a string representation of the decoded bytes. It is the way a Java byte [] prints. The [B indicates a byte array, and the remaining characters are the hexadecimal digits of the object identity. (It will print differently for every byte array instance and has nothing to do with the contents of the array.)
If you want the String representation of the bytes you will need to construct a String from the bytes:
System.out.println("This is a decoded value: " + new String(decoder.decode(stringEncoded), StandardCharsets.UTF_8));
System.out.println("This is a re-coded value: " + new String(encoder.encode(decoder.decode(stringEncoded), StandardCharsets.UTF_8));
Based on this answer how about specify the encoding. Recommended encoding is UTF-8.

Java base64 encode, decode yield different results

I'm using this:
import com.sun.org.apache.xml.internal.security.utils.Base64; to encode/decode Base64 strings and byte arrays to store into a db.
I'm testing out encoding and decoding to see if I can get back the original string:
SecureRandom srand = new SecureRandom();
byte[] randomSalt = new byte[64];
srand.nextBytes(randomSalt);
System.out.println("rand salt bytes: " + randomSalt); // first line
String salt = Base64.encode(randomSalt);
try {
System.out.println(Base64.decode(salt)); // second line
}catch(Base64DecodingException e){
System.out.println(e);
}
However, this prints out:
rand salt bytes: [B#68286c59
[B#44d01f20
Why are these not the same, so that I can get back the original byte array?
What you are doing is actually dealing with the java pointer instead of the actual bytes.
This is the correct way to implement
byte[] bytesEncoded = Base64.encodeBase64(str .getBytes());
System.out.println("ecncoded 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));

encrypt and decrypt string

I have a question regarding encrypting and decrypting a string
I have to send a encrypted string over the network.(an android app is the client) this is what i did so far
byte[] input = getByteArray(filePath);//get the message stored in a file as a byte array
by going through some tutorial i managed to get the String message to a byte array and
encrypted it using javax.crypto
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
encrypted msg is retrived as a byte array
byte[] encrypted
i even managed to decrypt it using the reverse method and get the message again
but my problem comes when i try to convert this encrypted byte array to strings (to pass it over the network)
and then reconvert it to a byte array
i tryed this
String encryptedStrn = new String(encrypted); // convert to string
when i convert it to the byte array by
byte[] enc = encryptedStrn.getBytes();
and use this enc array to decrypt but the output does not come correctly.
Have i missed some basic stuff regarding converting. Please help me.
thanks in advance
As CodeInChaos wrote in a comment, you shouldn't use the String(byte[]) constructor to create a string from opaque binary data. The string constructors are intended for text data which has been encoded using an encoding like ASCII, UTF-8 etc. Opaque binary data such as the result of encryption, or an image file, is not encoded text data in the same way, so you end up losing information.
You should use base64 instead, which encodes any binary data into ASCII. There are various 3rd party libraries for this, including a good public domain one. Alternatively, on Android you can just use the Base64 class.
Additionally, even when you are encoding or decoding real text, you shouldn't use String.getBytes() and the String(byte[]) constructor anyway - they use the platform default encoding, which is almost always the wrong choice. Instead, you should use the overloads which explicitly take a CharSet or the name of a character encoding. UTF-8 is typically a good encoding to use if you're able to control both ends - if you're only controlling one end, you need to know which encoding the other end is expecting.
You should base64-encode the cipher text. Don't just convert it to a String. String is not a container for binary data.
public string EncryptUser(string userID)
{
using (var cryptoProvider = new DESCryptoServiceProvider())
using (var memoryStream = new MemoryStream())
using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateEncryptor(DESKey, DESInitializationVector), CryptoStreamMode.Write))
using (var writer = new StreamWriter(cryptoStream))
{
writer.Write(userID);
writer.Flush();
cryptoStream.FlushFinalBlock();
writer.Flush();
return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
}
}
public string DecryptUserID(string userID)
{
using (var cryptoProvider = new DESCryptoServiceProvider())
using (var memoryStream = new MemoryStream(Convert.FromBase64String(userID)))
using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateDecryptor(DESKey, DESInitializationVector), CryptoStreamMode.Read))
using (var reader = new StreamReader(cryptoStream))
{
return reader.ReadToEnd();
}
}

byte to string and vice versa

I need to convert a salt value randomly generated and store it in the database. To store it in the database I converted it to a string. Then for retrieving the original value, I convert it back to byte. But both value are not matching. I have tried "UTF-8","UTF-16", BASE64Encoder.
SecureRandom ranGen = new SecureRandom();
byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
ranGen.nextBytes(aesKey);
System.out.println(aesKey);
String a=new String(aesKey,"UTF-16");
byte[] b=new byte[16];
b=a.getBytes("UTF-16");
System.out.println(b);
Outputs for the above code(Executed it 2 times):
[B#11563ff
[B#1581593
and
[B#170888e
[B#11563ff
You really ought to use Base64 for converting binary data to Strings. There are lots of free implementations available, for example the one found in Apache Commons Codec.
Also, it's really easy to use, for example:
For encoding:
import org.apache.commons.codec.binary.Base64;
...
byte[] abValue = {...}; // Your data to encode
Base64 base64 = new Base64();
String strEncodedData = base64.encodeToString(abValue).trim();
For decoding:
import org.apache.commons.codec.binary.Base64;
...
String strEncodedData = "..."; // Your previously encoded data
Base64 base64 = new Base64();
byte[] abValue = base64.decode(strValue);
As your code is written above, printing aesKey and then b, what you are actually printing is the output of the toString method for an array object, which is just the default Object toString method. So I don't see how you can expect them to be the same.
If you really want to check they are the same you should compare them byte by byte.
In terms of your actual question regarding storing a byte[] as a String in the DB, your best bet is to Base64 encode it. I would suggest using the Apache Commons Codec library for this. See the user guide.
EDIT:
Using the BASE64Encode and BASE64Decoder you have referred to, the code would be like this:
SecureRandom ranGen = new SecureRandom();
byte[] aesKey = new byte[16]; // 16 bytes = 128 bits
ranGen.nextBytes(aesKey);
String a = new BASE64Encoder().encode(aesKey);
System.out.println(a);
byte[] b = new BASE64Decoder().decodeBuffer(a);
System.out.println(new BASE64Encoder().encode(b));
for (int i = 0; i < aesKey.length; i++) {
System.out.println(aesKey[i] + " " + b[i]);
}
Here, I have also looped through the bytes individually, to show that they are indeed equal.

How do I convert a byte array to Base64 in Java?

Okay, I know how to do it in C#.
It's as simple as:
Convert.ToBase64String(byte[])
and Convert.FromBase64String(string) to get byte[] back.
How can I do this in Java?
Java 8+
Encode or decode byte arrays:
byte[] encoded = Base64.getEncoder().encode("Hello".getBytes());
println(new String(encoded)); // Outputs "SGVsbG8="
byte[] decoded = Base64.getDecoder().decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64.getEncoder().encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(Base64.getDecoder().decode(encoded.getBytes()));
println(decoded) // Outputs "Hello"
For more info, see Base64.
Java < 8
Base64 is not bundled with Java versions less than 8. I recommend using Apache Commons Codec.
For direct byte arrays:
Base64 codec = new Base64();
byte[] encoded = codec.encode("Hello".getBytes());
println(new String(encoded)); // Outputs "SGVsbG8="
byte[] decoded = codec.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
Base64 codec = new Base64();
String encoded = codec.encodeBase64String("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(codec.decodeBase64(encoded));
println(decoded) // Outputs "Hello"
Spring
If you're working in a Spring project already, you may find their org.springframework.util.Base64Utils class more ergonomic:
For direct byte arrays:
byte[] encoded = Base64Utils.encode("Hello".getBytes());
println(new String(encoded)) // Outputs "SGVsbG8="
byte[] decoded = Base64Utils.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64Utils.encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = Base64Utils.decodeFromString(encoded);
println(new String(decoded)) // Outputs "Hello"
Android (with Java < 8)
If you are using the Android SDK before Java 8 then your best option is to use the bundled android.util.Base64.
For direct byte arrays:
byte[] encoded = Base64.encode("Hello".getBytes());
println(new String(encoded)) // Outputs "SGVsbG8="
byte [] decoded = Base64.decode(encoded);
println(new String(decoded)) // Outputs "Hello"
Or if you just want the strings:
String encoded = Base64.encodeToString("Hello".getBytes());
println(encoded); // Outputs "SGVsbG8="
String decoded = new String(Base64.decode(encoded));
println(decoded) // Outputs "Hello"
Use:
byte[] data = Base64.encode(base64str);
Encoding converts to Base64
You would need to reference commons codec from your project in order for that code to work.
For java8:
import java.util.Base64
Additionally, for our Android friends (API Level 8):
import android.util.Base64
...
Base64.encodeToString(bytes, Base64.DEFAULT);
In case you happen to be using Spring framework along with java, there is an easy way around.
Import the following.
import org.springframework.util.Base64Utils;
Convert like this.
byte[] bytearr ={0,1,2,3,4};
String encodedText = Base64Utils.encodeToString(bytearr);
To decode you can use the decodeToString method of the Base64Utils class.

Categories

Resources