Java Convert Asn.1 byte Array in convienient String for Browser - java

I try to convert a ASN.1 Byte Array into a String with Java. My results up to now:
byte[] asn = ocspResponse.getEncoded();
String liccert = new String(asn, "Cp850");
This String contains some String artifakts which are very disturbing:
Like this:
4¦20110416173611Z0üÏ0üi0:0
Is there a way to convert the byte Array like this:
RFMRIwEAYDVQQIEwlsb2NhbGhvc3QxFDASBgNV?

You should absolutely not convert arbitrary binary data to a string using the String constructor. That constructor is for taking binary data which is actually encoded text and building a string from it. Your data isn't really encoded text - it's just arbitrary binary data. Pretending it was originally text is a recipe for data loss.
The best approach is usually to Base64 encode it. There are plenty of third party libraries to do this, including Apache Commons Codec or this public domain encoder.
For example, using the latter:
String liccert = Base64.encodeBytes(asn);

Related

Base64 binary data type in java

I need to attach a Base64 binary element to a SOAP message...Im doing a dry run to check if I can convert a value read from a file into Base64 binary..
Here is the below code..In the last line I try to print the type of encoded1(I assume it should be Base64 binary values) but I get the following display..."Attachment[B"...How can I confirm if its Base64 binary string?
Path path = Paths.get("c:/tomcatupload/text.csv");
byte[] attachment1 = Files.readAllBytes(path);
byte[] encoded1 = Base64.encode(attachment1);
System.out.println("Attachment"+ encoded1.getClass().getName());
Base-64 encoding is a way to convert arbitrary bytes to bytes that fit in a range of text characters in ASCII encoding. This is done without any interpretation whatsoever - raw bytes are converted to base-64 on sender's end; the receiver converts them back to a stream of bytes, and that's all there is to it.
When your code prints encoded1.getClass().getName(), all it gets is the static type of the byte array. In order to interpret the data encoded in base-64 as something meaningful to your program, you need to know the format of underlying data transported as base-64. Once the bytes are delivered to you (in your case, that's encoded1 array of bytes) you need to decide what's inside, and act accordingly.
For example, if a serialized Java object is sent to you as base-64, you need to take encoded1, make an in-memory stream from it, and read the object using the regular serialization mechanism:
ByteArrayInputStream memStream = new ByteArrayInputStream(encoded1);
ObjectInputStream objStream = new ObjectInputStream(memStream);
Object attachedObject = objStream.readObject();
The encoding by Base64.encode() was successful if and only if size of encoded1 > size of obtained attachment1.
Please refer, to understand how the encoding works.
http://en.wikipedia.org/wiki/Base64
By the way, your last statement doesn't print the array content. It prints the name of the class to which encoded1 belongs to.

How to convert byte array in String format to byte array?

I have created a byte array of a file.
FileInputStream fileInputStream=null;
File file = new File("/home/user/Desktop/myfile.pdf");
byte[] bFile = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
fileInputStream.read(bFile);
fileInputStream.close();
}catch(Exception e){
e.printStackTrace();
}
Now,I have one API, which is expecting a json input, there I have to put the above byte array in String format. And after reading the byte array in string format, I need to convert it back to byte array again.
So, help me to find;
1) How to convert byte array to String and then back to the same byte array?
The general problem of byte[] <-> String conversion is easily solved once you know the actual character set (encoding) that has been used to "serialize" a given text to a byte stream, or which is needed by the peer component to accept a given byte stream as text input - see the perfectly valid answers already given on this. I've seen a lot of problems due to lack of understanding character sets (and text encoding in general) in enterprise java projects even with experienced software developers, so I really suggest diving into this quite interesting topic. It is generally key to keep the character encoding information as some sort of "meta" information with your binary data if it represents text in some way. Hence the header in, for example, XML files, or even suffixes as parts of file names as it is sometimes seen with Apache htdocs contents etc., not to mention filesystem-specific ways to add any kind of metadata to files. Also, when communicating via, say, http, the Content-Type header fields often contain additional charset information to allow for correct interpretation of the actual Contents.
However, since in your example you read a PDF file, I'm not sure if you can actually expect pure text data anyway, regardless of any character encoding.
So in this case - depending on the rest of the application you're working on - you may want to transfer binary data within a JSON string. A common way to do so is to convert the binary data to Base64 and, once transferred, recover the binary data from the received Base64 string.
How do I convert a byte array to Base64 in Java?
is a good starting point for such a task.
String class provides an overloaded constructor for this.
String s = new String(byteArray, "UTF-8");
byteArray = s.getBytes("UTF-8");
Providing an explicit encoding charset is encouraged because different encoding schemes may have different byte representations. Read more here and here.
Also, your inputstream maynot read all the contents in one go. You have to read in a loop until there is nothing more left to be read. Read the documentation. read() returns the number of bytes read.
Reads up to b.length bytes of data from this input stream into an
array of bytes. This method blocks until some input is available
String.getBytes() and String(byte[] bytes) are methods to consider.
Convert byte array to String
String s = new String(bFile , "ISO-8859-1" );
Convert String to byte array
byte bArray[] =s.getBytes("ISO-8859-1");

