Android 3Des encrypt Binary Output - java

decrypt with 3des. I can get Base64 output correctly but i want to get output binary. How can i do?
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedText = cipher.doFinal(unencryptedString);
byte[] sdd = Base64.encode(encryptedText, Base64.DEFAULT);

A simple method that turns a byte array in to a String containing the binary value.
String bytesToBinaryString(byte[] bytes){
StringBuilder binaryString = new StringBuilder();
/* Iterate each byte in the byte array */
for(byte b : bytes){
/* Initialize mask to 1000000 */
int mask = 0x80;
/* Iterate over current byte, bit by bit.*/
for(int i = 0; i < 8; i++){
/* Apply mask to current byte with AND,
* if result is 0 then current bit is 0. Otherwise 1.*/
binaryString.append((mask & b) == 0 ? "0" : "1");
/* bit-wise right shift the mask 1 position. */
mask >>>= 1;
}
}
/* Return the resulting 'binary' String.*/
return binaryString.toString();
}

Related

Byte by byte need to xor but its showing as integer and getting lost of precision error?

I have socket application and I can read byte by byte and I can push all the byte into one single array. I read like below.So I will have 12+bodylen bytes.
int messageID = r.readUnsignedShort();
int bodyLen = r.readUnsignedShort();
byte[] phoneNum = new byte[6];
r.readFully(phoneNum);
int serialNum = r.readUnsignedShort();
byte[] messageBody = new byte[bodyLen];
r.readFully(messageBody);
byte checkCode = r.readByte();
Next I do this where I create a bytebuffer and later I tried to run the for loop to print first to check where its byte format or not I receive it in integer values cause one of the value is -110? and also I receive error on this line xor = (byte)xor ^ (byte)fullMessage[sf]; possible loss of precision?
ByteBuffer buf = ByteBuffer.allocate(12+bodyLen);
buf.putShort((short)messageID);
buf.put((byte)bodyLen);
buf.put(phoneNum);
buf.putShort((short)serialNum);
buf.put(messageBody);
byte[] fullMessage=buf.array();
int xor = 0;
for(int sf=0,s=fullMessage.length;sf<s;sf++){
xor ^= fullMessage[sf];
fullMessage[sf] = (byte)xor;
// System.out.println("\n\nprint value for : "+sf+" "+"value is:"+xor);
// do your XOR operations -> xor operator is ^
}
System.out.println("\n\nfinal xor is :"+xor+" "+Integer.toHexString(xor));
First since you are doing:
int serialNum = r.readUnsignedShort();
Replace
buf.put((byte)serialNum);
by
buf.putShort((short)serialNum);
The sign skews the value, but that can be repaired by: & 0xFFFF.
Bytes are xorred as:
byte x = (byte) 0xA0; // Negative signed byte value
byte y = ...
byte z = (byte)(x ^ y); // Xor is done on int
So the xorring will be:
int xor = 0;
for (int sf = 0, s = fullMessage.length; sf < s; sf++) {
xor ^= fullMessage[sf];
fullMessage[sf] = (byte)xor;
}
Using that 0 is the neutral element of ^.
xor = (byte) ((byte)xor ^ (byte)fullMessage[sf]);

How to convert minus hex value to String and byte array

I want to convert decimal -10 value to hex in a String and byte array format.
I have tried
String minHex = Integer.toHexString(Integer.valueOf(-10));
System.out.println(minHex);
Which results in fffffff6, and I think it is not correct. And for converting byte array I am using below function which I found from
Convert a string representation of a hex dump to a byte array using Java?
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
So also not sure it will work for minus hex value or not.
To convert an hex to a String the way you expect it i.e. -10 is converted to -a, use:
String hex = Integer.toString(-10, 16);
To convert to a byte array, simply convert the int to a byte array, it is represented the same way:
byte[] bytes = ByteBuffer.allocate(4).putInt(-10).array();

How do I convert a large string into hex and then into byte?

