I've a big problem.
I using this C# function to encode my message:
byte[] buffer = Encoding.ASCII.GetBytes(file_or_text);
SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
String hashText = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");
On java side, I use this snippet:
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] sha1hash = new byte[40];
md.update(text.getBytes("iso-8859-1"), 0, text.length());
sha1hash = md.digest();
My message is: Block|Notes|Text !£$%&/()=?^€><{}ç°§;:_-.,##ùàòè+
I have this result:
(C#) 8EDC7F756BCECDB99B045FA3DEA2E36AA0BF0875
(Java) 2a566428826539365bb2fe2197da91395c2b1b72
Can you help me please??
Thanks...
My guess is you seem to be comparing ASCII bytes to Latin1 bytes. Try switching
md.update(text.getBytes("iso-8859-1"), 0, text.length());
to this
md.update(text.getBytes("ISO646-US"), 0, text.length());
That might solve your problem.
(Or switch C# to use Latin1)
What is happening in your program your GetBytes method is returning different values for the same characters depending on encoding, so our nifty SHA1 hash algorithm is getting passed different parameters resulting in different return values.
The change to use ISO-8859-1 on the C# side is easy:
byte[] buffer = Encoding.GetEncoding(28591).GetBytes(file_or_text);
However, both this and ASCII will lose data if your text contains Unicode characters above U+00FF.
Ideally if your source data is genuinely text, you should use an encoding which will cope with anything (e.g. UTF-8) and if your source data is actually binary, you shouldn't be going through text encoding at all.
Try the following code:
public static string Sha1encode(string toEncrypt) {
// Produce an array of bytes which is the SHA1 hash
byte[] sha1Signature = new byte[40];
byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt);
SHA1 sha1 = SHA1Managed.Create();
sha1Signature = sha1.ComputeHash(sha);
// The BASE64 encoding standard's 6-bit alphabet, from RFC 1521,
// plus the padding character at the end.
char[] Base64Chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '+', '/', '=' };
// Algorithm to encode the SHA1 hash using Base64
StringBuilder sb = new StringBuilder();
int len = sha1Signature.Length;
int i = 0;
int ival;
while (len >= 3) {
ival = ((int) sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int) sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int) sha1Signature[i++] + 256) & 0xff;
len -= 3;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[(ival >> 6) & 63]);
sb.Append(Base64Chars[ival & 63]);
}
switch (len) {
case 0: // No pads needed.
break;
case 1: // Two more output bytes and two pads.
ival = ((int) sha1Signature[i++] + 256) & 0xff;
ival <<= 16;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[64]);
sb.Append(Base64Chars[64]);
break;
case 2: // Three more output bytes and one pad.
ival = ((int) sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int) sha1Signature[i] + 256) & 0xff;
ival <<= 8;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[(ival >> 6) & 63]);
sb.Append(Base64Chars[64]);
break;
}
string base64Sha1Signature = sb.ToString();
return base64Sha1Signature;
}
Related
I was wondering those differences, since I have a program that asks me for a byte[].
public static string DecryptTextFromFile(String FileName, byte[] Key, byte[]
IV){}
enter image description here
and I have already tried:
char[] key= { '9', 'D', '2', 'A', 'E'}; doesn't give an error but I need byte[]
and this:
byte[] key= { '9', 'D', '2', 'A', 'E'}; // but this one says that I am using char characters, how do I put them in byte[] format?.
You can initialize a byte array like :
byte[] key1 = new byte[] { 57, 68, 50, 65, 69 };
Or convert from Char Array :
char[] keyChars = { '9', 'D', '2', 'A', 'E' };
var key2 = Encoding.ASCII.GetBytes(keyChars);
The char and byte are two different types, char size is 16 bit and byte size is 8 bit;
To represent a char you need to convert to bytes.
To do that you can use BitConverter
char charValue = 'c';
bytep[] bytes = BitConverter.GetBytes(charValue);
To convert your string from the picture you can use this method
static class HexStringConverter
{
public static byte[] ToByteArray(String HexString)
{
int NumberChars = HexString.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
{
bytes[i / 2] = Convert.ToByte(HexString.Substring(i, 2), 16);
}
return bytes;
}
}
Hope this answer will help you
I'm rewriting this stopwatch code from C# to C++.
I have rewritten some of the code (I can attach it if you think it's helpful) but confused about the lines after var watch = Stopwatch.StartNew(). Does C++ have similar things like this? What kind of variable type should I put for watch in C++?
namespace BruteForcePasswordGeneration
{
class Program
{
static void Main(string[] args)
{
char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
int passwordLength=0;
Console.WriteLine("Enter the password length");
passwordLength = Convert.ToInt32(Console.ReadLine());
BigInteger iPossibilities = (BigInteger)Math.Pow((double)chars.Length, (double)passwordLength);
Console.WriteLine("{0} words total. Press enter to continue;", iPossibilities);
Console.ReadLine();
var watch = Stopwatch.StartNew();
for (BigInteger i = 0; i < iPossibilities; i++)
{
string theword = "";
BigInteger val = i;
for (int j = 0; j < passwordLength; j++)
{
BigInteger ch = val % chars.Length;
theword = chars[(int)ch] + theword;
val = val / chars.Length;
}
Console.WriteLine(theword);
}
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Console.WriteLine("It took {0} seconds to generate {1} possible combinations", elapsedMs / 1000, iPossibilities);
Console.ReadLine();
}
}
}
Although you can write a "stopwatch" class in C++ if you want, the usual is to just use high_resolution_clock::now() to get the start and stop times. You then use duration_cast to get the difference in the form you want.
If you'll forgive me, I don't see any real point in requiring the user to enter the password length after starting the program. At least to me, it seems easier to use something like "gen_passwords 4" to generate all the passwords of length 4.
That gives code something on this general order:
#include <iostream>
#include <chrono>
#include <string>
int main(int argc, char **argv) {
static const std::string chars{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
if (argc != 2) {
std::cerr << "Usage: generate <password length>\n";
return EXIT_FAILURE;
}
int passwordLength = std::stoi(argv[1]);
unsigned long long iPossibilities = std::pow(chars.size(), passwordLength);
using namespace std::chrono;
auto start = high_resolution_clock::now();
for (unsigned long long i = 0; i < iPossibilities; i++) {
std::string theword;
unsigned long long val = i;
for (int j = 0; j < passwordLength; j++) {
size_t ch = val % chars.size();
theword = chars[ch] + theword;
val /= chars.size();
}
std::cout << theword << '\n';
}
auto stop = high_resolution_clock::now();
double elapsed = duration_cast<milliseconds>(stop - start).count() / 1000.0;
std::cerr << "It took " << elapsed << " seconds to generate " << iPossibilities << " combinations\n";
}
I'm trying to convert a code from C++ to C#, but I'm not being able to do it...
std::string Cipher(std::string Str)
{
char Key[5] = { 'H', 'S', 'M', 'K', 'V' };
std::string Encrypted = Str;
for (unsigned int i = 0; i < Str.size(); i++)
{
Encrypted[i] = Str[i] ^ Key[i % (sizeof(Key) / sizeof(char))];
}
return Encrypted;
}
What I got so far in C# is this:
public string Cipher(string Str)
{
char[] Key = new char[5] { 'H', 'S', 'M', 'K', 'V' };
string Encrypted = Str;
for(int i = 0; i < Str.Length; i++)
{
Encrypted[i] = Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]; //line 29
}
return Encrypted;
}
But I keep getting this error:
Property or indexer 'string.this[int]' cannot be assigned to -- it is read only (on line 29)
I found out that it has something to do with immutability of strings, so I tried this:
public string Cipher(string Str)
{
char[] Key = new char[5] { 'H', 'S', 'M', 'K', 'V' };
string Encrypted = Str;
StringBuilder sb = new StringBuilder(Encrypted);
for (int i = 0; i < Str.Length; i++)
{
sb[i] = Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]; //line 30
}
return Encrypted;
}
But, now I get this error:
Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?) (on line 30)
Anyone can help?
Thanks
Close! You are right to use StringBuilder. However, ^ -operator (bitwise XOR) makes C# intepret the result as int. Since you know it's still a char, just add cast:
for (int i = 0; i < Str.Length; i++)
{
sb[i] = (char)(Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]); //line 30
}
Othewise I'm not sure if this does exactly the same as C++ implementation. (sizeof(Key) / sizeof(char) is basically the length of the array. So you should just use Key.length at C# implementation. So a bit more accurate one would be
for (int i = 0; i < Str.Length; i++)
{
sb[i] = (char)(Str[i] ^ Key[i % Key.Length]); //line 30
}
Replace
Encrypted[i] = Str[i] ^ Key[i % ((Marshal.SizeOf(Key)) / sizeof(char))]; //line 29
with
Encrypted[i] = Str[i] ^ Key[i % Key.Lenght]; //line 29
And you can replace characters in a string with:
"1234567890123".Remove(9,1).Insert(9,"A")
Using a string builder is a smarter choice though.
I'm trying to upload a Base64 image string from iOS (using NSData+Base64) to MVC .Net. The upload is ok, but when I try to convert string back to Image, an exception is thrown at line:
byte[] imageBytes = Convert.FromBase64String(imageString);
Exception: "Invalid length for a Base-64 char array"
The imageString length converted in iOS is 944062.
To verify the length, I converted the same image in .Net using
string fota = ImageToBase64(Image.FromFile(#"C:\PR\Source\Servicea\bin\Imag043.jpg"), System.Drawing.Imaging.ImageFormat.Jpeg);
and the size was 203956. And the original image file size is 156,967.
Both methods shouldn't convert the image returning the same string? Anybody had this problem before? Tks
Update: After many tests, I decided to use ASIHTTPRequest lib. Tks all.
Try using this:
#import <CommonCrypto/CommonDigest.h>
#include <stdlib.h>
static char base64EncodingTable[64] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
+ (NSString *) base64StringFromData: (NSData *)data length: (int)length {
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1)
return #"";
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0)
break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext)
input[i] = raw[ix];
else
input[i] = 0;
}
output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
[result appendString: [NSString stringWithFormat: #"%c", base64EncodingTable[output[i]]]];
for (i = ctcopy; i < 4; i++)
[result appendString: #"="];
ixtext += 3;
charsonline += 4;
if ((length > 0) && (charsonline >= length))
charsonline = 0;
}
return result;
}
I am trying to calculate a SHA-1 Hash from a string, but when I calculate the string using php's sha1 function I get something different than when I try it in C#. I need C# to calculate the same string as PHP (since the string from php is calculated by a 3rd party that I cannot modify). How can I get C# to generate the same hash as PHP? Thanks!!!
String = s934kladfklada#a.com
C# Code (Generates d32954053ee93985f5c3ca2583145668bb7ade86)
string encode = secretkey + email;
UnicodeEncoding UE = new UnicodeEncoding();
byte[] HashValue, MessageBytes = UE.GetBytes(encode);
SHA1Managed SHhash = new SHA1Managed();
string strHex = "";
HashValue = SHhash.ComputeHash(MessageBytes);
foreach(byte b in HashValue) {
strHex += String.Format("{0:x2}", b);
}
PHP Code (Generates a9410edeaf75222d7b576c1b23ca0a9af0dffa98)
sha1();
Use ASCIIEncoding instead of UnicodeEncoding. PHP uses ASCII charset for hash calculations.
This method in .NET is equivalent to sha1 in php:
string sha1Hash(string password)
{
return string.Join("", SHA1CryptoServiceProvider.Create().ComputeHash(Encoding.UTF8.GetBytes(password)).Select(x => x.ToString("x2")));
}
I had this problem also. The following code will work.
string dataString = "string to hash";
SHA1 hash = SHA1CryptoServiceProvider.Create();
byte[] plainTextBytes = Encoding.ASCII.GetBytes(dataString);
byte[] hashBytes = hash.ComputeHash(plainTextBytes);
string localChecksum = BitConverter.ToString(hashBytes)
.Replace("-", "").ToLowerInvariant();
Had the same problem. This code worked for me:
string encode = secretkey + email;
SHA1 sha1 = SHA1CryptoServiceProvider.Create();
byte[] encodeBytes = Encoding.ASCII.GetBytes(encode);
byte[] encodeHashedBytes = sha1.ComputeHash(passwordBytes);
string pencodeHashed = BitConverter.
ToString(encode HashedBytes).Replace("-", "").ToLowerInvariant();
FWIW, I had a similar issue in Java. It turned out that I had to use "UTF-8" encoding to produce the same SHA1 hashes in Java as the sha1 function produces in PHP 5.3.1 (running on XAMPP Vista).
private static String SHA1(final String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
final MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(text.getBytes("UTF-8"));
return new String(org.apache.commons.codec.binary.Hex.encodeHex(md.digest()));
}
Try The following! I think it will work great:
public static string SHA1Encodeb64(string toEncrypt)
{
//Produce an array of bytes which is the SHA1 hash
byte[] sha1Signature = new byte[40];
byte[] sha = System.Text.Encoding.Default.GetBytes(toEncrypt);
SHA1 sha1 = SHA1Managed.Create();
sha1Signature = sha1.ComputeHash(sha);
/**
* The BASE64 encoding standard's 6-bit alphabet, from RFC 1521,
* plus the padding character at the end.
*/
char[] Base64Chars = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
'='
};
//Algorithm to encode the SHA1 hash using Base64
StringBuilder sb = new StringBuilder();
int len = sha1Signature.Length;
int i = 0;
int ival;
while (len >= 3)
{
ival = ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int)sha1Signature[i++] + 256) & 0xff;
len -= 3;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[(ival >> 6) & 63]);
sb.Append(Base64Chars[ival & 63]);
}
switch (len)
{
case 0: // No pads needed.
break;
case 1: // Two more output bytes and two pads.
ival = ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 16;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[64]);
sb.Append(Base64Chars[64]);
break;
case 2: // Three more output bytes and one pad.
ival = ((int)sha1Signature[i++] + 256) & 0xff;
ival <<= 8;
ival += ((int)sha1Signature[i] + 256) & 0xff;
ival <<= 8;
sb.Append(Base64Chars[(ival >> 18) & 63]);
sb.Append(Base64Chars[(ival >> 12) & 63]);
sb.Append(Base64Chars[(ival >> 6) & 63]);
sb.Append(Base64Chars[64]);
break;
}
//Encode the signature using Base64
string base64Sha1Signature = sb.ToString();
return base64Sha1Signature;
}