Getting different encryption results between C#.Net and Oracle - c#

I want to encrypt some strings based on SHA1 algorithm in both C#.Net and Oracle 10g.
My algorithm in C#.Net:
string salt = "123";
System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
byte[] preHash = System.Text.Encoding.UTF32.GetBytes(salt);
byte[] hash = sha.ComputeHash(preHash);
string password = System.Convert.ToBase64String(hash);
password = password.Substring(0, 8);
// password value is: "7yP7/lkJ"
In Oracle:
Create Or Replace Function Sha1(P_Value Varchar2,P_Length Number) Return Varchar2
Is
P_String Varchar2(2000) := P_Value ;
L_Hash_Value_Raw Raw (100);
Lv_Hash_Value_Varchar Varchar2 (40);
Begin
L_Hash_Value_Raw := Dbms_Crypto.Hash (Src => Utl_Raw.Cast_To_Raw(P_String),
Typ => Dbms_Crypto.Hash_Sh1);
-- Convert Into Varchar2
Select Utl_Raw.Cast_To_Varchar2(Utl_Encode.Base64_Encode(L_Hash_Value_Raw))
Into Lv_Hash_Value_Varchar
From Dual;
Lv_Hash_Value_Varchar := Substr(Lv_Hash_Value_Varchar,0,P_Length);
Return Lv_Hash_Value_Varchar;
End;
Oracle's invokation:
select SHA1('123', 8) from dual; -- Result: "QLOAFWMI"
Maybe my general question is what is the difference between Oracle (PL/SQL) and .Net regarding encryption/raw/hex levels? I guess that answer would solve this specific problem.

you use wrong encoding. try the following code:
string salt = "123";
System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
byte[] preHash = System.Text.Encoding.UTF8.GetBytes(salt);
byte[] hash = sha.ComputeHash(preHash);
string password = System.Convert.ToBase64String(hash);
password = password.Substring(0, 8);

Related

Base64 Hash from PDF file different between C# and Delphi

I'm trying to generate a hash from a PDF. This hash should be SHA256 and Base64.
I'm using a simple PDF with one line with the content: Hello World.
With the C# code below I've got the result:
Gv5AR2YOxUVOjx+QFakM56Wj7CSqeZWiaVqczra/iBk=
string digest;
using (SHA256Managed sha = new SHA256Managed())
{
byte[] hash = sha.ComputeHash(pdf);
digest = Convert.ToBase64String(hash);
}
Then, using Delphi, with the code below, I've got this:
wPUoG1guk2hQ5TxS5lUmaMLk83E=
// uses IdCoderMIME, IdHashSHA, IdGlobal;
var
oHash: TIdHashSHA1;
oFileStream: TFileStream;
begin
oHash := TIdHashSHA1.Create;
oFileStream := TFileStream.Create(edtPDFPath.Text, fmOpenRead);
try
result := TIdEncoderMIME.EncodeBytes(oHash.HashStream(oFileStream, 0, oFileStream.Size));
finally
Freeandnil(oFileStream);
oHash.Free
end;
I need to hash this file with Delphi but I don't know if my result is right or not.
Someone knows another way to get as a result a SHA256 Base64 hash?
You can get same result as C# with following code
// uses System.Hash, System.NetEncoding;
Result := TNetEncoding.Base64.EncodeBytesToString(THashSHA2.GetHashBytes(oFileStream, THashSHA2.TSHA2Version.SHA256));

Getting issue when convert c# code to PHP as below

I am running this code:
var timeStamp = DateTime.UtcNow;
var sharedSecret = "xx";
var saltedString = timeStamp.ToString("2021-01-07T16:42:33.619667Z") + sharedSecret;
//Encoding saltedString using Unicode little-endian byte order
byte[] encodedSaltedString = Encoding.Unicode.GetBytes(saltedString);
//Hashing Algorithm used is SHA512
HashAlgorithm hash = new SHA512Managed();
//Compute Hash of encodedSaltedString
byte[] hashedEncodedString = hash.ComputeHash(encodedSaltedString);
//Convert hashed array to base64-encoded string
string signature = Convert.ToBase64String(hashedEncodedString);
I am then getting this result in C#:
"gQhjrLnY6fo44EeaaWaUBE1PY/8oEIRsUcK3AMSCVUCYMM4vRfxvQEEggXaHTF0GQbw4w2HbWArX1k6NnkzJFg=="
I converted to this code as below, but I am getting an issue. Can I get some help on this?
$timestamp = "2021-01-07T16:42:33.619667Z";
$sharedSecret = 'xx';
$saltedString = $timestamp.$sharedSecret;
$utf=mb_convert_encoding($saltedString, "UTF-16LE");
$signature = base64_encode(hash('sha512', $utf));
IN PHP I am getting this result:
ODEwODYzYWNiOWQ4ZTlmYTM4ZTA0NzlhNjk2Njk0MDQ0ZDRmNjNmZjI4MTA4NDZjNTFjMmI3MDBjNDgyNTU0MDk4MzBjZTJmNDVmYzZmNDA0MTIwODE3Njg3NGM1ZDA2NDFiYzM4YzM2MWRiNTgwYWQ3ZDY0ZThkOWU0Y2M5MTY=
But both should be same. The c# one is correct, I want the same in the php code as well.
From the PHP docs for hash:
hash ( string $algo , string $data , bool $binary = false ) : string|false
binary
   When set to true, outputs raw binary data. false outputs lowercase hexits.
