base64_encode(pack("H*",$sha1Signature)) to C# - c#

$sha1Signature = sha1($toEncrypt)
//This will give b14dcc7842a53f1ec7a621e77c106dfbe8283779
$base64Sha1Signature = base64_encode(pack("H*",$sha1Signature));
//This will give sU3MeEKlPx7HpiHnfBBt++goN3k=
My code is calculating SHA1 and displaying the required :
b14dcc7842a53f1ec7a621e77c106dfbe8283779
but Base 64 Encode Result is different. When I send
"b14dcc7842a53f1ec7a621e77c106dfbe8283779" to the following function it gives
"ZmVkMzg5ZjJlNjM0ZmE2YjYyYmRmYmZhZmQwNWJlNzYxMTc2Y2VlOQ==" but I want it to be
"sU3MeEKlPx7HpiHnfBBt++goN3k=".
my code :
string toEncrypt = password+merchantID.Value.ToString()+acquirerID.Value.ToString()+orderID.Value.ToString()+formattedPurchaseAmt1+currency.Value.ToString();
SHA1 sha1Hash = SHA1.Create();
//From String to byte array
byte[] sourceBytes = Encoding.UTF8.GetBytes(toEncrypt);
byte[] hashBytes = sha1Hash.ComputeHash(sourceBytes);
string hash = BitConverter.ToString(hashBytes).Replace("-", String.Empty);
SHA1 sha = new SHA1Managed();
string base64Sha1Signature1 = Convert.ToBase64String(Encoding.UTF8.GetBytes(hash));

Related

Equivalent from PHP hash_hmac("sha384", $data, $key) in .NET

In PHP i do following steps:
<?php
$key="mM8Y28b5R7KFe3Y5";
$data="298052380sbEUREinzellizenz Spieler SEN329739test120211572380R-00001003authorization19";
$hash=hash_hmac("sha384", $data, $key);
echo $hash;
?>
i get following output:
f34fb28f6462cde18a92ee854d289ba5aed3cfc07d0abb52cfef3b70028e1b38b098ae17514a9121d43d3d6f684eccd8
I try to do this in .NET with:
string data = "298052380sbEUREinzellizenz Spieler SEN329739test120211572380R-00001003authorization19";
string key = "mM8Y28b5R7KFe3Y5";
string hash = "";
using (SHA384 sha384Hash = SHA384.Create())
{
byte[] sourceBytes = Encoding.ASCII.GetBytes(data);
byte[] hashBytes = sha384Hash.ComputeHash(sourceBytes);
hash = BitConverter.ToString(hashBytes).Replace("-", String.Empty).ToLower();
}
and i get
77b7eccd4f66b07c66e2c49b83e53bf84dfd4dc67ec60007df4476adfe16d9b0bfdd6e58e9a5008bde4908335d161ef5
i tried also:
var keyByte = Encoding.ASCII.GetBytes(key);
using (HMACSHA256 sha384Hash = new HMACSHA256(keyByte))
{
byte[] sourceBytes = Encoding.ASCII.GetBytes(data);
byte[] hashBytes = sha384Hash.ComputeHash(sourceBytes);
hash2 = BitConverter.ToString(hashBytes).Replace("-", String.Empty).ToLower();
}
hash2 is
ceaabe254e19d77940ac3edfdf2fa3d1de424d569136e8deb770aa81be5cb24a
i don't get the difference. I checked already the Encodings, but i see no differents.
What i am doing wrong?
use the second example but with
using (HMACSHA384 sha384Hash = new HMACSHA384(Encoding.ASCII.GetBytes(key)))

SHA3 CryptoJS equivalent in C#

