So I have an issue with comparing MD5 sums of the same text using the same techniques. I am using .NET MD5 tools and Unix's md5sum.exe program.
Here's my .NET code:
public void Test()
{
string str1 = "testline1";
string str2 = "testline2";
StringBuilder sb = new StringBuilder();
sb.Append(str1);
sb.Append(Constants.vbLf);
sb.Append(str2);
string hash = GetMD5Hash(sb.ToString());
//hash = 4fb435ffb8e071151c3411dd3a922460
}
public string GetMD5Hash(string text)
{
byte[] hash;
using (MD5 md5 = MD5.Create())
{
hash = md5.ComputeHash(Encoding.UTF8.GetBytes(text));
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString();
}
I have a server running a unix based OS which has md5sum.exe on it. On my server I have a file which is simply:
testline1
testline2
Let's say the file is named testFile.txt
I have tried running multiple variations of md5sum to see if I can get these values to equal to no avail.
$md5sum testFile.txt //22f877bcf8985a0f038a5b70086b955d
$echo -n $(cat testFile.txt) | md5sum //1e192bb9877cc2f20e7010d499c0a306
$echo -E $(cat testFile.txt) | md5sum //83b6873b79ca36952eb58ea05083c02e
$unix2dos testFile.txt //converting file to dos just in case line endings are issue
$md5sum testFile.txt //d302436fa25c7faaab75ceca1f1df16d
$echo -n $(cat testFile.txt) | md5sum //94f0c8f7e9820cb6eda9e911ee21b2a8
$echo -E $(cat testFile.txt) | md5sum //f39452a70621ed225057073e86f17858
I have worked at this for hours and cannot seem to get these MD5 to match. Any ideas?
Your testFile.txt has a newline at the end of the second line, whereas your .NET code is not putting a newline at the end of the second line. If you run your file through xxd, you'll be able to see the extra newline that's tripping you up.
This is probably due to the different line-breaks on each OS.
See here for how to convert one of those files to match the other's line breaks, and I bet your checksums will then match: http://en.wikipedia.org/wiki/Newline#Conversion_utilities
echo -n "root" | md5sum
The problem is newline, when to get the result in terminal, if you don't use -n, the result is wrong.
-n do not output the trailing newline
Related
i'm trying to decode a string and save it into a file following this method
C# code working successfully:
string val;
var path = #"decoded.txt";
Console.Write("Enter value:");
val = Console.ReadLine();
byte[] bytes1 = Convert.FromBase64String(val);
File.WriteAllBytes(path, bytes1);
but i dont get the same result using bash:
echo -n realm_result.json.public_key | base64 -di > temp_key_public
EDIT
the working bash mlethod:
printf '%s' {{ realm_result.json.public_key }} | base64 -d > temp_key_public
thank you #konrad-rudolph for pointing to the type of variable, it is an ansible task result containing a string.
This question already has an answer here:
bash, md5sum behaves strange
(1 answer)
Closed 2 years ago.
I'm trying understand why when i use a linux md5sum function, like this:
#!/bin/bash
p="4c4712a4141d261ec0ca8f90379"
Etime="123456"
TOTP=$(echo $Etime$p|md5sum|cut -f1 -d' ')
echo $TOTP
I've got: ce007ddfb5eb0ccda6d4a6ddd631c563
But when i trying generate md5sum in c# using this code:
public static string Hash()
{
string p = "4c4712a4141d261ec0ca8f90379";
string Etime = "123456";
string h = Etime + p ;
string r = md5test(h);
return r;
}
public static string md5test(string testString)
{
byte[] asciiBytes = ASCIIEncoding.UTF8.GetBytes(testString);
byte[] hashedBytes = MD5CryptoServiceProvider.Create().ComputeHash(asciiBytes);
string hashedString = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
return hashedString;
}
I've got different value: acb6242ab9ad7a969fb27f10644a0283
I think the problem is in conversion bytes to string, but i'm not sure.
Does anyone could explain where i make mistake or how to do to have expected value:ce007ddfb5eb0ccda6d4a6ddd631c563
Thanks
Wojtek
The problem is the newline at the end of the output of echo. Use echo -n or printf instead:
TOTP=$(printf %s "$Etime$p" | md5sum | cut -f1 -d' ')
I rewritten the bash part of you test:
printf '1234564c4712a4141d261ec0ca8f90379' | md5sum
# prints: acb6242ab9ad7a969fb27f10644a0283 -
printf '1234564c4712a4141d261ec0ca8f90379\n' | md5sum
# prints: ce007ddfb5eb0ccda6d4a6ddd631c563 -
The difference is, that echo append a new line character. A solution is to use echo with option -n: echo -n .... A better solution is, to use printf instead of echo: printf %s%s' "$Etime" "$p"
I'm trying to consume an API and for that purpose I have to create a signature using SHA384. The docs describe doing:
signature = hex(HMAC_SHA384(base64(payload), key=api_secret))
They give an example:
~$ base64 << EOF
> {
> "request": "/v1/order/status",
> "nonce": 123456,
>
> "order_id": 18834
> }
> EOF
ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYs
CgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=
In this example, the api_secret is 1234abcd
echo -n 'ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=' | openssl sha384 -hmac "1234abcd"
(stdin)= 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f
It took a little while, but I realized that in order to replicate the base64 of the original string I had to replace "\r\n" with "\n".
Here's what I've got (ignoring the formatting that I wasted 20 minutes trying to make good):
var raw = #"{
""request"": ""/v1/order/status"",
""nonce"": 123456,
""order_id"": 18834
}
";
var data = raw.Replace("\r\n", "\n");
Console.WriteLine(data);
var data64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(data.ToCharArray()));
if (data64 != "ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=")
{
Console.WriteLine("base64's don't match");
}
Console.WriteLine("ewogICAgInJlcXVlc3QiOiAiL3YxL29yZGVyL3N0YXR1cyIsCiAgICAibm9uY2UiOiAxMjM0NTYsCgogICAgIm9yZGVyX2lkIjogMTg4MzQKfQo=");
Console.WriteLine(data64);
var key = Encoding.UTF8.GetBytes("1234abcd");
using (var hash = new HMACSHA384(key))
{
var hash64 = Convert.ToBase64String(hash.ComputeHash(Encoding.UTF8.GetBytes(data64)));
StringBuilder sb = new StringBuilder();
foreach (char c in hash64)
{
sb.Append(Convert.ToInt32(c).ToString("x"));
}
Console.WriteLine(sb.ToString());
// yields:
// 4d337a49744f70704c50356c744b68667a4a38454b79342f6343724a5676304a6a57414b7356634664314158767135414b2b647a7a753451635a2f3344584550
// should be:
// 337cc8b4ea692cfe65b4a85fcc9f042b2e3f702ac956fd098d600ab15705775017beae402be773ceee10719ff70d710f
}
My code's output doesn't match the documentation's expected output. Can someone see what I'm doing wrong?
For some reason you are converting hash to base-64 string, then you convert each character of that string to int and that you convert to hex. All that is not needed and not described in "documentation". Instead, do like this:
var hashBin = hash.ComputeHash(Encoding.UTF8.GetBytes(data64));
var hashHex = BitConverter.ToString(hashBin).Replace("-", "").ToLowerInvariant();
Console.WriteLine(hashHex);
I'm having a hard time trying to figure this out. I'm writing a Unit test that verifies that the MD5 that a site displays matches the actual MD5 of the file. I do this by simply grabbing what the page displays and then calculating my own MD5 of the file. I get the text on the page by using Selenium WebDriver.
As expected, the strings show up as the same...or it appears to be
When I try to test the two strings using Assert.AreEqual or Assert.IsTrue, it fails no matter how I try to compare them
I've tried the following ways:
Assert.AreEqual(md5, md5Text); //Fails
Assert.IsTrue(md5 == md5Text); //Fails
Assert.IsTrue(String.Equals(md5, md5Text)); //Fails
Assert.IsTrue(md5.Normalize() == md5Text.Normalize()); //Fails
Assert.AreEqul(md5.Normalize(), md5Text.Normalize()); //Fails
At first, I thought the strings were actual different, but looking at them in the debugger shows that both strings are exactly the same
So I tried looking at their lengths, that's when I saw why
The strings are different lengths..so I tried to substring the md5 variable to match the size of the md5Text variable. My thinking here was maybe md5 had a bunch of 0 width characters. However doing this got rid of the last half of md5
SOO, this must mean their in different encodings correct? But wouldn't Normalize() fix that?
This is how the variable md5 is created
string md5;
using (var stream = file.Open()) //file is a custom class with an Open() method that returns a Stream
{
using (var generator = MD5.Create())
{
md5 = BitConverter.ToString(generator.ComputeHash(stream)).Replace("-", "").ToLower().Trim();
}
}
and this is how the md5Text variable is created
//I'm using Selenium WebDrvier to grab the text from the page
var md5Element = row.FindElements(By.XPath("//span[#data-bind='text: MD5Hash']")).Where(e => e.Visible()).First();
var md5Text = md5Element.Text;
How can I make this test pass? as it should be passing (since they are the same)
UPDATE:
The comments suggested I turn the strings into a char[] and iterate over it. Here are the results of that (http://pastebin.com/DX335wU8) and the code I added to do it
char[] md5Characters = md5.ToCharArray();
char[] md5TextCharacters = md5Text.ToCharArray();
//Use md5 length since it's bigger
for (int i = 0; i < md5Characters.Length; i++)
{
System.Diagnostics.Debug.Write("md5: " + md5Characters[i]);
if (i >= md5TextCharacters.Length)
{
System.Diagnostics.Debug.Write(" | Exhausted md5Text characters..");
}
else
{
System.Diagnostics.Debug.Write(" | md5Text: " + md5TextCharacters[i]);
}
System.Diagnostics.Debug.WriteLine("");
}
One thing I found interesting is that the md5 char array has a bunch of random characters inside of it every 2 letters
.Replace("-", "")
Your "" is not empty, there is actually a " then unicode zero width non-joiner + zero width space then " so you are not replacing "-" with an empty string rather you are inserting additional characters.
Delete and retype "" or use String.Empty.
I loaded up a small console app that simply reads and prints the first command line argument passed to the program to the console.
I want to pass a newline to the argument I tried this:
prog.exe \n --> outputs \n
prog.exe "sfs \n sfff" --> outputs sfs \n sfff
prog.exe "ff \\n ff" --> outputs ff \\n ff
prog .exe "ff \\\\n ff" --> outputs ff \\\\n ff
Is there some other escaping I'm suppose to use? Or is there some function I have to call on args[0] to process escaped characters before outputting it to the console?
To clarify, I'm trying to pass a string to my program that has newlines in it. The outputting to console was being used as a test. I could have just as easily inserted a debug break line and inspect the contents of the variable.
The problem you're having is that the strings you get from the command line are not compiled. When you have string literals in your code they are compiled and this is when escape characters are processed and converted into newlines etc. You will probably have to do something like replacing all instances of "\n" in your input string with a newline character.
Edit:
From here (with minor modifications), this will compile your string using the CSharp compiler thus replacing the escape sequences with the appropriate characters:
public static string ParseString(string input)
{
var provider = new Microsoft.CSharp.CSharpCodeProvider();
var parameters = new System.CodeDom.Compiler.CompilerParameters()
{
GenerateExecutable = false,
GenerateInMemory = true,
};
var code = #"
public class TmpClass
{
public static string GetValue()
{
return """ + input + #""";
}
}";
var compileResult = provider.CompileAssemblyFromSource(parameters, code);
if (compileResult.Errors.HasErrors)
{
throw new ArgumentException(compileResult.Errors.Cast<System.CodeDom.Compiler.CompilerError>().First(e => !e.IsWarning).ErrorText);
}
var asmb = compileResult.CompiledAssembly;
var method = asmb.GetType("TmpClass").GetMethod("GetValue");
return method.Invoke(null, null) as string;
}
Passing line breaks in command line arguments works as expected, actually. Quick test in PowerShell:
PS> ./echoargs "a`nb" b c
arg 1: a
b
arg 2: b
arg 3: c
Now, if what you're trying is to do the same thing in cmd that could prove difficult (and is not really obvious from your question – Process.Start would work, though).
If you pass prog .exe "ff \\\\n ff"
you can replace them from inside your code var s = arg[0[.Replace("\" ,#"\\"); like this
From the windows command line, this is impossible. For security, C# parses user input from the command line as entirely literal. There are no escape characters that will automatically create a new line, unless you write code to go through the string and replace \n with the actual newline character.
If you type in \n into the command line, C# will parse that as \\n.