I use this code in C#.net to send challenge to web page.
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
Byte[] rnd = new Byte[64];
rng.GetBytes(rnd);
hidChallenge.Value = Encoding.Unicode.GetString(rnd);
And I in java script use of it.
var base64str = document.getElementById("<%=hidChallenge.ClientID %>");
When run and debug:
base64str = 感≗좦短䗅燛梻脕冔춇噙풣訋詇蹘᧩쾏휇늸䫐顨◣希ࠟ䠎ᐷ
But in java (JSP)
I use this code:
Random r = new Random();
byte[] rndbyte = new byte[64];
r.nextBytes(rndbyte);
String challenge = new String(rndbyte,StandardCharsets.UTF_16LE);
session.setAttribute("challenge", challenge);
And in javascript:
var base64str = 퓻�ꦖ쁳春꼪ꝝ䣇͋ꟼ鱐䆺㺪᠁郷̣攺줶ꋏ歮㏹㬎ꢔ崬魔弝孓翊
I try follow charset also:
US_ASCII
UTF_8
UTF_16
So I get base 64 string error.
it sounds like there is a confusion between what UTF-8/16 or Ascii are for, and Base64.
UTF-8 is meant to encode string to byte sequence. And Base64 is meant to encode byte sequence to string.
If you want to generate base64 in Java, here is how it should look like:
Random r = new Random();
byte[] rndbyte = new byte[64];
r.nextBytes(rndbyte);
String challenge = Base64.encodeBase64String(rndbyte);
session.setAttribute("challenge", challenge);
Here is another post that explain pretty good the difference, if you want to know more about this:
What's the difference between UTF8/UTF16 and Base64 in terms of encoding
Related
I need to convert PDF content to Base64 and use that as a String.
When I use the below program to test the out.pdf becomes blank.
byte[] pdfRawData = FileUtils.readFileToByteArray(new File("C:\\in.pdf")) ;
String pdfStr = new String(pdfRawData);
//My data is available in the form of String
BASE64Encoder encoder = new BASE64Encoder();
String encodedPdf = encoder.encode(pdfStr.getBytes());
System.out.println(encodedPdf);
// Decode the encoded content to test
BASE64Decoder decoder = new BASE64Decoder();
FileUtils.writeByteArrayToFile(new File("C:\\out.pdf") , decoder.decodeBuffer(encodedPdf));
Can anyone please help me?
Why are you doing:
String pdfStr = new String(pdfRawData);
instead of passing pdfRawData to the encoder?
Doing so lead to lots of encoding issue, as you don't specify the encoding of the byte array to use to build the string (it will use platform default). And this is clearly redondant (byte array -> string -> byte array)
I'm converting an old VB.net project to Java (I barely know any VB).
Dim asciis As Byte() = System.Text.Encoding.ASCII.GetBytes(name)
For i As Int32 = 0 To asciis.Length - 1
asciis(i) = CByte(asciis(i) + 1)
Next
Dim encryptedName As String = StrReverse(Uri.EscapeDataString(System.Text.Encoding.ASCII.GetString(asciis, 0, asciis.Count())))
I converted it to:
byte[] asciis = name.getBytes();
for (int i =0; i<asciis.length-1;i++){
asciis[i] = (byte)(asciis[i]+1);
}
String encryptedName = StringUtils.reverse(asciis.toString()).substring(0,asciis.length);
I converted the name 29384 and the .Net gives 594A3%3 while my Java code gives d9354.
What am I missing?
This asciis.toString() is not correct (it will give you the adress of the array instead), you need to do new String(asciis, StandardCharsets.UTF_8) to create the String from the array of bytes. And you need to apply URLEncoder.encode(newString, StandardCharsets.UTF_8.name()) to apply the same URI encoding that is done in your VB code. Also you need to do name.getBytes(StandardCharsets.UTF_8) instead of just name.getBytes(), because else you'll use the default charset of the operating system it's running on, and it might not be ASCII compatible.
Alright as #Nyamiou said I had to give the charset to the String and encode it with an URLEncoder.
byte[] asciis = number.getBytes(Charset.forName("US-ASCII"));
for (int i =0; i<asciis.length;i++){
asciis[i] = (byte)(asciis[i]+1);
}
String asciiString = new String(asciis, Charset.forName("US-ASCII"));
String encryptedNumber= StringUtils.reverse(URLEncoder.encode(asciiString, "US-ASCII"));
I am trying to decode some hex values to their actual names, but i am having issue.
21043D0438043C043E043A04 should be decoded to СНИМОК.
Current code I am using
String test = "21043D0438043C043E043A04";
byte[] bytes = Hex.decodeHex(test.toCharArray());
String a = new String(bytes, "UTF-8");
but i am getting some pretty weird results.
Tried also getting it as utf8 bytes but did not work.
byte[] bytesone = test.getBytes(Charset.forName("UTF-8"));
String b = new String(bytesone, Charset.forName("UTF-8"));
byte[] bytes = Hex.decodeHex(b.toCharArray());
String a = new String(bytes, "UTF-8");
Thanks in advance
\u0421 is the Cyrillic С so the code seems UTF-16LE (little endian).
String a = new String(bytes, "UTF-16LE");
String a = new String(bytes, StandardCharsets.UTF_16LE);
This looks more like UTF-16LE.
Need to pass a tokenized (encrypted) username and date from webapp A to webapp B via a url parameter. Something like http://webappB?username=userA×tamp=13445341313 should be sent as http://webappB?token=geufjsggtj26hjdhcjre87klj3. The receiving webapp B should be able to decode the token into the original parameters.
Which technology offers a simple solution that is available for .NET and java? Thanks
I would like to share the solution that I found after some more research.
I chose a very simple symmetric XOR based scramble method in favour of using encryption across platforms.
A piece of code says more than thousand words :
// webappA, encode URL parameter
byte[] userBytes = username.getBytes("UTF-8");
byte[] keyBytes = key.getBytes("UTF-8");
//XOR scramble
byte[] encrypted = new byte[userBytes.length];
for(int i = 0; i < userBytes.length; i++){
encrypted[i] = (byte)(userBytes[i] ^ keyBytes[i % keyBytes.length]);
}
BASE64Encoder encoder = new BASE64Encoder();
String encoded = encoder.encode(encrypted);
// webappB, decode the parameter
BASE64Decoder decoder = new BASE64Decoder();
byte[] decoded = decoder.decodeBuffer( encoded );
//XOR descramble
byte[] decrypted = new byte[decoded.length];
for(int i = 0; i < decoded.length; i++){
decrypted[i] = (byte)(decoded[i] ^ keyBytes[i % keyBytes.length] );
}
What you've suggested is very simple and doesn't require including technologies outside of what Java and .NET already offer. Simply build up an HTTP request, fire it to the right URL, and listen for the response.
Class References
Java: HttpURLConnectionOracle
.NET: WebRequestMSDN
If you think you'll be doing more of this, or the data gets more frequent, complex, or structured, I highly recommend the ubiquitous SOAPWikipedia protocol for extensibility and modularity.
Is it possible to convert a string to a byte array and then convert it back to the original string in Java or Android?
My objective is to send some strings to a microcontroller (Arduino) and store it into EEPROM (which is the only 1 KB). I tried to use an MD5 hash, but it seems it's only one-way encryption. What can I do to deal with this issue?
I would suggest using the members of string, but with an explicit encoding:
byte[] bytes = text.getBytes("UTF-8");
String text = new String(bytes, "UTF-8");
By using an explicit encoding (and one which supports all of Unicode) you avoid the problems of just calling text.getBytes() etc:
You're explicitly using a specific encoding, so you know which encoding to use later, rather than relying on the platform default.
You know it will support all of Unicode (as opposed to, say, ISO-Latin-1).
EDIT: Even though UTF-8 is the default encoding on Android, I'd definitely be explicit about this. For example, this question only says "in Java or Android" - so it's entirely possible that the code will end up being used on other platforms.
Basically given that the normal Java platform can have different default encodings, I think it's best to be absolutely explicit. I've seen way too many people using the default encoding and losing data to take that risk.
EDIT: In my haste I forgot to mention that you don't have to use the encoding's name - you can use a Charset instead. Using Guava I'd really use:
byte[] bytes = text.getBytes(Charsets.UTF_8);
String text = new String(bytes, Charsets.UTF_8);
You can do it like this.
String to byte array
String stringToConvert = "This String is 76 characters long and will be converted to an array of bytes";
byte[] theByteArray = stringToConvert.getBytes();
http://www.javadb.com/convert-string-to-byte-array
Byte array to String
byte[] byteArray = new byte[] {87, 79, 87, 46, 46, 46};
String value = new String(byteArray);
http://www.javadb.com/convert-byte-array-to-string
Use [String.getBytes()][1] to convert to bytes and use [String(byte[] data)][2] constructor to convert back to string.
byte[] pdfBytes = Base64.decode(myPdfBase64String, Base64.DEFAULT)
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
public class FileHashStream
{
// write a new method that will provide a new Byte array, and where this generally reads from an input stream
public static byte[] read(InputStream is) throws Exception
{
String path = /* type in the absolute path for the 'commons-codec-1.10-bin.zip' */;
// must need a Byte buffer
byte[] buf = new byte[1024 * 16]
// we will use 16 kilobytes
int len = 0;
// we need a new input stream
FileInputStream is = new FileInputStream(path);
// use the buffer to update our "MessageDigest" instance
while(true)
{
len = is.read(buf);
if(len < 0) break;
md.update(buf, 0, len);
}
// close the input stream
is.close();
// call the "digest" method for obtaining the final hash-result
byte[] ret = md.digest();
System.out.println("Length of Hash: " + ret.length);
for(byte b : ret)
{
System.out.println(b + ", ");
}
String compare = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
String verification = Hex.encodeHexString(ret);
System.out.println();
System.out.println("===")
System.out.println(verification);
System.out.println("Equals? " + verification.equals(compare));
}
}