I have data encrypted with CryptoJS using SHA3 like this example. I try to write in C# using SHA3.NET, a BouncyCastle wrapper.
using (var shaAlg = SHA3.Net.Sha3.Sha3512())
{
var hash = shaAlg.ComputeHash(Encoding.UTF8.GetBytes(data));
var hashString = BitConverter.ToString(result).Replace("-", "").ToLowerInvariant();
}
Using the BouncyCastle directly generates the same result as above (not matched CryptoJS).
var hashAlgorithm = new Org.BouncyCastle.Crypto.Digests.Sha3Digest(512);
byte[] input = Encoding.ASCII.GetBytes(data);
hashAlgorithm.BlockUpdate(input, 0, input.Length);
byte[] result = new byte[64];
hashAlgorithm.DoFinal(result, 0);
string hashString = BitConverter.ToString(result).Replace("-", "").ToLowerInvariant();
When passing data parameter abc the result should be 18587dc2ea106b9a1563e32b3312421ca164c7f1f07bc922a9c83d77cea3a1e5d0c69910739025372dc14ac9642629379540c17e2a65b19d77aa511a9d00bb96 but the result is b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0

Invalid padding error when using AesCryptoServiceProvider in C#

I've written a simple encryp/decrypt method in c# which uses the AES alg. When I try to encrypt and then decrypt a string with certain lengths like 4 or 7 characters, it works fine, with other lengths however It says that the padding is invalid and cannot be removed.
public static string Decrypt(string text)
{
Aes a = System.Security.Cryptography.AesCryptoServiceProvider.Create();
a.Padding = PaddingMode.PKCS7;
a.Key = Convert.FromBase64String("UDlArN63HCk15fHBski/zvaWiMZJi+jR1BADvVgenCU=");
a.IV = Convert.FromBase64String("xZG/eLY8eq0mQhUXvKbUDQ==");
var dc = a.CreateDecryptor();
byte[] encryptedBytes = Encoding.Unicode.GetBytes(text);
byte[] decryptedBytes = dc.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
return Encoding.Unicode.GetString(decryptedBytes);
}
public static string Encrypt(string text)
{
Aes a = System.Security.Cryptography.AesCryptoServiceProvider.Create();
a.Padding = PaddingMode.PKCS7;
a.Key = Convert.FromBase64String("UDlArN63HCk15fHBski/zvaWiMZJi+jR1BADvVgenCU=");
a.IV = Convert.FromBase64String("xZG/eLY8eq0mQhUXvKbUDQ==");
var dc = a.CreateEncryptor();
byte[] decryptedBytes = Encoding.Unicode.GetBytes(text);
byte[] encryptedBytes = dc.TransformFinalBlock(decryptedBytes, 0, decryptedBytes.Length);
return Encoding.Unicode.GetString(encryptedBytes);
}
Ciphertexts are binary data which might contain bytes that are not printable. If try to encode the byte array as a Unicode string, you will lose some bytes. It will be impossible to recover them during decryption.
If you actually want to handle the ciphertext as a string, you need to convert it into a textual representation like Base 64 or Hex.
// encryption
return Convert.ToBase64String(decryptedBytes);
// decryption
byte[] decryptedBytes = Convert.FromBase64String(text);

InCorrect output using Rfc2898DeriveBytes for password hashing

