I want to convert a string value to the same byte array in C# and Java with following codes:
C#:
string key="EA1302AFBCCF791CB0065BFAD948B092";
byte[] keyByte = Encoding.UTF8.GetBytes(plainKey);
Java:
String key="EA1302AFBCCF791CB0065BFAD948B092";
byte[] keyByte = (key).getBytes("UTF-8");
But the length of the generated array is 32 in C# and 343 in Java. I have to create a byte array in C# same as Java, so please don't suggest changes for my Java code.
I tried:
public static void main(String args[]) throws UnsupportedEncodingException {
String key="EA1302AFBCCF791CB0065BFAD948B092";
byte[] keyByte = key.getBytes("UTF-8");
System.out.println("Length: " + keyByte.length);
}
output is:
Length: 32
Related
I have generated Base64 encoded value using below Scala code:
println(Base64.getEncoder.encodeToString("E5E9FA1BA31ECD1AE84F75CAAA474F3A".getBytes(StandardCharsets.UTF_8)))
YxRfXk827kPgkmMUX15PNg==
Now I am trying to convert "YxRfXk827kPgkmMUX15PNg==" to Hex. I tried with below Java code but no luck:
public static void main(String[] args) throws DecoderException {
String guid = "RTVFOUZBMUJBMzFFQ0QxQUU4NEY3NUNBQUE0NzRGM0E=";
byte[] hexString = Hex.decodeHex(guid);
System.out.println(hexString);
Exception in thread "main" org.apache.commons.codec.DecoderException: Illegal hexadecimal character R at index 0
When I explored I found below working Java code:
String guid = "YxRfXk827kPgkmMUX15PNg==";
byte[] decoded = Base64.decodeBase64(guid);
String hexString = Hex.encodeHexString(decoded);
System.out.println(hexString);
4535453946413142413331454344314145383446373543414141343734463341
But here Base64 values is getting decoded and then converted to Hex. I am trying to figure out if there is a way we can directly convert Base64 to Hex? Please excuse as it looks like a duplicate question and thanks in advance.
Since it is a String, it already has a way to get the ByteArray.
Don't decode the Base64, simply request the bytes from the String:
public static void main(String[] args) {
String guid = "YxRfXk827kPgkmMUX15PNg==";
String hexString = Hex.encodeHexString(guid.getBytes());
System.out.println(hexString);
}
This basically means you only have to convert your string to a Byte[].
You can see that the business logic code is very simple and that the original text and the hex encoded are the same by trying to decode them in a test:
// actual business logic
public String hexEncoder(String content) {
return Hex.encodeHexString(content.getBytes());
}
// input and assertion
#Test
public void hexEncoder() throws DecoderException {
String guid = "YxRfXk827kPgkmMUX15PNg==";
String hexString = hexEncoder(guid);
String hexDecoded = new String(Hex.decodeHex(hexString));
// no need to decode Base64 but might be useful for `printLn` or debugging
String s = new String(Base64.decodeBase64(guid));
String s1 = new String(Base64.decodeBase64(hexDecoded));
assertEquals(s, s1);
}
I've written this simple Java snippet to SHA-256 a string:
public static void main(String[] args) throws NoSuchAlgorithmException {
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
String input = "00010966776006953D5567439E5E39F86A0D273BEE";
byte[] output = sha256.digest(input.getBytes());
System.out.println(new String(output));
}
Running SHA-256 using this tool gives the output 3CC2243D50E87857A233965AA6B68B37563BFCC52B3C499FBB259B9AA87FFF40, but when I run it myself I get <�$=P�xW�3�Z���7V;��+<I��%����#. It looks like something is going wrong with the byte conversion, but I'm not exactly sure what.
You are correct that something was wrong when you tried to convert byte[] to string. Here is a code that works :)
public static void main(String[] args) throws NoSuchAlgorithmException {
final String input = "Nishit";
final MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(input.getBytes());
final byte[] data = md.digest();
StringBuilder sb = new StringBuilder(data.length * 2);
for (byte b : data) {
sb.append(String.format("%02x", b));
}
System.out.println(sb.toString());
}
What it is really happenning is that the SHA256 returns a 256-bit hash value. So what you're printing is those bytes as if they were characters and their respective character values is all that gibberish.
What the online tool is returning you is the representation of that value in hexadecimal format.
Notice that you're getting, (with the tool) 64 bytes IE 64 characters when 256-bit is equal to 32 bytes (32 charaters you may think).
That is because to represent a whole byte in hexadecimal format 2 characters are needed. 4 most significative bits take one character and the other less significative bits take another one.
I want using CRC16, but first, i want to convert string to hex. because integer must be 16 bytes. i still confused to encrypt using CRC16. this is my code.
public static void main(String[] args) {
String input = "skn";
byte[] valuesDefault = input.getBytes();
System.out.println("input:" + input);
System.out.println(Arrays.toString(valuesDefault));
}
Try this below
DatatypeConverter.printHexBinary(input.getBytes())
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.
This is the PHP code I have.
function decrypt($s_input, $s_key, $s_iv) {
$s_decrypted = pack("H*" , $s_input); // Hex to binary
$s_decrypted = mcrypt_decrypt (MCRYPT_3DES, $s_key, $s_decrypted, MCRYPT_MODE_CBC, $s_iv); // 3des decryption
return $s_decrypted;
}
echo encrypt('c37551bb77f741d0bcdc16497b4f97b1','123456781234567812345678','12345678' );
what it basically does is to decrypt a 3des encrypted string (first it convert the hex string to binary using pack function and then does the actual decryption).
This perfectly works in PHP-4 and prints the "Hello World" message.
However, if I run the equivalent java code (jdk 1.6), it prints garbage output as - ¬ªmjV=7xl_ÓÄ^›*?.
Can someone help to troubleshoot this? Why Java is not properly decrypting the hex string.
private static String decrypt(String inputStr, String keyStr, String ivStr) throws Exception {
IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
SecretKeySpec key = new SecretKeySpec(keyStr.getBytes(), "DESede");
inputStr = hexToString(inputStr, 2);
Cipher cipher = Cipher.getInstance("DESede/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decrypted = cipher.doFinal(inputStr.getBytes());
return new String(decrypted);
}
private static String hexToString(String input, int groupLength) {
StringBuilder sb = new StringBuilder(input.length() / groupLength);
for (int i = 0; i < input.length() - groupLength + 1; i += groupLength) {
String hex = input.substring(i, i + groupLength);
sb.append((char) Integer.parseInt(hex, 16));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String decryptSignature = decrypt("c37551bb77f741d0bcdc16497b4f97b1", "123456781234567812345678", "12345678");
System.out.println(decryptSignature);
}
There are a few things you should check. You might find Encryption using AES-128 in Java to be of some assistance. There could be issues with differences between how you are handling keys in the PHP and Java code. Calling getBytes() on a String in Java without an encoding is almost always a bad idea. Plus the padding used could be a problem. From what I've seen PHP pads with null characters by default, which does not correspond to NoPadding in Java. Finally, the hexToString method should return a byte[] instead of a String. Add the result of calling Integer.parseInt(hex, 16) into an array:
byte[] results = new byte[input.length() / groupLength];
...
//inside the loop
results[i / groupLength] = (byte) Integer.parseInt(hex, 16);
...
return results;