You're not passing a value for $binary, so it's returning a string of hexadecimal characters.
The C# HashAlgorithm.ComputeHash method on the other hand binary data.
Since you're base64-encoding the result, you're presumably expecting the hash function to return binary data. You therefore need to pass true as the value for $binary:
$signature = base64_encode(hash('sha512', $utf, true));

C# Hash SHA256Managed is not equal to TSQL SHA2_256

I am using hashed passwords with a salt (the username).
Problem is that the hashed values of c# are not equal to the initial values I add to the database by a TSQL Script.
TSQL:
UPDATE [Users]
SET Password = HASHBYTES('SHA2_256', 'test123'+UPPER([UserName]))
GO;
C#:
var passBytes = new UnicodeEncoding().GetBytes(pass);
var saltBytes = new UnicodeEncoding().GetBytes(userName.ToUpper());
var dataToHash = new byte[passBytes.Length + saltBytes.Length];
Array.Copy(passBytes, dataToHash, passBytes.Length);
Array.Copy(saltBytes, dataToHash, saltBytes.Length);
var sha = new SHA256Managed();
return sha.ComputeHash(dataToHash);
I guess it has something to do with the encoding.
But i have no idea how to fix this.
UserName is varchar(50)
The DB is an existing one so changing the varchar will not be so easy.
I already tried:
UPDATE [Users]
SET Password = HASHBYTES('SHA2_256', N'test123'+UPPER([UserName]))
GO;
After struggling to get this to work, here is a sample of what I finally got to work:
public string Hash(string input)
{
using (SHA256 hasher = SHA256.Create())
{
// Convert the input string to a byte array and compute the hash.
byte[] data = hasher.ComputeHash(Encoding.Unicode.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("X2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
TSQL
declare #input as nvarchar(max) = 'Test';
select #input;
declare #hash as varbinary(max) = HASHBYTES('SHA2_256', #input );
select #hash;
declare #result as nvarchar(max) = CONVERT(NVARCHAR(MAX), #hash, 2);
select #result;
These will produce identical results.
Note that this is using a nvarchar datatype, not a varchar.
If your SQL Server database is configured to use the default collation of SQL_Latin1_General_CP1_CI_AS, then in your C# code, use code page 1252 to convert characters to bytes. Thus, the equivalent of
HASHBYTES('SHA2_256', 'test123' + UPPER([UserName]))
is
byte[] data = Encoding.GetEncoding(1252).GetBytes("test123" + userName.ToUpper());
var sha = new SHA256Managed();
byte[] hash = sha.ComputeHash(data);
Hashes work on bytes, not on characters. What you're doing is Hash(StringToBytes(str)). Your StringToBytes step is different. In SQL you are using ANSI varchar strings and in C# UTF-16 strings. Decide which one you want and use that. I recommend Unicode (nvarchar).
Encoding.UTF8.GetBytes(input) = HASHBYTES('SHA2_256', #varcharVariable);
Encoding.Unicode.GetBytes(input) = HASHBYTES('SHA2_256', #nvarcharVariable);

How to store hashed password in database

I am trying to store hashed password in sql express database. but I am not able to do that one.
Here is my code:
SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
byte[] encode = sha.ComputeHash(Encoding.ASCII.GetBytes(pass));
string cmd = "insert into tblLogin (username,password,email,state,active) values ('"+name+"',"+encode+",'"+email+"','"+state +"',"+ active + ")" ;
And in database I kept password as varbinary.
Here my problem is I am getting value of encode as System.Byte[] but not hashed value.
How can I do this, I tried to find and I am getting how to hash password but not how to store password.
Here my main problem is How can I construct Insert query and store Byte[] into database?
Save it as a varchar, not varbinary.
var provider = new SHA1CryptoServiceProvider(salt);
byte[] bytes = Encoding.UTF8.GetBytes(input);
string result = Convert.ToBase64String(provider.ComputeHash(bytes)); // store it

UTF8 encoded password Byte[] with SHA512 encryption to string conversion

I have created a web form in c# that accepts username and password and stores password in MSSQL 2005 db in 'image' format. The password is merged with salt, encoded in UTF8 and lastly it is applied with a SHA512 encryption. I want to be able to see the passwords in string format when I pull them up back from the database. How should my decrypt function be, if the following is how I encrypted the password? Is that possible? :
string loginID = "";//This will be stored in varchar format in MSSQL..(Unrelated to the question)
string password =""; //This is where I store password inputted by user.
Random r = new Random();
int salt = r.Next((int)Math.Pow(2, 16));
int verifyCode = r.Next((int)Math.Pow(2, 16));
string tmpPwd = password.ToLower() + salt.ToString();
UTF8Encoding textConverter = new UTF8Encoding();
byte[] passBytes = textConverter.GetBytes(tmpPwd);
byte[] hashedPWD = new SHA512Managed().ComputeHash(passBytes);
The value in hashedPWD is stored in MSSQL as image datatype and salt is stored as int.
You can't - that's what a hash function is, by definition - a one-way function. Up until the last line, you can get the password back, but after the hash function, all you can do is generate a second hash and compare the two to see if they've produced the same result, in which case you can presume that the source strings were the same.

Categories

Resources