I am certainly sure i am doing something wrong here. Using .net implementation of the algorithm i hash the password to store in database along with the salt used to hash. On validating the same password with the existing hash does not match.Here is my code
New Entry
byte[] SALT = GetRandomKey();
string password = Convert.ToBase64String((new Rfc2898DeriveBytes(txtPassword.Text, SALT)).GetBytes(20));
Session["test"] = password;
Session["salt"] = Convert.ToBase64String(SALT);
Validating
string HASHEDPASSWORD = Session["test"];
string SALT = Session["salt"];
string ouput = Convert.ToBase64String((new Rfc2898DeriveBytes(password, Encoding.Unicode.GetBytes(SALT))).GetBytes(20));
ltrResult.Text = HASHEDPASSWORD.Equals(ouput) ? "EQUAL" : "NOT EQUAL";
Get RandomKey method
byte[] GetRandomKey()
{
byte[] secretkey = new Byte[64];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetBytes(secretkey);
return secretkey;
}
Or Convert.FromBase64String instead of Encoding.Unicode.GetBytes.
You use Convert.ToBase64String when adding items, and Encoding.Unicode.GetBytes when retrieving it...
Use Encoding.Unicode.GetString when adding a new entry and your code should work, eg:
private static string GetString(byte[] bytes)
{
return Encoding.Unicode.GetString(bytes);
}
private static byte[] GetBytes(string value)
{
return Encoding.Unicode.GetBytes(value);
}
Adding
byte[] salt = GetRandomKey();
byte[] hash = new Rfc2898DeriveBytes(txtPassword.Text, salt)).GetBytes(20);
Session["test"] = GetString(hash);
Session["salt"] = GetString(salt);
Checking
byte[] hash = GetBytes(Session["test"]);
byte[] salt = GetBytes(Session["salt"]);
byte[] output = new Rfc2898DeriveBytes(password, salt).GetBytes(20);
ltrResult.Text = GetString(hash).Equals(GetString(output)) ? "EQUAL" : "NOT EQUAL";
You could store the salt as array of bytes in the session so that you don't get any differences of encoding when converting between strings and bytes:
byte[] SALT = GetRandomKey();
string password = Convert.ToBase64String((new Rfc2898DeriveBytes(txtPassword.Text, SALT)).GetBytes(20));
Session["test"] = password;
Session["salt"] = SALT;
and then to verify that a given password matches the hash you repeat the same procedure:
string HASHEDPASSWORD = Session["test"];
byte[] SALT = Session["salt"] as byte[];
string ouput = Convert.ToBase64String((new Rfc2898DeriveBytes(password, SALT)).GetBytes(20));
ltrResult.Text = HASHEDPASSWORD.Equals(ouput) ? "EQUAL" : "NOT EQUAL";

Converting Byte[] to String to Byte[] - RSA Encryption C#

If I give the decrypter RSAalg2.Decrypt(encryptedData, false); it works fine but I need to convert the encrypted data (byte array) to a string then back to a byte array.
I've tried ASCIIEncoding, UTF-8 rather than Unicode with no luck. I'd appreciate any help I can get. Thanks
UnicodeEncoding ByteConverter = new UnicodeEncoding();
string dataString = "Test";
byte[] dataToEncrypt = ByteConverter.GetBytes(dataString);
byte[] encryptedData;
byte[] decryptedData;
RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider();
Console.WriteLine("Original Data: {0}", dataString);
encryptedData = RSAalg.Encrypt(dataToEncrypt, false);
Console.WriteLine("Encrypted Data: {0}", ByteConverter.GetString(encryptedData));
String XML = RSAalg.ToXmlString(true);
XmlDocument doc = new XmlDocument();
doc.LoadXml(XML);
doc.Save(Environment.CurrentDirectory + "\\key.xml");
RSACryptoServiceProvider RSAalg2 = new RSACryptoServiceProvider();
StreamReader sr2 = File.OpenText(Environment.CurrentDirectory + "\\key.xml");
string rsaXml2 = sr2.ReadToEnd();
sr2.Close();
RSAalg2.FromXmlString(rsaXml2);
string s = ByteConverter.GetString(encryptedData);
byte[] se = ByteConverter.GetBytes(s);
decryptedData = RSAalg2.Decrypt(se, false);
Console.WriteLine("Decrypted plaintext: {0}", ByteConverter.GetString(decryptedData));
The code below demonstrates what you are after.
[Test]
public void RsaEncryptDecryptDemo()
{
const string str = "Test";
var rsa = new RSACryptoServiceProvider();
var encodedData = rsa.Encrypt(Encoding.UTF8.GetBytes(str), false);
var encodedString = Convert.ToBase64String(encodedData);
var decodedData = rsa.Decrypt(Convert.FromBase64String(encodedString), false);
var decodedStr = Encoding.UTF8.GetString(decodedData);
Assert.AreEqual(str, decodedStr);
}
The trick is to convert your byte array into a form that can be represented as a string. To that effect, the example above utilizes Base64 encoding and decoding.

Categories