Decoding 'code string' to UTF8 and string - c#

First, sorry about my knowledge ...
Above all I have string type value %B3%F3%C7%F9.
Since I receive it from other processor, I don't know how it made... (just I receive this string)
What I only know are
this is something encoded Korean language (I guess it is 농협)
the encode method is one of utf-8 or euc-kr
What I wnat to do is to decode this strange and coded string to utf-8 string.
(for example, decode %B3%F3%C7%F9 to 농협 and assign it string type variable)
Thanks for your attention
(I'm working in ASP.NET Core 1.1)

Your % values are basically URL encoding, so %F9 represents a byte value of 249, for example.
So the first thing you need to do is convert this into a byte array. I've done this a potentially inefficient way in my example. Once you've done that, you need to convert that byte array into a string using the EUC-KR encoding type.
public static void Main()
{
string data = "%B3%F3%C7%F9";
byte[] bData = new byte[data.Length / 3];
for (int i = 0; i < data.Length; i += 3)
{
int pos = i / 3;
bData[pos] = Convert.ToByte(data.Substring(i + 1, 2), 16);
}
data = System.Text.Encoding.GetEncoding("euc-kr").GetString(bData);
Console.WriteLine(data);
}
Fiddle

Related

Having trouble with AWS4 Signature tutorial, hash doesn't match example

I'm working through the tutorial on AWS, trying to calculate the Authorization header and I'm stuck. (Tutorial here: https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html)
I've narrowed down my problem to a step at the end of task 3. I can create the signing key as they described and get the same result as they do,
c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9
I can calculate the stringToSign as they describe and I get a matching result,
AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/iam/aws4_request\nf536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59
But when I try to sign the string my result doesn't match their result.
var kha = KeyedHashAlgorithm.Create("HMACSHA256");
kha.Key = Encoding.UTF8.GetBytes("c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9");
var sts = "AWS4-HMAC-SHA256\n20150830T123600Z\n20150830/us-east-1/iam/aws4_request\nf536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59";
var signature = HexEncode(kha.ComputeHash(Encoding.UTF8.GetBytes(sts)));
When I run this my signature comes out as
fe52b221b5173b501c9863cec59554224072ca34c1c827ec5fb8a257f97637b1
but they say it should be
5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7
In task 2 I run my HexEncode function as part of creating the HashedCanonicalRequest and that is coming out fine so I don't think it is that function but here it is just in case:
private static string HexEncode(byte[] data, bool lowercase = true)
{
var sb = new StringBuilder();
for (var i = 0; i < data.Length; i++)
{
sb.Append(data[i].ToString(lowercase ? "x2" : "X2"));
}
return sb.ToString();
}
I've tried various ways of writing the sts like using
#"AWS4-HMAC-SHA256
20150830T123600Z
20150830/us-east-1/iam/aws4_request
f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59"
instead of using \n but nothing has worked. I also read through a few of the other postings here on SO but none of those seemed to help either.
Update:
I created this fiddle just to prove to myself that it isn't something environmental but it gets the same answer as my local code.
https://dotnetfiddle.net/A5mVp9
So it turns out that using
kha.Key = Encoding.UTF8.GetBytes("c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9");
is incorrect. That string is hex encoded (because that's what it says to do in the tutorial) but you are supposed to use the byte-array version and not hex encode it. They showed the hex encoded just for display purposes but didn't do a good job of saying to use the regular byte array and DO NOT HEX ENCODE IT! Anyways, that's what solves this.
If you want to see it in action, write a hex decoder:
public static byte[] DecodeHex(string hex)
{
byte[] raw = new byte[hex.Length / 2];
for (int i = 0; i < raw.Length; i++)
{
raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
}
return raw;
}
and hex decode the string I listed and use that byte array in the hashing.
kha.Key = DecodeHex("c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9");

Error "Hex string have a odd number of digits" while converting int->hex->binary in C#

Aim :
To convert a integer value first to hexstring and then to byte[].
Example :
Need to convert int:1024 to hexstring:400 to byte[]: 00000100 00000000
Method:
For converting from integer to hex string i tried below code
int i=1024;
string hexString = i.ToString("X");
i got hexstring value as "400". Then i tried converting hex string to byte[] using below code
byte[] value = HexStringToByteArray(hexValue);
/* function for converting hexstring to byte array */
public byte[] HexStringToByteArray(string hex)
{
int NumberChars = hex.Length;
if(NumberChars %2==1)
throw new Exception("Hex string cannot have an odd number of digits.");
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
Error:
Here i got the exception "Hex String cannot have a odd number of digits"
Solution: ??
You can force the ToString to return a specific number of digits:
string hexString = i.ToString("X08");
The exception is thrown by your own code. You can make your code more flexible to accept hex strings that have an odd number of digits:
if (hex.Length % 2 == 1) hex = "0"+hex;
Now you can remove the odd/even check, and your code will be alright.
Your code throws the exception you're seeing:
throw new Exception("Hex string cannot have an odd number of digits.");
You can improve the conversion method to also accept odd hex string lengths like this:
using System.Collections.Generic;
using System.Linq;
// ...
public byte[] HexStringToByteArray(string hex)
{
var result = new List<byte>();
for (int i = hex.Length - 1; i >= 0; i -= 2)
{
if (i > 0)
{
result.Insert(0, Convert.ToByte(hex.Substring(i - 1, 2), 16));
}
else
{
result.Insert(0, Convert.ToByte(hex.Substring(i, 1), 16));
}
}
return bytes.ToArray();
}
This code should iterate through the hex string from its end, adding new bytes to the beginning of the resulting list (that will be transformed into an array before returning the value). If a single digit remains, it will be treated separately.
Your hex string has an odd number of digits and you are explicitly checking for that and throwing the exception. You need to decide why you put this line of code in there and whether you need to remove that in favour of other logic.
Other options are:
add a "0" to the beginning of the string to make it even length
force whoever is calling that code to always provide an even length string
change the later code to deal with odd numbers of characters properly...
In comments you have suggested that the first is what you need to know in which case:
if(hex.Length%2==1)
hex = "0"+hex;
Put this at the beginning of your method and if you get an odd number in then you will add the zero to it automatically. You can of course then take out your later check and exception throw.
Of note is that you may want to validate the input string as hex or possibly just put a try catch round the conversion to make sure that it is a valid hex string.
Also since it isn't clear whether the string is a necessary intermediate step or just one that you think is necessary, you might be interested in C# int to byte[] which deals with converting to bytes without the intermediate string.

Search ReadAllBytes for specific values

I am writing a program that reads '.exe' files and stores their hex values in an array of bytes for comparison with an array containing a series of values. (like a very simple virus scanner)
byte[] buffer = File.ReadAllBytes(currentDirectoryContents[j]);
I have then used BitConverter to create a single string of these values
string hex = BitConverter.ToString(buffer);
The next step is to search this string for a series of values(definitions) and return positive for a match. This is where I am running into problems. My definitions are hex values but created and saved in notepad as defintions.xyz
string[] definitions = File.ReadAllLines(#"C:\definitions.xyz");
I had been trying to read them into a string array and compare the definition elements of the array with string hex
bool[] test = new bool[currentDirectoryContents.Length];
test[j] = hex.Contains(definitions[i]);
This IS a section from a piece of homework, which is why I am not posting my entire code for the program. I had not used C# before last Friday so am most likely making silly mistakes at this point.
Any advice much appreciated :)
It is pretty unclear exactly what kind of format you use of the definitions. Base64 is a good encoding for a byte[], you can rapidly convert back and forth with Convert.ToBase64String and Convert.FromBase64String(). But your question suggests the bytes are encoded in hex. Let's assume it looks like "01020304" for a new byte[] { 1, 2, 3, 4}. Then this helper function converts such a string back to a byte[]:
static byte[] Hex2Bytes(string hex) {
if (hex.Length % 2 != 0) throw new ArgumentException();
var retval = new byte[hex.Length / 2];
for (int ix = 0; ix < hex.Length; ix += 2) {
retval[ix / 2] = byte.Parse(hex.Substring(ix, 2), System.Globalization.NumberStyles.HexNumber);
}
return retval;
}
You can now do a fast pattern search with an algorithm like Boyer-Moore.
I expect you understand that this is a very inefficient way to do it. But except for that, you should just do something like this:
bool[] test = new bool[currentDirectoryContents.Length];
for(int i=0;i<test.Length;i++){
byte[] buffer = File.ReadAllBytes(currentDirectoryContents[j]);
string hex = BitConverter.ToString(buffer);
test[i] = ContainsAny(hex, definitions);
}
bool ContainsAny(string s, string[] values){
foreach(string value in values){
if(s.Contains(value){
return true;
}
}
return false;
}
If you can use LINQ, you can do it like this:
var test = currentDirectoryContents.Select(
file=>definitions.Any(
definition =>
BitConverter.ToString(
File.ReadAllBytes(file)
).Contains(definition)
)
).ToArray();
Also, make sure that your definitions-file is formatted in a way that matches the output of BitConverter.ToString(): upper-case with dashes separating each encoded byte:
12-AB-F0-34
54-AC-FF-01-02

Convert Hex string to Image

I am using FormsConnect an App for the iPad to export signatures to XML.
The output from the App is as follows:
0x1828023f020000001d1100000018000000e02f01000000000000000000000000a888223f010000005259414ca0a37e00000000000000000000000000000000000000000000000000000000000000000010b9611100000000000000000000000000000000308e660e00000000c021070030a46c0e00000000000000000000000044b0fb3e00beb0000100000001000000107b6111000030420000584200000000000000000000000000000000000080bf00000000000000000100000000000000000000000000000000000000000000001cb0fb3e0100000000000000000000000000000000000000000000000047864aa0860100a086010000c05411000070110047864a0000000000000000010000000000000000000000000000000000000018884d3f801200010900000101000000000000000000020074a54e3fb0b6690ec0b6690e00000000000000000000000044b0fb3e0038a9000100000001000000f0e4c008000030420000304200000000000000000000000000000000000080bf00000000000000000100000000000000000000000000000000000000000000001cb0fb3e0100000000000000000000000000000000000000000000000047864aa0860100a08601000020761100407c110047864a0000000000000000010000000000000000000000000000000000000018884d3f801200010900000101000000000000000000020074a54e3f20b6690e30b6690e000000000000000000000000a888223f010000005259414c808b730c00000000000000000000000000000000000000000000000000000000000000000cc0fb3e0000000000000000000000000400000000000000000000000000000000000000000000000000000000000000a888223f010000005259414ce06ebe0a00000000000000000000000000000000000000000000000000000000000000009ceefb3ea08c61110000000000000000000000000000000000000000000000000000000000000000280001c10400000000000000b017640000000000000000000000000000000000000000000000000000000000000020415846fc3ed08c6111000000000000000000000000000000000000000000000000000000000000003f000000004014630000887a0670c89b0c40146300000000000000000000000000000000000000000000000000100000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e44200000000000000000000000000000000408d6111f08e61110000584200003042000000000000000000000000a888223f010000005259414c4040050d00000000000000000000000000000000000000000000000000000000000000002cd7fb3e108d61110000000000000000a08e6111d033120000000000000000000000000000000000200000c10000000000000000000000000000000000000000a888223f010000005259414c304d050d0000000000000000000000000000000000000000000000000000000000000000ccc8fb3eb08d611100000000d08c611100000000908b6111000000000000000000000000000000000000000000000000000000000150000000000000f08d611101000000000000000000e03f0000204100000000000000000000000000000000108e611104000000000000000000000084854d3f01000000110000000300000002000000e08d61110000000000000000f0c7fb3e908b61112952d53200000000d08d6111000000000000000000000000c08a4d3f8011000101000000000000000000000000000100c8c94e3f0000000094c9fb3e0100000000000000608e611100000000000000000000000000000000000000000000000000003442000000000000e83f000000606666d63f808e6111408d6111000000000000000000000000c08a4d3f8011000101000000000000000000000000000100c8c94e3f0000000084854d3f0000000001000000030000000100000000000000000000000000000084854d3f01000000110000000300000002000000c08e61110000000000000000408d6111000000000000000000000000d088223fe003fe07020000000800000002000000000000000000000000000000b4effb3e308f6111000000000000000000000000b0906111000000000000000000000000f0496300200000c100000000608f6111000080bf0200000000000000a888223f010000005259414cf04a050d000000000000000000000000000000000000000000000000000000000000000054a0fb3ed08f6111000000000000000000000000d0331200000000000000000000000000f0496300330000c100000000000000000000000020887a06201c630000000000e0a762001032d805000000000000803f0000000000000000010000000000c841000000000416000000000000a888223f010000005259414c9047050d0000000000000000000000000000000000000000000000000000000000000000d088223fc00bfe070100000008000000010000000000000000000000000000003ca9fb3e00000000b7b6363f9796163ffffefe3e0000803f304277060000000084854d3f01000000110000000300000007000000609061110000000000000000c0b96f0e000000000000000000000000a8894d3f800501012412010050596100000000000000000000000000040000009f9e9e3ea9a8a83eb3b2b23e0000803f00c66d0e00000000000000000000000084854d3f01000000110000000300000002000000c06e6d0e00000000000000009ceefb3ee09161110000000000000000000000000000000000000000000000000000000000000000280001c10400000000000000b017640000000000000000000000000000000000000000000000000000000000000020415846fc3e10926111000000000000000000000000000000000000000000000000000000000000003f000000004014630020629b0c10629a0c40146300000000000000000000000000000000000000000000000000100000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e4420000000000000000000000000000000080926111309461110000584200003042000000000000000000000000a888223f010000005259414c1043050d00000000000000000000000000000000000000000000000000000000000000002cd7fb3e509261110000000000000000e0936111d033120000000000000000000000000000000000200000c10000000000000000000000000000000000000000a888223f010000005259414c804b050d0000000000000000000000000000000000000000000000000000000000000000ccc8fb3ef0926111000000001092611100000000d09061110000000000000000000000000000000000000000000000000000000001500000000000003093611101000000000000000000e03f00002041000000000000000000000000000000005093611104000000000000000000000084854d3f01000000110000000300000002000000209361110000000000000000f0c7fb3ed09061112952d5320000000010936111000000000000000000000000c08a4d3f8011000101000000000000000000000000000100c8c94e3f0000000094c9fb3e0100000000000000a093611100000000000000000000000000000000000000000000000000003442000000000000e83f000000606666d63fc093611180926111000000000000000000000000c08a4d3f8011000101000000000000000000000000000100c8c94e3f0000000084854d3f0000000001000000030000000100000000000000000000000000000084854d3f0100000011000000030000000200000000946111000000000000000080926111000000000000000000000000d088223f6007fe07020000000800000002000000000000000000000000000000b4effb3e7094611100000000000000000000000030976111000000000000000000000000f0496300200000c100000000a0946111000080bf0200000000000000a888223f010000005259414c0047050d000000000000000000000000000000000000000000000000000000000000000054a0fb3e10956111000000000000000000000000d0331200000000000000000000000000f0496300330000c100000000000000000000000040629b0c201c630000000000e0a762001032d805000000000000803f0000000000000000010000000000c841000000000416000000000000a888223f010000005259414c8042050d0000000000000000000000000000000000000000000000000000000000000000d088223fc00ffe07010000000800000001000000000000000000000000000000907c6211000000000000000000000000a0946111000000000000000000000000a8894d3f8006010200000000504f6c0e00100000000000000000000000000000000000000000000045f41836397925360000000000000000000000005854554d000000006028000000000000000000000000000000000000d09561110000000000000000d4956111000000000010ea0d0000000000000000000000000000000000000000000000000000000000000000a8894d3f8005010132e100005059610000000000000000000000000004000000e3e2e23ef1f0f03e8180003f0000803fa888223f010000005259414c5045050d0000000000000000000000000000000000000000000000000000000000000000a888223f010000005259414cc044050d000000000000000000000000000000000000000000000000000000000000000054a0fb3e202fc508000000000000000000000000d0331200000000000000000000000000f0496300330000c10000000000000000000000008054990c201c630000000000e0a762001032d805000000000000803f0000000000000000010000000000c841000000000416000000000000a0966111000000000000000000000000087c070000000000000000000000000084854d3f010000001100000003000000020000007095611100000000000000009ceefb3e409661110000000000000000000000000000000000000000000000000000000000000000280001c10400000000000000b017640000000000000000000000000000000000000000000000000000000000000020415846fc3e60986111000000000000000000000000000000000000000000000000000000000000003f0000000040146300402a930c20a5990c40146300000000000000000000000000000000000000000000000000100000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e44200000000000000000000000000000000a0986111509a611100005842000030420000000000000000000000002cd7fb3e709661110000000000000000009a6111d033120000000000000000000000000000000000200000c10000000000000000000000000000000000000000ccc8fb3e10996111000000006098611100000000509761110000000000000000000000000000000000000000000000000000000001500000000000005099611101000000000000000000e03f00002041000000000000000000000000000000007099611104000000000000000000000084854d3f01000000110000000300000002000000409961110000000000000000f0c7fb3e509761112952d5320000000030996111000000000000000000000000c08a4d3f8011000101000000000000000000000000000100c8c94e3f0000000094c9fb3e0100000000000000c099611100000000000000000000000000000000000000000000000000003442000000000000e83f000000606666d63fe0996111a0986111000000000000000000000000c08a4d3f8011000101000000000000000000000000000100c8c94e3f0000000084854d3f00000000010000000300000001000000000000000000000000
Now I'm trying to convert this Hex string back into an image using this code:
Bitmap newImage = new Bitmap(new MemoryStream(StringToByteArray(hex)));
public static byte[] StringToByteArray(string hex)
{
hex = hex.Substring(2, hex.Length - 2);
if (hex.Length % 2 != 0)
{
throw new ArgumentException(String.Format(CultureInfo.InvariantCulture, "The binary key cannot have an odd number of digits: {0}", hex));
}
byte[] HexAsBytes = new byte[hex.Length / 2];
for (int index = 0; index < HexAsBytes.Length; index++)
{
string byteValue = hex.Substring(index * 2, 2);
HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
return HexAsBytes;
}
But I keep getting Parameter is not valid, when attempting to Load the stream into a Bitmap. I posed the question to the developer of the App, and here is his response:
Dear Alex
The data is stored in binary, hex format. Here are the instructions on how to read the binary data and write it back out as a jpg.
byteData[i] = (digit [i * 2] shl 4) + (digit [i * 2 + 1])
The above assumes that the digits are already converted to numbers from 0 to 15. If you’re trying to optimize your script by writing to memory in larger chunks (integers, for instance) you need to take endianness into account. All major CPU architectures are little-endian which means the numbers are stored with their bytes arranged in the opposite order from their actual value (ie, 0x1234 is stored as 0x3412 in memory).
Below are two different scripts for extracting blob data from the form:
1. Python Script:
iterate over each photo attached to image field in FormConnect xml file
data = R[i]
to strip '0x' off front of each blob
a = data[2:]
iterate over each byte, write as binary int to array
for i in range(len(a)/2):
b = (int(bin(int(a[i*2],16)),2)<<4) + int(bin(int(a[i*2+1],16)),2)
data.append(b)
write array to binary file
F = file(outFile,'wb')
data.tofile(F)
F.close()
PHP Script:
$pic = "";
$field = substr($field,2);
header("Content-Type: image/jpeg");
$pic = pack("H*", $field);
echo $pic;
If anyone can help me on this, I would be very grateful.
Kind regards,
Alex
Your problem isn't the hex conversion routine, it's that the original data isn't encoded properly. Based on all the zeroes within it, I'd say it's just a raw bitmap! My guess is that the author of the program that generated that data forgot to encode the bitmap into a specific file format before outputting it.

C# Create an Auth Token from Guid combined with 40Char Hex string (UUID)

I am writing an asp.net MVC app that drives an IPhone application.
I want the Iphone to send me its UUID looks like this:
2b6f0cc904d137be2e1730235f5664094b831186
On the server I want to generate a Guid:
466853EB-157D-4795-B4D4-32658D85A0E0
On both the Iphone and the Server I need a simple aglorithm to combine these 2 values into an Auth token that can be passed around. Both the IPhone and the ASP.NET MVC app need to be able to compute the value over and over based on the UUID and the GUID.
So this needs to be a simple algorithm with no libraries from the .net framework.
Full Solution Here
public void Test()
{
var DeviceId = Guid.NewGuid();
var newId = "2b6f0cc904d137be2e1730235f5664094b831186";
var guidBytes = DeviceId.ToByteArray();
var iphoneBytes = StringToByteArray(newId);
byte[] xor = new byte[guidBytes.Length];
for (int i=0;i<guidBytes.Length;i++)
{
xor[i] = (byte) (guidBytes[i] ^ iphoneBytes[i]);
}
var result = ByteArrayToString(xor);
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
public static string ByteArrayToString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
Well, the iPhone ID looks like a hex string, so converting both to binary and XORing the bytes ought to do it. You could store the result as an array, hex string, or base-64 encoded string as appropriate.
The way you refer to this as an "auth token" is a little concerning, however. Session ids must be unpredictable. You might consider generating an array of cryptographically random data on the server instead of a GUID.
Edit
// Convert the server GUID to a byte array.
byte[] guidBytes = severGuid.ToByteArray();
// Convert the iPhone device ID to an array
byte[] idBytes = StringToByteArray(iPhoneId);
Sadly, it seems .NET doesn't have a built-in method to convert to/from hex strings, but this subject has been covered before: Convert byte array to hex string and vice versa
// Once you've XORed the bytes, conver the result to a string.
string outputString = ByteArrayToString(outputBytes);
Just as a side note, all the "auth token" mechanisms I've worked with (at least) concatenated a constant value (a "secret") with the current time, then hashed them together then sent the hash and the date. The server then reconstructed the hash from the received date and known "secret" and then compared to the received hash (signature).
My point here was "concatenated with date" - this allows the resulting signature to be different every time which in theory should be more secure.
Rather than XORing, which loses information, you could just concatenate these hex digits.
Why do you even need the GUID? The phone ID is unique, the GUID seems to add no value.
I thought you can use two way algorithm. It mean the algorithm can be encode and decode like Base64, SHA256, AES

Categories