how to make a searchable String ID with a byte[] using java and hibernate

i am working on a RFID project, in which i should identify vehicles with their RFID tag.
the RFID Tags contain 14 bytes of data.
my first clue was to convert each byte of the array to string something like this :
public String convertByteToString(byte[] tag)
{
String stringRfid ="";
for(int i=0; i<14; i++)
stringRfid = stringRfid + tag[i];
return stringRfid;
}
i don't know if this is a humble solution or what. some say and i quote it "storing raw byte[] in BLOB - the safest and most storage-effective way."
would you please give me tip what is the fastest and easiest and also efficient way to do this?
I would transform the byte array to a base64-encoded readable string, and store this string in the database. It would only increase the size with a 4/3 ratio (so around 20 bytes instead of 14), and would store readable, indexable and printable ascii strings in the database.
Guava and apache commons-codec both have a free base64 encoder/decoder.

String to byte and viceversa in java

I am converting a byte[] array to string . And then converting the string back to byte[] array. Then on checking if both the arrays are equal - I get that they are not equal:
byte[] ciphertext2=c.doFinal(username.getBytes("utf-8"));
//JUST CHECKING IGNORE
String qaz=new String(ciphertext2,"utf-8");
//qaz=qaz+"1";
System.out.println("just chekcing------------------------"+qaz);
byte[] ciphertext3=qaz.getBytes("utf-8");
if(Arrays.equals(ciphertext2,ciphertext3))
{
System.out.println("just chekcing they are equal------------------------");
}
else
System.out.println("just chekcing they are not equal------------------------");<br>
OUTPUT :
just chekcing they are not equal--------------------
Why doesn't it work?
Edit
It works perfectly fine when using Base64 of java. But why doesn't it work when converting byte to string and vice-versa directly? What actually happens when you convert a string a byte array and vice versa?
If this is the result of encryption, you should not be using a string constructor. You don't have encoded text - you have arbitrary binary data. You need to understand the difference between data which is fundamentally text and which needs to be represented in binary (e.g. writing a text file to disk) and data which is fundamentally binary and which needs to be represented in text (e.g. including encrypted data in an XML document).
You should use base64 (e.g. with this public domain library) or possibly hex. This will result in ASCII data which is guaranteed to roundtrip to the original binary data.

Use Java Serialization to Save Object

I'm planning to use Serialization to save the Bean modified by user--to store the history record. But the ByteArrayOutputStream output a byte array:byte[]. If I convert it to String and convert it back, then it can't be de-serialized. --How to explain this?
If I use byte array to store in the oracle, it's complicated.Is there any way to make the String can be de-serialized? Thank you!
I'm a Chinese, so forgive me for my bad English. :)
Use ObjectOutputStream to serialize and ObjectInputStream to deserialize objects. The API documentation of those classes has examples that show how to use them to serialize and deserialize objects to and from a file.
Don't try to force a byte[] into a String. (Why would you want to put it in a String?). Serialized objects are binary data, not text characters that you would store in a String.
Brief Answer: encode the byte array as a Base64 string.
Base64 is a way of ensuring that binary data can be stored and transmitted as text - a reasonable explanation can be found on Wikipedia; if you don't encode the byte array, data can easily become "corrupted" by the use of different codepages etc. One thing to be aware of - base64 encoding will take more space than the byte array (so a byte array of 20 bytes may take around 30 characters to be stored)
There are many libraries that can encode/decode Base64 Apache Commons Codec is just one. See this question for more discussions on which library to use (there is a "private" one in the JDK, but use of it may be considered questionable by some developers).
So, in summary, to serialize an object into string, us an ObjectOutputStream and a ByeArrayOutputStream to convert to a byte array, and then use a Base64 encoder to translate that into a string.
To deserialize, use a Base64 decoder to convert the string back into a byte array, and then use a ByteArrayInputStream and a ObjectInputStream to read it back.
In byte[] all possible byte values can be used i.e. -128 to 127. However, in text these values and combination of values can be invalid and not convert to text as expected.
I suggest you consider a text based serialization like XML or JSon. These can be read/written as text safely. Text base serialization can be read by a human and possibly edited as text if you want to correct a value.
EDIT: I would look at using XMLEncoder which is crude, but built in or XStream for XML and JSon, which is more flexible and efficient (but requires a couple of extra libraries)
static final String SQL_SERIALIZE_OBJECT="insert into serialized_java_objects(serialized_id,object_name,serialized_object) values (ser_id_seq.nextval,?,?)";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(objectToBeSerilize);
byte[] serializeBytes = baos.toByteArray();
prepStatement = connection.prepareStatement(SQL_SERIALIZE_OBJECT);
prepStatement.setString(1, objectToBeSerilize.getClass().getName());
prepStatement.setBytes(2, serializeBytes);
prepStatement.executeUpdate();

Categories