JAVA: failing to get encrypted data in string using xor - java

I was trying to print encrypted text using string perhaps i was wrong somewhere. I am doing simple xor on a plain text. Coming encrypted text/string i am putting in a C program and doing same xor again to get plain text again.
But in between, I am not able to get proper string of encrypted text to pass in C
String xorencrypt(byte[] passwd,int pass_len){
char[] st = new char[pass_len];
byte[] crypted = new byte[pass_len];
for(int i = 0; i<pass_len;i++){
crypted[i] = (byte) (passwd[i]^(i+1));
st[i] = (char)crypted[i];
System.out.println((char)passwd[i]+" "+passwd[i] +"= " + (char)crypted[i]+" "+crypted[i]);/* characters are printed fine but problem is when i am convering it in to string */
}
return st.toString();
}
I don't know if any kind of encoding also needed because if i did so how I will decode and decrypt from C program.
example if suppose passwd = bond007
then java program should return akkb78>
further C program will decrypt akkb78> to bond007 again.

Use
return new String(crypted);
in that case you don't need st[] array at all.
By the way, the encoded value for bond007 is cmm`560 and not what you posted.
EDIT
While solution above would most likely work in most java environments, to be safe about encoding,
as suggested by Alex, provide encoding parameter to String constructor.
For example if you want your string to carry 8-bit bytes :
return new String(crypted, "ISO-8859-1");
You would need the same parameter when getting bytes from your string :
byte[] bytes = myString.getBytes("ISO-8859-1")
Alternatively, use solution provided by Alex :
return new String(st);
But, convert bytes to chars properly :
st[i] = (char) (crypted[i] & 0xff);
Otherwise, all negative bytes, crypted[i] < 0 will not be converted to char properly and you get surprising results.

Change this line:
return st.toString();
with this
return new String(st);

Related

Convert a byte array from one encoding to another java

hi guys i should convert this code to C# in Java. Could you give me a hand?
private static String ConvertStringToHexStringByteArray(String input) {
Encoding ebcdic = Encoding.GetEncoding("IBM037");
Encoding utf8 = Encoding.UTF8;
byte[] utfBytes = utf8.GetBytes(input);
byte[] isoBytes = Encoding.Convert(utf8, ebcdic, utfBytes);
StringBuilder hex = new StringBuilder(isoBytes.length * 2);
foreach( byte b in isoBytes)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
I tried to convert it to java like this. But the result is different:
private static String ConvertStringToHexStringByteArray(String input) throws UnsupportedEncodingException {
byte[] isoBytes = input.getBytes("IBM037");
StringBuilder hex = new StringBuilder(isoBytes.length * 2);
for (byte b : isoBytes) {
hex.append(String.format("%02x", b));
}
return hex.toString();
}
input = "X1GRUPPO 00000000726272772"
expected = "e7f1c7d9e4d7d7d64040404040f0f0f0f0f0f0f0f0f1f6f7f3f5f3f5f5f2"
result = "e7f1c7d9e4d7d7d640f0f0f0f0f0f0f0f0f7f2f6f2f7f2f7f7f2"
what am I doing wrong?
Your code works but you are comparing the output for two different input strings.
When you write expected and result side by side:
e7f1c7d9e4d7d7d64040404040f0f0f0f0f0f0f0f0f1f6f7f3f5f3f5f5f2
e7f1c7d9e4d7d7d640f0f0f0f0f0f0f0f0f7f2f6f2f7f2f7f7f2
you will notice that both start with the same sequence (e7f1c7d9e4d7d7d6) which seems to come from a common beginning X1GRUPPO
But then the two outputs differ:
4040404040f0f0f0f0f0f0f0f0f1f6f7f3f5f3f5f5f2
40f0f0f0f0f0f0f0f0f7f2f6f2f7f2f7f7f2
Reasoning from the input that you provided, the remainder of first input string starts with 5 spaces followed by "00000000167353552"
This means the complete input for the C# code was "X1GRUPPO 00000000167353552", which is not the same input that you provided to the Java code and then clearly the output cannot match.

Convert string to byte[] do an operation and back to byte[]

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"));

Issue with java String and String Builder

I'm working on a project in which I have to decrypt a xml text from PHP server and parse into java, I have decrypted the xml text by using CipherInputStream and seen xml file fully get printed, but I'm facing a weird issue while trying to store the xml text in a java string, I'm working on the code below:
public String decrypt(InputStream Fis){
Cipher c = Cipher.getInstance(algo + "/CBC/NoPadding");
String add = "";
StringBuilder getAns = new StringBuilder();
c.init(Cipher.DECRYPT_MODE, key);
CipherInputStream cis = new CipherInputStream(Fis , c);
byte[] encData = new byte[16];
int dummy;
while ((dummy = cis.read(encData)) != -1)
{
System.out.println(new String(encData, "UTF-8").trim());
add = (new String(encData, "UTF-8").trim());
getAns.append(add);
}
System.out.println(getAns);
...
}
It prints the full XML text in log cat by the first println statement inside while loop, But when printing the StringBuilder getAns, it only prints a part of the text.
I have also tried just using String:
add = add + (new String(encData, "UTF-8").trim());
also using ArrayList<String> but it only prints a part of the text.
I guess this may be due to a silly mistake , but I'm struggling with this. Any help will be appreciated.
You are reading some bytes from the input stream inside the while condition:
while ((dummy = cis.read(encData)) != -1)
This already populates the encData byte array with having the correct number of read bytes in the dummy variable. Afterwards you again read some bytes:
dummy = cis.read(encData);
This overwrites the bytes you have read one step before. Delete that line!
Finally caught the issue, It's with the System.out.pritnln(), It has certain limits for printing. This function can only print around 4060 characters at a time, I've found this by using getAns.substring(10000,15000);.

Get Multilingual Data from ByteBuffer

I am receiving ByteBuffers in an UDP Java application.
Now the data in this ByteBuffer can be any string in any language or any special chars separated by zero.
I use following code to get Strings from it.
public String getString() {
byte[] remainingBytes = new byte[this.byteBuffer.remaining()];
this.byteBuffer.slice().get(remainingBytes);
String dataString = new String(remainingBytes);
int stringEnd = dataString.indexOf(0);
if(stringEnd == -1) {
return null;
} else {
dataString = dataString.substring(0, stringEnd);
this.byteBuffer.position(this.byteBuffer.position() + dataString.getBytes().length + 1);
return dataString;
}
}
These strings are stored in MySQL DB with everything set as UTF8.
IF i run application in Windows then special chars like ® are displayed but chinese are not.
On adding VM argument -Dfile.encoding=UTF8 chinese are displayed but chars like ® are shown as ?? etc.
Please Help.
Edit:
Input Strings in UDP packet are variable-length byte field, encoded in UTF-8, terminated by 0x00
For JDBC also i use useUnicode=true&characterEncoding=UTF-8
String dataString = new String(remainingBytes); is wrong. You should almost never do that. You should find out what encoding was used to put the bytes into the UDP packet, and use the same encoding on that line:
String dataString = new String(remainingBytes, encoding); // e.g. "UTF-8"
Edit: based on your updated question, encoding should be "UTF-8"
Not sure, but dataString contains only data till this zero, because stringEnd shows on first zero postion but not behind.
dataString = dataString.substring(0, stringEnd+1);
or
char specChar = dataString.substring(stringEnd, stringEnd+1); and it should return only special character, but as I said in the biggining, not sure...

Convert a String to a byte array and then back to the original String

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));
}
}

Categories

Resources