I want to convert a some code which is in Java to C#.
Java Code:
private static final byte[] SALT = "NJui8*&N823bVvy03^4N".getBytes();
public static final String getSHA256Hash(String secret)
{
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(secret.getBytes());
byte[] hash = digest.digest(SALT);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
hexString.append(Integer.toHexString(0xFF & hash[i]));
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
throw new RuntimeException("SHA-256 realization algorithm not found in JDK!");
}
When I tried to use the SimpleHash class I got different hashs
UPDATE:
For example:
Java: byte[] hash = digest.digest(SALT);
generates (first 6 bytes):
[0] = 9
[1] = -95
[2] = -68
[3] = 64
[4] = -11
[5] = 53
....
C# code (class SimpleHash):
string hashValue = Convert.ToBase64String(hashWithSaltBytes);
hashWithSaltBytes has (first 6 bytes):
[0] 175 byte
[1] 209 byte
[2] 120 byte
[3] 74 byte
[4] 74 byte
[5] 227 byte
The String.getBytes method encodes the string to bytes using the platform's default charset, whereas the example code you linked uses UTF-8.
Try this:
digest.update(secret.getBytes("UTF-8"));
Secondly, the Integer.toHexString method returns the hexadecimal result with no leading 0s.
The C# code you link to also uses salt - but the Java code does not. If you use salt with once, but not the other, then the results will be (and should be!) different.
hexString.append(Integer.toHexString(0xFF & hash[i]));
You are building the hash string incorrectly. Integer.toHexString does not include leading zeros, so while Integer.toHexString(0xFF) == "FF", the problem is that Integer.toHexString(0x05) == "5".
Suggested correction: String.format("%02x", hash[i] & 0xFF)
public static String getEncryptedPassword(String clearTextPassword) throws NoSuchAlgorithmException{
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(clearTextPassword.getBytes(StandardCharsets.UTF_8));
byte[] digest = md.digest();
String hex = String.format("%064x", new BigInteger(1, digest));
String st = new String(hex.toUpperCase());
for (int i = 2; i < (hex.length() + hex.length() / 2) - 1 ;) {
st = new StringBuffer(st).insert(i, "-").toString();
i = i + 3;
}
return st ;
}
You can use the following java to match that of C#
You didn't really write how you called the SimpleHash class - with which parameters and such.
But note that its ComputeHash method has in its documentation:
Hash value formatted as a base64-encoded string.
Your class instead formats the output in hexadecimal, which will obviously be different.
Also, the salt is in SimpleHash interpreted as base64, while your method interprets it as ASCII (or whatever your system encoding is - most probably something ASCII-compatible, and the string only contains ASCII characters).
Also, the output in SimpleHash includes the salt (to allow reproducing it for the "verify" part when using random salt), which it doesn't in your method.
(More points are already mentioned by the other answers.)
Related
I got a boolean list with 92 booleans, I want the list to be converted to a string, I thought I ll take 8 booleans(bits) and put them in a Byte(8 bits) and then use the ASCII to convert it the byte value to a char then add the chars to a string. However after googeling for more then 2 hours, no luck atm. I tried converting the List to a Byte list but it didn t work either ^^.
String strbyte = null;
for (int x = 0; x != tmpboolist.Count; x++) //tmpboolist is the 90+- boolean list
{
//this loop checks for true then puts a 1 or a 0 in the string(strbyte)
if (tmpboolist[x])
{
strbyte = strbyte + '1';
}
else
{
strbyte = strbyte + '0';
}
}
//here I try to convert the string to a byte list but no success
//no success because the testbytearray has the SAME size as the
//tmpboolist(but it should have less since 8 booleans should be 1 Byte)
//however all the 'Bytes' are 48 & 49 (which is 1 and 0 according to
//http://www.asciitable.com/)
Byte[] testbytearray = Encoding.Default.GetBytes(strbyte);
PS If anyone has a better suggestion on how to code & decode a Boolean list to a String?
(Because I want people to share their boolean list with a string rather then a list of 90 1 and 0s.)
EDIT: got it working now! ty all for helping
string text = new string(tmpboolist.Select(x => x ? '1' : '0').ToArray());
byte[] bytes = getBitwiseByteArray(text); //http://stackoverflow.com/a/6756231/1184013
String Arraycode = Convert.ToBase64String(bytes);
System.Windows.MessageBox.Show(Arraycode);
//first it makes a string out of the boolean list then it uses the converter to make it an Byte[](array), then we use the base64 encoding to make the byte[] a String.(that can be decoded later)
I ll look into the encoding32 later, ty for all the help again :)
You should store your boolean values in a BitArray.
var values = new BitArray(92);
values[0] = false;
values[1] = true;
values[2] = true;
...
Then you can convert the BitArray to a byte array
var bytes = new byte[(values.Length + 7) / 8];
values.CopyTo(bytes);
and the byte array to a Base64 string
var result = Convert.ToBase64String(bytes);
Reversely, you can convert a Base64 string to a byte array
var bytes2 = Convert.FromBase64String(result);
and the byte array to a BitArray
var values2 = new BitArray(bytes2);
The Base64 string looks like this: "Liwd7bRv6TMY2cNE". This is probably a bit unhandy for sharing between people; have a look at human-oriented base-32 encoding:
Anticipated uses of these [base-32 strings] include cut-
and-paste, text editing (e.g. in HTML files), manual transcription via a
keyboard, manual transcription via pen-and-paper, vocal transcription over
phone or radio, etc.
The desiderata for such an encoding are:
minimizing transcription errors -- e.g. the well-known problem of confusing
'0' with 'O'
embedding into other structures -- e.g. search engines, structured or
marked-up text, file systems, command shells
brevity -- Shorter [strings] are better than longer ones.
ergonomics -- Human users (especially non-technical ones) should find the
[strings] as easy and pleasant as possible. The uglier the [strings] looks, the worse.
To start with, it's a bad idea to concatenate strings in a loop like that - at least use StringBuilder, or use something like this with LINQ:
string text = new string(tmpboolist.Select(x => x ? '1' : '0').ToArray());
But converting your string to a List<bool> is easy with LINQ, using the fact that string implements IEnumerable<char>:
List<bool> values = text.Select(c => c == '1').ToList();
It's not clear where the byte array comes in... but you should not try to represent arbitrary binary data in a string just using Encoding.GetString. That's not what it's for.
If you don't care what format your string uses, then using Base64 will work well - but be aware that if you're grouping your Boolean values into bytes, you'll need extra information if you need to distinguish between "7 values" and "8 values, the first of which is False" for example.
Since I am infering from your code you want a string with n digits of either 1 or 0 depending onthe internal lists bool value then how about...
public override string ToString()
{
StringBuilder output = new StringBuilder(91);
foreach(bool item in this.tempboolist)
{
output.Append(item ? "1" : "0");
}
return output.ToString();
}
Warning this was off the cuff typing, I have not validated this with a compiler yet!
This function does what you want:
public String convertBArrayToStr(bool[] input)
{
if (input == null)
return "";
int length = input.Count();
int byteArrayCount = (input.Count() - 1) / 8 + 1;
var bytes = new char[byteArrayCount];
for (int i = 0; i < length; i++ )
{
var mappedIndex = (i - 1) / 8;
bytes[mappedIndex] = (char)(2 * bytes[mappedIndex] +(input[i] == true ? 1 : 0));
}
return new string(bytes);
}
I've been working on converting a C++ crypting method to C#. The problem is, I cant get it to encrypt/decrypt the way I want it to.
The idea is simple, I capture a packet, and decrypt it. The output will be:
Packet Size - Command/Action - Null (End)
(The decryptor cuts off the first and last 2 bytes)
The C++ code is this:
// Crypt the packet with Xor operator
void cryptPacket(char *packet)
{
unsigned short paksize=(*((unsigned short*)&packet[0])) - 2;
for(int i=2; i<paksize; i++)
{
packet[i] = 0x61 ^ packet[i];
}
}
So I thought this would work in C# if I didn't want to use pointers:
public static char[] CryptPacket(char[] packet)
{
ushort paksize = (ushort) (packet.Length - 2);
for(int i=2; i<paksize; i++)
{
packet[i] = (char) (0x61 ^ packet[i]);
}
return packet;
}
-but it isn't, the value returned is just another line of rubish instead of the decrypted value. The output given is: ..O♦&/OOOe.
Well.. atleast the '/' is in the right place for some reason.
Some more information:
The test packet I'm using is this:
Hex value: 0C 00 E2 66 65 47 4E 09 04 13 65 00
Plain text: ...feGN...e.
Decrypted: XX/hereXX
X = Unknown value, I cant really remember, but it doesn't matter.
Using Hex Workshop you can decrypt the packet this way:
Special Paste the hex value as CF_TEXT, make sure the 'treat as hexidecimal value' box is checked.
Afterwards, select everything from the hexidecimal value you just pasted, except the first and last 2 bytes.
Go to Tools>Operations>Xor.
Select 'Treat data as 8 bit data' and set value to '61'.
Press 'OK', and you'r done.
That's all the information I can give at the moment, because I'm writing this off the top of my head.
Thank you for your time.
In case you don't see a question in this:
It would be great if someone could take a look at the code to see what's wrong with it, or if there's another way to do it. I'm converting this code because I'm horrible with C++, and want to create a C# application with that code.
Ps: The code tags and such were a pain, so I'm sorry if the spacing etc. is a little messed up.
Your problem might be that as .NET's char is unicode, some characters are going to be using more than one byte, and your bitmask is only one byte long. So the most significant byte will be left unaltered.
I just tried your function and it seems ok:
class Program
{
// OP's method: http://stackoverflow.com/questions/4815959
public static byte[] CryptPacket(byte[] packet)
{
int paksize = packet.Length - 2;
for (int i = 2; i < paksize; i++)
{
packet[i] = (byte)(0x61 ^ packet[i]);
}
return packet;
}
// http://stackoverflow.com/questions/321370 :)
public static byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length).
Where(x => 0 == x % 2).
Select(x => Convert.ToByte(hex.Substring(x, 2), 16)).
ToArray();
}
static void Main(string[] args)
{
string hex = "0C 00 E2 66 65 47 4E 09 04 13 65 00".Replace(" ", "");
byte[] input = StringToByteArray(hex);
Console.WriteLine("Input: " + ASCIIEncoding.ASCII.GetString(input));
byte[] output = CryptPacket(input);
Console.WriteLine("Output: " + ASCIIEncoding.ASCII.GetString(output));
Console.ReadLine();
}
}
Console output:
Input: ...feGN.....
Output: ...../here..
(where '.' represents funny ascii characters)
It seems a bit smelly that your CryptPacket method is overwriting the initial array with the output values. And that irrelevant characters are not trimmed. But if you are trying to port something, I guess you should know what you are doing.
You could also consider trimming the input array, to remove the unwanted characters first, and then use a generic ROT13 method (like this one). This way you have your own "specialized" version with 2-byte offsets inside the crypt function itself, instead of something like:
public static byte[] CryptPacket(byte[] packet)
{
// create a new instance
byte[] output = new byte[packet.Length];
// process ALL array items
for (int i = 0; i < packet.Length; i++)
{
output[i] = (byte)(0x61 ^ packet[i]);
}
return output;
}
Here's an almost literal translation from C++ to C#, and it seems to work:
var packet = new byte[] {
0x0C, 0x00, 0xE2, 0x66, 0x65, 0x47,
0x4E, 0x09, 0x04, 0x13, 0x65, 0x00
};
CryptPacket(packet);
// displays "....../here." where "." represents an unprintable character
Console.WriteLine(Encoding.ASCII.GetString(packet));
// ...
void CryptPacket(byte[] packet)
{
int paksize = (packet[0] | (packet[1] << 8)) - 2;
for (int i = 2; i < paksize; i++)
{
packet[i] ^= 0x61;
}
}
I need a way to take a 12 digit number and encrypt it to a different 12 digit number (no characters other than 0123456789). Then at a later point I need to be able to decrypt the encrypted number back to the original number.
It is important that it isn't obvious if 2 encrypted numbers are in order. So for instance if I encrypt 0000000000001 it should look totally different when encrypted than 000000000002. It doesn't have to be the most secure thing in the world, but the more secure the better.
I've been looking around a lot but haven't found anything that seems to be a perfect fit. From what I've seen some type of XOR might be the easiest way to go, but I'm not sure how to do this.
Thanks,
Jim
I ended up solving this thanks to you guys using "FPE from a prefix cipher" from the wikipedia page http://en.wikipedia.org/wiki/Format-preserving_encryption. I'll give the basic steps below to hopefully be helpful for someone in the future.
NOTE - I'm sure any expert will tell you this is a hack. The numbers seemed random and it was secure enough for what I needed, but if security is a big concern use something else. I'm sure experts can point to holes in what I did. My only goal for posting this is because I would have found it useful when doing my search for an answer to the problem. Also only use this in situations where it couldn't be decompiled.
I was going to post steps, but its too much to explain. I'll just post my code. This is my proof of concept code I still need to clean up, but you'll get the idea. Note my code is specific to a 12 digit number, but adjusting for others should be easy. Max is probably 16 with the way I did it.
public static string DoEncrypt(string unencryptedString)
{
string encryptedString = "";
unencryptedString = new string(unencryptedString.ToCharArray().Reverse().ToArray());
foreach (char character in unencryptedString.ToCharArray())
{
string randomizationSeed = (encryptedString.Length > 0) ? unencryptedString.Substring(0, encryptedString.Length) : "";
encryptedString += GetRandomSubstitutionArray(randomizationSeed)[int.Parse(character.ToString())];
}
return Shuffle(encryptedString);
}
public static string DoDecrypt(string encryptedString)
{
// Unshuffle the string first to make processing easier.
encryptedString = Unshuffle(encryptedString);
string unencryptedString = "";
foreach (char character in encryptedString.ToCharArray().ToArray())
unencryptedString += GetRandomSubstitutionArray(unencryptedString).IndexOf(int.Parse(character.ToString()));
// Reverse string since encrypted string was reversed while processing.
return new string(unencryptedString.ToCharArray().Reverse().ToArray());
}
private static string Shuffle(string unshuffled)
{
char[] unshuffledCharacters = unshuffled.ToCharArray();
char[] shuffledCharacters = new char[12];
shuffledCharacters[0] = unshuffledCharacters[2];
shuffledCharacters[1] = unshuffledCharacters[7];
shuffledCharacters[2] = unshuffledCharacters[10];
shuffledCharacters[3] = unshuffledCharacters[5];
shuffledCharacters[4] = unshuffledCharacters[3];
shuffledCharacters[5] = unshuffledCharacters[1];
shuffledCharacters[6] = unshuffledCharacters[0];
shuffledCharacters[7] = unshuffledCharacters[4];
shuffledCharacters[8] = unshuffledCharacters[8];
shuffledCharacters[9] = unshuffledCharacters[11];
shuffledCharacters[10] = unshuffledCharacters[6];
shuffledCharacters[11] = unshuffledCharacters[9];
return new string(shuffledCharacters);
}
private static string Unshuffle(string shuffled)
{
char[] shuffledCharacters = shuffled.ToCharArray();
char[] unshuffledCharacters = new char[12];
unshuffledCharacters[0] = shuffledCharacters[6];
unshuffledCharacters[1] = shuffledCharacters[5];
unshuffledCharacters[2] = shuffledCharacters[0];
unshuffledCharacters[3] = shuffledCharacters[4];
unshuffledCharacters[4] = shuffledCharacters[7];
unshuffledCharacters[5] = shuffledCharacters[3];
unshuffledCharacters[6] = shuffledCharacters[10];
unshuffledCharacters[7] = shuffledCharacters[1];
unshuffledCharacters[8] = shuffledCharacters[8];
unshuffledCharacters[9] = shuffledCharacters[11];
unshuffledCharacters[10] = shuffledCharacters[2];
unshuffledCharacters[11] = shuffledCharacters[9];
return new string(unshuffledCharacters);
}
public static string DoPrefixCipherEncrypt(string strIn, byte[] btKey)
{
if (strIn.Length < 1)
return strIn;
// Convert the input string to a byte array
byte[] btToEncrypt = System.Text.Encoding.Unicode.GetBytes(strIn);
RijndaelManaged cryptoRijndael = new RijndaelManaged();
cryptoRijndael.Mode =
CipherMode.ECB;//Doesn't require Initialization Vector
cryptoRijndael.Padding =
PaddingMode.PKCS7;
// Create a key (No IV needed because we are using ECB mode)
ASCIIEncoding textConverter = new ASCIIEncoding();
// Get an encryptor
ICryptoTransform ictEncryptor = cryptoRijndael.CreateEncryptor(btKey, null);
// Encrypt the data...
MemoryStream msEncrypt = new MemoryStream();
CryptoStream csEncrypt = new CryptoStream(msEncrypt, ictEncryptor, CryptoStreamMode.Write);
// Write all data to the crypto stream to encrypt it
csEncrypt.Write(btToEncrypt, 0, btToEncrypt.Length);
csEncrypt.Close();
//flush, close, dispose
// Get the encrypted array of bytes
byte[] btEncrypted = msEncrypt.ToArray();
// Convert the resulting encrypted byte array to string for return
return (Convert.ToBase64String(btEncrypted));
}
private static List<int> GetRandomSubstitutionArray(string number)
{
// Pad number as needed to achieve longer key length and seed more randomly.
// NOTE I didn't want to make the code here available and it would take too longer to clean, so I'll tell you what I did. I basically took every number seed that was passed in and prefixed it and postfixed it with some values to make it 16 characters long and to get a more unique result. For example:
// if (number.Length = 15)
// number = "Y" + number;
// if (number.Length = 14)
// number = "7" + number + "z";
// etc - hey I already said this is a hack ;)
// We pass in the current number as the password to an AES encryption of each of the
// digits 0 - 9. This returns us a set of values that we can then sort and get a
// random order for the digits based on the current state of the number.
Dictionary<string, int> prefixCipherResults = new Dictionary<string, int>();
for (int ndx = 0; ndx < 10; ndx++)
prefixCipherResults.Add(DoPrefixCipherEncrypt(ndx.ToString(), Encoding.UTF8.GetBytes(number)), ndx);
// Order the results and loop through to build your int array.
List<int> group = new List<int>();
foreach (string key in prefixCipherResults.Keys.OrderBy(k => k))
group.Add(prefixCipherResults[key]);
return group;
}
One more way for simple encryption, you can just substruct each number from 10.
For example
initial numbers: 123456
10-1 = 9
10-2 = 8
10-3 = 7
etc.
and you will get
987654
You can combine it with XOR for more secure encryption.
What you're talking about is kinda like a one-time pad. A key the same length as the plaintext and then doing some modulo math on each individual character.
A xor B = C
C xor B = A
or in other words
A xor B xor B = A
As long as you don't use the same key B on multiple different inputs (e.g. B has to be unique, every single time you encrypt), then in theory you can never recover the original A without knowing what B was. If you use the same B multiple times, then all bets are off.
comment followup:
You shouldn't end up with more bits aftewards than you started with. xor just flips bits, it doesn't have any carry functionality. Ending up with 6 digits is just odd... As for code:
$plaintext = array(digit1, digit2, digit3, digit4, digit5, digit6);
$key = array(key1, key2, key3, key4, key5, key6);
$ciphertext = array()
# encryption
foreach($plaintext as $idx => $char) {
$ciphertext[$idx] = $char xor $key[$idx];
}
# decryption
foreach($ciphertext as $idx => $char) {
$decrypted[$idx] = $char xor $key[$idx];
}
Just doing this as an array for simplicity. For actual data you'd work on a per-byte or per-word basis, and just xor each chunk in sequence. You can use a key string shorter than the input, but that makes it easier to reverse engineer the key. In theory, you could use a single byte to do the xor'ing, but then you've just basically achieved the bit-level equivalent of rot-13.
For example you can add digits of your number with digits some const (214354178963...whatever) and apply "~" operator (reverse all bits) this is not safely but ensure you can decrypt your number allways.
anyone with reflector or ildasm will be able to hack such an encryption algorithm.
I don't know what is your business requirement but you have to know that.
If there's enough wriggle-room in the requirements that you can accept 16 hexadecimal digits as the encrypted side, just interpret the 12 digit decimal number as a 64bit plaintext and use a 64 bit block cipher like Blowfish, Triple-DES or IDEA.
i have this line I need to write in C#
sprintf(
currentTAG,
"%2.2X%2.2X,%2.2X%2.2X",
hBuffer[ presentPtr+1 ],
hBuffer[ presentPtr ],
hBuffer[ presentPtr+3 ],
hBuffer[ presentPtr+2 ] );
hbuffer is a uchar array.
In C# I have the same data in a byte array and I need to implement this line...
Please help...
Check if this works:
byte[] hBuffer = { ... };
int presentPtr = 0;
string currentTAG = string.Format("{0:X2}{1:X2},{2:X2}{3:X2}",
hBuffer[p+1],
hBuffer[p],
hBuffer[p + 3],
hBuffer[p + 2]);
This is another option but less efficient:
byte[] hBuffer = { ... };
int presentPtr = 0;
string currentTAG = string.Format("{0}{1},{2}{3}",
hBuffer[p+1].ToString("X2"),
hBuffer[p].ToString("X2"),
hBuffer[p + 3].ToString("X2"),
hBuffer[p + 2].ToString("X2"));
Converting each byte of hBuffer to a
string, as in the second example, is
less efficient. The first example will
give you better performance,
especially if you do this many times,
by virtue of not spamming the garbage
collector.
[From the top of my head] In C/C++ %2.2X outputs the value in hexadecimal using upper case letters and at least two letters (left padded with zero).
In C++ the next example outputs 01 61 in the console:
unsigned char test[] = { 0x01, 'a' };
printf("%2.2X %2.2X", test[0], test[1]);
Using the information above, the following C# snippet outputs also 01 61 in the console:
byte[] test = { 0x01, (byte) 'a' };
Console.WriteLine(String.Format("{0:X2} {1:X2}", test[0], test[1]));
Composite Formatting: This page discusses how to use the string.Format() function.
You are looking for String.Format method.
I'm trying to use an integer as the numerical representation of a string, for example, storing "ABCD" as 0x41424344. However, when it comes to output, I've got to convert the integer back into 4 ASCII characters. Right now, I'm using bit shifts and masking, as follows:
int value = 0x41424344;
string s = new string (
new char [] {
(char)(value >> 24),
(char)(value >> 16 & 0xFF),
(char)(value >> 8 & 0xFF),
(char)(value & 0xFF) });
Is there a cleaner way to do this? I've tried various casts, but the compiler, as expected, complained about it.
Characters are 16 bit, so you have to encode them into eight bit values to pack them in an integer. You can use the Encoding class to convert between characters and bytes, and the BitConverter class to convert between bytes and integer
Here is conversion both ways:
string original = "ABCD";
int number = BitConverter.ToInt32(Encoding.ASCII.GetBytes(original), 0);
string decoded = Encoding.ASCII.GetString(BitConverter.GetBytes(number));
Note that the order of the bytes in the integer depends on the endianess of the computer. On a little endian system the numeric value of "ABCD" will be 0x44434241. To get the reverse order, you can reverse the byte array:
byte[] data = Encoding.ASCII.GetBytes(original);
Array.Reverse(data);
int number = BitConverter.ToInt32(data, 0);
byte[] data2 = BitConverter.GetBytes(number);
Array.Reverse(data2);
string decoded = Encoding.ASCII.GetString(data2);
Or if you are using framework 3.5:
int number =
BitConverter.ToInt32(Encoding.ASCII.GetBytes(original).Reverse().ToArray() , 0);
string decoded =
Encoding.ASCII.GetString(BitConverter.GetBytes(number).Reverse().ToArray());
int value = 0x41424344;
string s = Encoding.ASCII.GetString(
BitConverter.GetBytes(value).Reverse().ToArray());
(The above assumes that you're running on a little-endian system. For big-endian you could just drop the .Reverse().ToArray() part, although if you are on a little-endian system then it would probably make more sense for you to just store "ABCD" as 0x44434241 in the first place, if possible.)
public string ConvertToHex(string asciiString)
{
string hex = "";
foreach (char c in asciiString)
{
int tmp = c;
hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
}
return hex;
}
It will convert string to hex as you required.
public static string ToHexString(string value)
{
return value.Aggregate(new StringBuilder("0x"),
(sb, c) => sb.AppendFormat("{0:x2}", (int)c)).ToString();
}
if the string is never longer than 8 chars and a kind of Hexstring, you could use
the base variable 16 have a look at the Conversion functions from the Convert class.
string s = "ABCD";
uint i = Convert.ToUInt32( s, 16 );
MessageBox.Show( Convert.ToString( i, 16 ) );
regards
Oops