SHA3 CryptoJS equivalent in C# - 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

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)))

base64_encode(pack("H*",$sha1Signature)) to 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));

How to handle encrypt and decrypt file in ASP.NET core web API

What is the best way to implement encrypt and decrypt file content using asp.net core web API?
It should be compatible with the swagger also. I have tried this the same way as encrypt a string, but there is a limitation of size length or incomplete file sent over API.
I require to encrypt at the client end before API call via swagger or postman and be decrypt at service end.
File content encrypts at the client end then only data at transmission will safe.
I have tried below
public static string encrypt(string PlainText, byte[] key, byte[] iv)
{
string sR = string.Empty;
byte[] plainBytes = Encoding.UTF8.GetBytes(PlainText);
GcmBlockCipher cipher = new GcmBlockCipher(new AesFastEngine());
AeadParameters parameters =
new AeadParameters(new KeyParameter(key), 128, iv, null);
cipher.Init(true, parameters);
byte[] encryptedBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
Int32 retLen = cipher.ProcessBytes
(plainBytes, 0, plainBytes.Length, encryptedBytes, 0);
cipher.DoFinal(encryptedBytes, retLen);
sR = Convert.ToBase64String(encryptedBytes, Base64FormattingOptions.None);
return sR;
}
You can take a look at this link: https://github.com/2Toad/Rijndael256/issues/13#issuecomment-637724412
It uses the Rijndael/AES cypher to encrypt the data you put in.
In the Github issue you will find the following code:
public static class CipherHelper
{
// This constant is used to determine the keysize of the encryption algorithm in bits.
// We divide this by 8 within the code below to get the equivalent number of bytes.
private const int Keysize = 256;
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
public static string Encrypt(string plainText, string passPhrase)
{
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
// so that the same Salt and IV values can be used when decrypting.
var saltStringBytes = Generate256BitsOfRandomEntropy();
var ivStringBytes = Generate256BitsOfRandomEntropy();
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
cipher.Init(true, keyParamWithIV);
var comparisonBytes = new byte[cipher.GetOutputSize(plainTextBytes.Length)];
var length = cipher.ProcessBytes(plainTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
// return Convert.ToBase64String(comparisonBytes);
return Convert.ToBase64String(saltStringBytes.Concat(ivStringBytes).Concat(comparisonBytes).ToArray());
}
}
public static string Decrypt(string cipherText, string passPhrase)
{
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
var engine = new RijndaelEngine(256);
var blockCipher = new CbcBlockCipher(engine);
var cipher = new PaddedBufferedBlockCipher(blockCipher, new Pkcs7Padding());
var keyParam = new KeyParameter(keyBytes);
var keyParamWithIV = new ParametersWithIV(keyParam, ivStringBytes, 0, 32);
cipher.Init(false, keyParamWithIV);
var comparisonBytes = new byte[cipher.GetOutputSize(cipherTextBytes.Length)];
var length = cipher.ProcessBytes(cipherTextBytes, comparisonBytes, 0);
cipher.DoFinal(comparisonBytes, length);
//return Convert.ToBase64String(saltStringBytes.Concat(ivStringBytes).Concat(comparisonBytes).ToArray());
var nullIndex = comparisonBytes.Length - 1;
while (comparisonBytes[nullIndex] == (byte)0)
nullIndex--;
comparisonBytes = comparisonBytes.Take(nullIndex + 1).ToArray();
var result = Encoding.UTF8.GetString(comparisonBytes, 0, comparisonBytes.Length);
return result;
}
}
private static byte[] Generate256BitsOfRandomEntropy()
{
var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
using (var rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with cryptographically secure random bytes.
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
}
To make this code work, you will need to install the BouncyCastle.NetCore NuGet package.
This code helps you to encrypt and decrypt a string by using a password.
In your case, if you somehow now the password at both sides of the request (send-side and receive-side) than this should be able to work.

Compatibility between AesJS and C# System.Security.Cryptography

I'm developing an application in NodeJS that consums a C# API. And I want to implement securized calls with AES. I'm using AesJS in NodeJS and System.Security.Cryptography in C#.
The C# part is used in other parts of the application and works correctly, so I'm guessing my error is in the NodeJS part.
The error is:
Invalid length for a Base-64 char array or string.
My code:
NodeJS
encryptData = function(data) {
var key = pbkdf2.pbkdf2Sync(config.aes.pass, config.aes.salt, 1, 128 / 8, null);
var dataBytes = aesjs.utils.utf8.toBytes(data);
var ivBytes = aesjs.utils.utf8.toBytes(config.aes.iv);
var aesOfb = new aesjs.ModeOfOperation.ofb(key, ivBytes);
var encryptedBytes = aesOfb.encrypt(dataBytes);
var encryptedHex = aesjs.utils.hex.fromBytes(encryptedBytes);
return encryptedHex;
}
C#
public static string DecodeAndDecrypt(string encrypted)
{
using (var csp = Aes.Create())
{
var d = GetCryptoTransform(csp, false);
byte[] output = Convert.FromBase64String(encrypted);
byte[] decryptedOutput = d.TransformFinalBlock(output, 0, output.Length);
string decypted = Encoding.UTF8.GetString(decryptedOutput);
return decypted;
}
}
The error happens in this line:
byte[] output = Convert.FromBase64String(encrypted);
UPDATE
In order to test what's commented, I added parse to base64 in NodeJS:
return Buffer.from(encryptedHex).toString('base64');
Now I'm getting one step ahead into:
byte[] decryptedOutput = d.TransformFinalBlock(output, 0, output.Length);
And it returns error:
The input data is not a complete block.

Sha256 and Biginteger in java and C# are getting different values

Actually i have a java code whic i need to convert to c#
salt="40be4e59b9a2a2b5dffb918c0e86b3d75727a8f82b898d65cf87017309818b35f5c07a364ee3e7117730058065c1bad8a43491dc6549e17b6b0c85b144ada408ca7a1e8c7505e41f91e5d0f37996fa1dd54e68160fb44631f7d5cfec517bcacf4a8a0b2ed3321d881ce224060b4c22c6d97461595d6e8d604a1c41f646adb19c06f8398c1b8ceeb9d1f090aa67cfe5b31b0741a407e93c92e421f759d475e70cc306bb88f0678921eaaacf10da4f5cdada4d288514aae58c06ae5f752ae814e321d2dcbd5cf6e1621e6f154fc88d6cfe31bdc17d94595f038874ffaebad9656f3278b2694c439cbb263494b76b8b4ed81547aae71a98a722448fe11cd348d4f2e4123b42bac43c64b378914536e8b352";
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(salt.getBytes());
result=new BigInteger(messageDigest.digest());
result = -8679331902525424680818339047284551675590913508739318217139721412571178967790
and the c# code which i am using
rawData = "40be4e59b9a2a2b5dffb918c0e86b3d75727a8f82b898d65cf87017309818b35f5c07a364ee3e7117730058065c1bad8a43491dc6549e17b6b0c85b144ada408ca7a1e8c7505e41f91e5d0f37996fa1dd54e68160fb44631f7d5cfec517bcacf4a8a0b2ed3321d881ce224060b4c22c6d97461595d6e8d604a1c41f646adb19c06f8398c1b8ceeb9d1f090aa67cfe5b31b0741a407e93c92e421f759d475e70cc306bb88f0678921eaaacf10da4f5cdada4d288514aae58c06ae5f752ae814e321d2dcbd5cf6e1621e6f154fc88d6cfe31bdc17d94595f038874ffaebad9656f3278b2694c439cbb263494b76b8b4ed81547aae71a98a722448fe11cd348d4f2e4123b42bac43c64b378914536e8b352";
using ( SHA256 sha256Hash = SHA256.Create())
{
var Rawdatabytes = System.Text.Encoding.ASCII.GetBytes(rawData);
byte[] bytes = sha256Hash.ComputeHash(Rawdatabytes);
var result = new System.Numerics.BigInteger(bytes);
}
result = 8306751456257555796593622157661757526221618682565362023319192974333645213676
for both after converting to Biginteger getting different result
any guess?

Categories