I work with cellphones and deal with MEID numbers on a daily basis. So instead of searching online for a MEID (a hex number of length 14) to pseudo ESN (a hex number of length 8) calculator, I figured I can make my own program. The way to obtain a pESN from MEID is fairly simple in theory. For example, given MEID 0xA0000000002329, to make a pESN, SHA-1 needs to be applied to the MEID. SHA-1 on A0000000002329 gives e3be267a2cd5c861f3c7ea4224df829a3551f1ab. Take the last 6 hex numbers of this result, and append it to 0x80 - the result is 0x8051F1AB.
Now here is the code I have so far:
public void sha1() throws NoSuchAlgorithmException {
String hexMEID = "A0000000002329";
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(hexMEID.getBytes());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
System.out.println(sb.toString());
}
The problem is that using this method, SHA-1 on A0000000002329 gives a89b611b421f57705bd013297ce3fc835f706ab0 instead of e3be267a2cd5c861f3c7ea4224df829a3551f1ab. What am I doing wrong here??
Someone gave me a hint that "the trick is to apply SHA-1 to the number representing the MEID, not the string representing the MEID. You'll need to process it byte-by-byte, so you must give it two hex numbers at a time (since two hex numbers make a byte) and make sure they are interpreted as numbers and not ASCII characters". If this is true then how do I change my string into hex and then into byte so that SHA1 can give me the correct result???
Without libraries, you can follow the example here:
In Java, how do you convert a hex string to a byte[]?
byte[] b = new BigInteger(s,16).toByteArray();
One library (I'm sure there are many) that also provides this is POJava:
<dependency>
<groupId>org.pojava</groupId>
<artifactId>pojava</artifactId>
<version>2.8.1</version>
</dependency>
byte[] hexMEIDBytes=EncodingTool.hexDecode(hexMEID);
[EDIT] ==============
Here's a more complete example per your followup question:
byte[] hexMEIDBytes = EncodingTool.hexDecode(hexMEID);
byte[] hash = HashingTool.hash(hexMEIDBytes, HashingAlgorithm.SHA);
String pESN="0x80" + EncodingTool.hexEncode(hash).substring(34).toUpperCase();
// a hexMEID value of "A0000000002329" results in a pESN value of "0x8051F1AB"
For String to Hex:
public String StrToHex(String arg) {
return String.format("%040x", new BigInteger(arg.getBytes(//Your Charset//)));
}
For Hex to byte:
This below code wont work for "0".
public byte[] hexStrToByteArray(String s) {
int leng = s.length();
byte[] data = new byte[leng / 2];
for (int i = 0; i < leng; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
You can use the following two methods
public static synchronized String bytesToHex(byte [] buf){
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10){
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
public synchronized static byte[] hexToBytes(String hexString) {
byte[] b = new BigInteger(hexString,16).toByteArray();
return b;
}

Java BigInteger vs Mono .net BigInteger

I use in .Net project mono implementation of BigInteger (link) In Java I use java.math.BigInteger.
The same code produces different results in Java.
.Net code
String inputBytes = "8E5BD77F0DCC30864634C134E28BFB42A149675A320786B616F4530708350D270353C30A40450325801B7AFED12BCCA274B8187072A89CC0CC3F95A24A8251243C1835898246F4D64CA3AC61DB841518F0E8FBC8996A40EB626153AE7F0BB87FD713FAC522719431428DE178E780A3FA45788A72C431926AED990E6DA268D2CC";
String modulus = "00e6b4b4511e0bd1b3d9c82ee189ba6d0c70b1466d94126f99a741af99a92701a789451742a357ddb61a4dea409965ec58dcaa5e30826de871b04700ed0fd46b1693446049734e8f95faba2bf9301347e63ba1771650e71982adef0cca6890b6f7baa7f5421a6533652f4b70c3c4270c480cf54cc06635f22901a42716d1dadf4f";
String exp = "010001";
BigInteger mModulus = new BigInteger(hexStringToByteArray(modulus));
BigInteger mExponent = new BigInteger(hexStringToByteArray(exp));
BigInteger input = new BigInteger(hexStringToByteArray(inputBytes));
BigInteger output = input.ModPow(mExponent, mModulus);
Console.WriteLine("==RESULT==" + byteArray2Hex(output.GetBytes()));
public static byte[] hexStringToByteArray(string hexString)
{
if (hexString.Length % 2 != 0)
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hexString));
byte[] HexAsBytes = new byte[hexString.Length / 2];
for (int index = 0; index < HexAsBytes.Length; index++)
{
string byteValue = hexString.Substring(index * 2, 2);
HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return HexAsBytes;
}
==RESULT==01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003020300C06082A864886F70D02050500041009EB0D996BFC1EFA5675997712A1AB6E
Java code.
The same inputBytes array, the same exponent and modulus, but different result.
String inputBytes = "8E5BD77F0DCC30864634C134E28BFB42A149675A320786B616F4530708350D270353C30A40450325801B7AFED12BCCA274B8187072A89CC0CC3F95A24A8251243C1835898246F4D64CA3AC61DB841518F0E8FBC8996A40EB626153AE7F0BB87FD713FAC522719431428DE178E780A3FA45788A72C431926AED990E6DA268D2CC";
String modulus = "00e6b4b4511e0bd1b3d9c82ee189ba6d0c70b1466d94126f99a741af99a92701a789451742a357ddb61a4dea409965ec58dcaa5e30826de871b04700ed0fd46b1693446049734e8f95faba2bf9301347e63ba1771650e71982adef0cca6890b6f7baa7f5421a6533652f4b70c3c4270c480cf54cc06635f22901a42716d1dadf4f";
String exp = "010001";
BigInteger mModulus = new BigInteger(hexStringToByteArray(modulus));
BigInteger mExponent = new BigInteger(hexStringToByteArray(exp));
BigInteger input = new BigInteger(hexStringToByteArray(inputBytes));
BigInteger output = input.modPow(mExponent, mModulus);
System.out.println("==RESULT==" + Utils.byteArray2Hex(output.getBytes()));
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
==RESULT==6ce02bd9536ad76bcfd7633b6a2305ed98b43b0bb5fc2acbf984566f1ab35db02e651e9ed8793bf64b018455872b8ae3a06af082e8d680df407ea1e5df1336a19c6f3e116c6ff1940066396afa1de5633fad814fb42790b3af0e62e6dd53977f78794b2d105cdca9272f9c0feea119fe2c9691b6f6e21db3065fb25d840acea2
I do not understand why the results are different.
P.S.
e.g. if I use InputBytes
String inputBytes = "242e35241b85fcfd75a53441ef9fc0941064c16f8e4555dabef5ce8ebc91400c6961b6b607e5dd762dbcabce51b11c8594e7d7183786c8e3c5300c7583c1871fc6f350b817682150b5cd0430ca9a2c3f8315b425c8fea0e7cc18187237ed47d29b082e7e7154888d5fb09f092a6dd5e2d3dac9df8de45837b708b5ae17f03e7f";
the the results in Java and .Net are the same
==RESULT==01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003020300c06082a864886f70d02050500041046fd8e86a4833e7141cbe4718e8e92f7
Where is the magic?
From the docs for java.math.BigInteger(byte[]):
Translates a byte array containing the two's-complement binary representation of a BigInteger into a BigInteger. The input array is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element.
From the docs for System.Numerics.BigInteger(byte[]):
The individual bytes in the value array should be in little-endian order, from lowest-order byte to highest-order byte.
So you might want to just try reversing the input bytes for one of the values you've got - it's not clear which set you should reverse, as we don't know what values you're trying to represent. I would suggest adding diagnostics of just printing out the normal decimal representation immediately after construction in each case - if those aren't the same, the rest of the code is irrelevant.
I solved my problem by adding 0 bit at the begining of inputBytes.

byte array to short array and back again in java

I'm having some issues taking audio data stored in a byte array, converting it to a big-endian short array, encoding it, then changing it back into a byte array. Here is what I have. The original audio data is stored in audioBytes2. I am using the same format for decode with a minus on the cos function instead. Unfortunately, changing the byte and short data types is non-negotiable.
short[] audioData = null;
int nlengthInSamples = audioBytes2.length / 2;
audioData = new short[nlengthInSamples];
for (int i = 0; i < nlengthInSamples; i++) {
short MSB = (short) audioBytes2[2*i+1];
short LSB = (short) audioBytes2[2*i];
audioData[i] = (short) (MSB << 8 | (255 & LSB));
}
int i = 0;
while (i < audioData.length) {
audioData[i] = (short)(audioData[i] + (short)5*Math.cos(2*Math.PI*i/(((Number)EncodeBox.getValue()).intValue())));
i++;
}
short x = 0;
i = 0;
while (i < audioData.length) {
x = audioData[i];
audioBytes2[2*i+1] = (byte)(x >>> 0);
audioBytes2[2*i] = (byte)(x >>> 8);
i++;
}
I have done everything that I can think of to make this work, but the closest I've come is getting it to work every other encode/decode and I have no idea why. Thanks for any help.
I also suggest you try ByteBuffer.
byte[] bytes = {};
short[] shorts = new short[bytes.length/2];
// to turn bytes to shorts as either big endian or little endian.
ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
// to turn shorts back to bytes.
byte[] bytes2 = new byte[shortsA.length * 2];
ByteBuffer.wrap(bytes2).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().put(shortsA);
public short bytesToShort(byte[] bytes) {
return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}
public byte[] shortToBytes(short value) {
return ByteBuffer.allocate(2).order(ByteOrder.LITTLE_ENDIAN).putShort(value).array();
}
How about some ByteBuffers?
byte[] payload = new byte[]{0x7F,0x1B,0x10,0x11};
ByteBuffer bb = ByteBuffer.wrap(payload).order(ByteOrder.BIG_ENDIAN);
ShortBuffer sb = bb.asShortBuffer();
while(sb.hasRemaining()){
System.out.println(sb.get());
}
byte[2] bytes;
int r = bytes[1] & 0xFF;
r = (r << 8) | (bytes[0] & 0xFF);
short s = (short)r;
Your code is doing little-endian shorts, not big. You've the indexing for MSB and LSB swapped.
Since you are using big-endian shorts, you could be using a DataInputStream wrapped around a ByteArrayInputStream (and DataOutputStream/ByteArrayOutputStream) on the other end, rather than doing your own decoding.
If you're getting every other decode working, I'd guess you've got an odd number of bytes, or an off-by-one error elsewhere which is causing your mistake to get fixed on every other pass.
Finally, I'd step through the array with i+=2 and use MSB= arr[i] and LSB=arr[i+1] rather than multiplying by 2, but that's just me.
It looks like you are swapping the byte order between reading the bytes in and writing them back out (unsure if this is intentional or not).

Categories

Resources