Difference between C# cryptoSha256 and HashLib Sha256 - asp.net

Good morning,
I need to Encryption a file in a Hash mode.
I look this library to use
HashLibrary
My Test with local C# 256 Method and HashLib Method get Differents Results,
FileStream fileStream;
SHA256 sha256 = SHA256Managed.Create();
fileStream = new FileStream(localPath, FileMode.Open);
fileStream.Position = 0;
///using System.Security.Cryptography;
byte[] hashValue = sha256.ComputeHash(fileStream);
string hash = ByteArrayToString(hashValue);
#region using HashLib;
//Run Hash
IHash hash256 = HashFactory.Crypto.CreateSHA256();
HashResult result256 = hash256.ComputeStream(fileStream);
byte[] bytearray = result256.GetBytes();
string stringtest = result256.ToString();
stringtest = result256.ToString().Replace("-", "");
#endregion
Result of First Method
byte[] hashValue = 94,171,27,169,32,82,120,2,177,84,58,6,216,77,110,239,85,282,75,159,183,85,70,208,22,146,201,22,47,122,153,74
string hash = 5EAB1BA920527802B1543A06D84D6EEF55FC4B9FB75546D01692C9162F7A994A
Result of Second Method with HashLib
var bytearray = 227,176,196,66,152,252,28,20,154,251,244,200,153,11,185,36,39,174,65,228,100,155,147,76,164,149,153,27,120,82,184,85
var stringtest = E3B0C442-98FC1C14-9AFBF4C8-996FB924-27AE41E4-649B934C-A495991B-7852B855
Someone can help me? i dont understand what is the problem, why result are differents?.
I start to use this library becouse i cant sha224, sha1 with System.Security.Cryptography

You already have read everything from the stream, so you're at the end of the stream. Recreate it to perform the testing. The second string is the well known hash over an empty array (aka nuthin').
Sometimes it is easy to check your output against well known tools such as sha256sum. For instance, the empty array can be tested like this, given a normal *nix shell (e.g. Cygwin or the Windows Subsystem for Linux I suppose):
$ dd count=0 status=none | sha256sum -b | awk '{print $1}'
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Related

Digital Signature Verification failed using SHA256withRSA in Python

I am trying to validate the digital signature with given certificate files for the offline aadhaar KYC verification application.
This instruction is given in the documentation for the verification.
Read the entire XML and separate the s=”xxxx” tag from it.
Use a signature validation algorithm leveraging “SHA256withRSA” based hashing and encryption technique
Signature value present in “s” tag, remaining XML (without "s" tag) and UIDAI public key (available here.) is to be fed to the algorithm to validate the digital signature.
Sample C# code snippets provided by the organization. (PS :which is also not working)
using System;
using System.Security.Cryptography.X509Certificates;
using System.Xml;
namespace test
{
class MainClass
{
public static void Main(string[] args)
{
// link -> https://drive.google.com/file/d/1aSv3HJUFf5_42Z-FqpdVHEk5b3VA3T3D/view
string XMLFilePath = "offlineaadhaar.xml"; //Get the XML file
// link -> https://drive.google.com/file/d/1FW4ciIhZqJuelOcGF2x6VaBCSDO9J-gM/view
string KeyFilePath = "okyc-publickey.cer"; //Get the public key certificate file
XmlDocument ObjXmlDocument = new XmlDocument();
ObjXmlDocument.Load(XMLFilePath); //Load the XML
XmlAttributeCollection SignatureElement = ObjXmlDocument.DocumentElement.Attributes; //Get the all XML attribute
string SignatureValue = SignatureElement.GetNamedItem("s").InnerXml; // Get Signature value
SignatureElement.RemoveNamedItem("s");//Remove the signature "s" attribute from XML and get the new XML to validate
/*----------------Read and parse the public key as string-----------------------*/
X509Certificate2 ObjX509Certificate2 = new X509Certificate2(KeyFilePath, "public"); //Initialize the public ket certificate file
Org.BouncyCastle.X509.X509Certificate objX509Certificate;
Org.BouncyCastle.X509.X509CertificateParser objX509CertificateParser = new Org.BouncyCastle.X509.X509CertificateParser();
objX509Certificate = objX509CertificateParser.ReadCertificate(ObjX509Certificate2.GetRawCertData());
/*----------------End-----------------------*/
/* Init alg */
Org.BouncyCastle.Crypto.ISigner signer = Org.BouncyCastle.Security.SignerUtilities.GetSigner("SHA256withRSA");
/* Populate key */
signer.Init(false, objX509Certificate.GetPublicKey());
/* Get the signature into bytes */
var expectedSig = Convert.FromBase64String(SignatureValue);
/* Get the bytes to be signed from the string */
var msgBytes = System.Text.Encoding.UTF8.GetBytes(ObjXmlDocument.InnerXml);
/* Calculate the signature and see if it matches */
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
bool Flag = signer.VerifySignature(expectedSig);
if (Flag)
{
Console.WriteLine("XML Validate Successfully");
}
else
{
Console.WriteLine("XML Validation Failed");
}
}
}
}
I am trying to implement in Python and getting the XML validation failed. I am not sure if the certificate file is wrong or there is some bug on my code.
Here is my Python Code :
import xml
import xml.etree.cElementTree as etree
from xml.etree import ElementTree
import OpenSSL
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from Crypto.PublicKey import RSA
from base64 import b64encode, b64decode
from M2Crypto import BIO, RSA, EVP
xmlDoc = open('adhar.xml', 'r').read()
Tr = etree.XML(xmlDoc)
Tr.keys()
# ['s', 'r', 'a', 'g', 'm', 'e', 'd', 'i', 'n', 'v']
sign = Tr.get('s')
len(sign)
# 344
del Tr.attrib['s']
from M2Crypto import X509
x509 =X509.load_cert('ekyc_public_key.cer')
#x509 =X509.load_cert(cert4)
rsa = x509.get_pubkey().get_rsa()
pubkey = EVP.PKey()
pubkey.assign_rsa(rsa)
xmlstr = etree.tostring(Tr, encoding='utf8', method='xml')
#rstr=str(xmlstr)[45:][:-1]
#rstr = rstr.encode(encoding='utf-8')
# if you need a different digest than the default 'sha1':
pubkey.reset_context(md='sha256')
pubkey.verify_init()
# hashlib.sha256(message_without_sign).digest()
pubkey.verify_update(xmlstr)
if(pubkey.verify_final(b64decode(sign)) != 1):
print('Digital Signeture not validated')
else:
print('Digital Signeture validated')
In cryptography, the devil is in the details, like what really is meant by:
remaining XML (without "s" tag)
We are lucky: this ridiculously vague specification comes came with a sample XML file and matching certificate, allowing to:
extract the signature signature field (converted from Base64 to binary) from the former to get S;
extract N and e from the later;
compute V = S e mod N
check that V is indeed formatted per SHA256withRSA (also known as RSASSA-PKCS1-v1_5 with SHA-256 hash),
on the right of V after a fixed DER prefix 3031300d060960864801650304020105000420 characteristic of a Digestinfo with SHA-256 we extract the 32-byte value f4efef8c788058df45385ec65a49e92f806b9ffd6fc6d11b4f3c2cf89a81fe2f, which thus is the expected hash for that example's signed data.
So with a little trial and error we find what that signed data really is. We want to start from XML file and remove
the s tag
its = (and, should there be any, whitespace between former s tag and =, and after = as allowed by the XML syntax)
its value field including leading and closing " (which contains the base64-encoded signature)
precisely two nearby space characters, like the one before the s tag and the one after the closing " (alternatively, we might want to leave a single space where there are now several, probably three after the removals in bullet points 1-3).
then hash what remains including < /> delimiters (as UTF-8), that is in the sample code pass it to BlockUpdate or verify_update. For that example:
<OKV v="1" n="Ravi Krishna Nalagatla" i="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" d="10121993" e="ac342bb947d5aa49847a0a05f87c388759a6cb156e04eac6ae995e9dca5ba1d9" m="254618fd06a2e7308247c7f0fb547f58174ab3b99e7b042d6705a5457235f32a" g="male" a="S/O Narasimham, 45, 74, 4, 7, Secunderabad, Hyderabad, Andhra Pradesh - 500003" r="328020181115111938451" />
Update: sample XML, certificate, and the above are in this zip archive.
For this project, all the instructions can be found on this page in Steps to validate signature step.
Sample data, sample public key and sample c# code can be found on this page in Offline ekyc Sample data tab.
For your own data please refer to this link and download the zip file and extract it.
Here is the ekyc public key for the other xml validation ekyc_public_key.cer
Please find the complete answer in below code snippet which is implemented in python :
from M2Crypto import BIO, RSA, EVP
from M2Crypto import X509
# 'ekyc_public_key.cer' for own your own data. as 'okyc_public_key.cer' only work for sample data only
x509 =X509.load_cert('okyc_public_key.cer')
rsa = x509.get_pubkey().get_rsa()
pubkey = EVP.PKey()
pubkey.assign_rsa(rsa)
import lxml.etree as le
with open(xml_path,'r') as f:
doc=le.parse(f)
for elem in doc.xpath('//*[attribute::s]'):
sign = elem.attrib['s']
elem.attrib.pop('s')
data_str = str(le.tostring(doc))[2:][:-1]
data = data_str[:-2] + ' />'
pubkey.reset_context(md='sha256')
pubkey.verify_init()
pubkey.verify_update((data_str[:-2] + ' />').encode())
is_valid_signeture = ""
if(pubkey.verify_final(b64decode(sign)) != 1):
print('Digital Signeture not validated')
is_valid_signeture = 'Invalid'
else:
print('Digital Signeture validated')
is_valid_signeture = 'Valid'
More about XML signing here
Python Code for Digital Signature verification for new Aadhar XML:
certificate_file = "uidai_offline_publickey_19062019.cer"
aadhar_file = "offlineaadhaar20200120032019978.xml"
certificate = open(certificate_file, "rb").read()
aadhar_xml = open(aadhar_file, "rb").read()
from signxml import XMLSigner, XMLVerifier
try:
verify_result = XMLVerifier().verify(aadhar_xml, x509_cert=certificate)
# return True
except Exception as e:
verify_result = None
# return False
print(e)
You can download the certificate from here.
More about signxml here.

PCLCrypto asymmetric encryption failing with leading zero padding public key

Running the following code fails. When I import the public key one of the RSA parameters seems to get padded with a leading zero, causing the publickKey to be 520 bits instead of the 512 bits of the privateKey.
public static void Test()
{
var algorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithm.RsaPkcs1);
ICryptographicKey privateKey = algorithm.CreateKeyPair(512);
byte[] publicKeyBytes = privateKey.ExportPublicKey(CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo);
ICryptographicKey publicKey = algorithm.ImportPublicKey(publickKeyBytes, CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo);
var encryptedValue = WinRTCrypto.CryptographicEngine.Encrypt(publicKey, Encoding.UTF8.GetBytes("test"));
var decryptedValue = WinRTCrypto.CryptographicEngine.Decrypt(privateKey, encryptedValue);
}
The problem seems to be this line:
algorithm.ImportPublicKey(publickKeyBytes, CryptographicPublicKeyBlobType.X509SubjectPublicKeyInfo);
The publicKeyBytes seems right. It works against another service that uses it to encrypt some data that I can succesfully decrypt. This issue is when i try to create some dummy encrypted data for unit testing.
Im running this code in a Portable Class Library using .Net Framework 4.5.
The above code throws at the line where it try's to decrypt, a System.Security.Cryptography.CryptographicExceptionwith the following message:
The data to be decrypted exceeds the maximum for this modulus of 64
bytes.
The following assert fails:
Assert.Equals(privateKey.KeySize, publicKey.KeySize)
Doing the following removeing the padded zero from the Modulus fix the public key and everything works fine.
RSAParameters rsaPublicParameters = publicKey.ExportParameters(false);
rsaPublicParameters.Modulus = rsaPublicParameters.Modulus.Skip(1).ToArray();
ICryptographicKey workingPublicKey = algorithm.ImportParameters(rsaPublicParameters);
Is this a bug in PCLCrypto or am I using it wrong.

RSA private key format

I was trying to find a way to replicate the session-id decoding of mega.co.nz in Ruby using OpenSSL. But, unfortunately, I'm not a cryptography expert.
The problem is I don't understand/recognise the private key format
This is what their code to decompose the private key looks like (https://eu.static.mega.co.nz/crypto.js):
// decompose private key
for (var i = 0; i < 4; i++)
{
var l = ((privk.charCodeAt(0)*256+privk.charCodeAt(1)+7)>>3)+2;
rsa_privk[i] = mpi2b(privk.substr(0,l));
if (typeof rsa_privk[i] == 'number') break;
privk = privk.substr(l);
}
privk itself is 656 bytes long (include eight dashes padding at the end).
After the 'decomposition' they use the decomposed parts to decrypt the session-id (https://eu.static.mega.co.nz/rsa.js):
// Compute m**d mod p*q for RSA private key operations.
function RSAdecrypt(m (encrypted session-id), d (rsa_privk[2]), p (rsa_privk[0]), q (rsa_privk[1]), u (rsa_privk[3]))
How to convert this key so OpenSSL knows how to use it?
OpenSSL supports different key formats, including PEM/X.509 and PKCS8.
The ruby standard library includes an OpenSSL binding.
Using the method provided in this post you can create the key from the exponent and then use for example
key.to_pem()
to convert it to an X.509-formatted string.

Problem transmiting a RSA public key, javaME , bouncy castle

I'm working on the porting of an instance messaging application from Java to JavaME ,that also implements cryptography. The problem is that I want to send my public key to the server. The desktop client has this code for this job:
byte[] encoded_public_key=publick_key.getEncoded();
And the server has this code to retrieve the key:
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encoded_public_key);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey puKey = keyFactory.generatePublic(publicKeySpec);
Now I've looked the API for the getEncoded and it says that it returns the DER-encoded form of the key as a byte array (http://www.docjar.com/docs/api/sun/s...tml#getEncoded)
My implementation for that in JavaME was this:
RSAPublicKeyStructure public_key_JAVAME=new RSAPublicKeyStructure(modulus,exponent);
byte[] DER_encoded_public_key_JAVAME=public_key_JAVAME.getDEREncoded();
//the getEncoded functions returns exact the same byte array.
However when I try to retrieve the JavaME created DER encoded key with the server code ,in other words when I try this:
EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(DER_encoded_public_key_JAVAME);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey puKey = keyFactory.generatePublic(publicKeySpec);
I get
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
Caused by: java.security.InvalidKeyException: IOException: algid parse error, not a sequence
at sun.security.x509.X509Key.decode(X509Key.java:380)
at sun.security.x509.X509Key.decode(X509Key.java:386)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)
Interesting point : The DER encoded key from the normal Java (using the getencoded() function) is a byte array is 162 bytes long while the SAME key DER encoded in JavaME using bouncy castle is 140 bytes long. Shouldn't these 2 DER encoded key be of the same lenght?I mean it's the same key in DER encoded format so they should be the same.
What am I doing wrong?
True I didn't notice that.Problem is do you know how to create a subjectPublickeyInfo object from a PublicKey in bouncyCastle? I've tried:
ByteArrayInputStream bIn = new ByteArrayInputStream(RSApublickey.toString().getbytes());
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(bIn).readObject());
But it didn't work. I also tried :
ByteArrayInputStream(RSApublicKeyStructure.getEncoded());
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo((ASN1Sequence)new ASN1InputStream(bIn).readObject());
Actually I did expect that not to work , but well I had to try it . So how can I create a Subjectpublickeyinfo from RSAkeyparameters?( This is one of the points where the obscurity of bouncy's castle API really shines I guess)
Again thank you for your response you've been of great help.You've put me on the right track.
DER-encoding is just a standard for encoding. Saying that a key is DER-encoded is equivalent to saying it is XML-encoded: you need to agree on how it is DER-/XML-encoded to be able to decode it.
In this case your RSAPublicKeyStructure.getEncoded() returns the key as the DER-encoding of an ASN.1 RSAPublicKey:
RSAPublicKey ::= SEQUENCE {
modulus INTEGER, -- n
publicExponent INTEGER -- e
}
The X509EncodedKeySpec on the other hand expects to be handed the DER-encoding of an ASN.1 PublicKeyInfo:
PublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
PublicKey BIT STRING
}
To create a PublicKeyInfo using BouncyCastle do this (courtesy of GregS):
RSAPublicKeyStructure rsaPublicKey = /* ... */
AlgorithmIdentifier rsaEncryption = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
SubjectPublicKeyInfo publicKeyInfo = new SubjectPublicKeyInfo(rsaEncryption, rsaPublicKey);
byte[] encodedPublicKeyInfo = publicKeyInfo.getEncoded();

Reimplement ASP.NET Membership and User Password Hashing in Ruby

I have a large database of users (~200,000) that I'm transferring from a ASP.NET application to a Ruby on Rails application. I don't really want to ask every user to reset their password and so I'm trying to re-implement the C# password hashing function in Ruby.
The old function is this:
public string EncodePassword(string pass, string saltBase64)
{
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] src = Convert.FromBase64String(saltBase64);
byte[] dst = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
byte[] inArray = algorithm.ComputeHash(dst);
return Convert.ToBase64String(inArray);
}
An example hashed password and salt is (and the password used was "password"):
Hashed password: "weEWx4rhyPtd3kec7usysxf7kpk="
Salt: "1ptFxHq7ALe7yXIQDdzQ9Q=="
Password: "password"
Now with the following Ruby code:
require "base64"
require "digest/sha1"
password = "password"
salt = "1ptFxHq7ALe7yXIQDdzQ9Q=="
concat = salt+password
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1)
puts encoded
I'm not getting the correct password hash (I'm getting "+BsdIOBN/Vh2U7qWG4e+O13h3iQ=" instead of "weEWx4rhyPtd3kec7usysxf7kpk="). Can anyone see what the problem might be?
Many thanks
Arfon
Just a quick update, a colleague of mine has solved this:
require "base64"
require "digest"
require "jcode"
def encode_password(password, salt)
bytes = ""
password.each_char { |c| bytes += c + "\x00" }
salty = Base64.decode64(salt)
concat = salty+bytes
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1).strip()
puts encoded
end
I have been tasked with migrating an existing .NET app to Ruby on Rails. I am using the code below to mimic the .NET password hashing. I am very new to Ruby, and don't know .NET at all. The code may not be as clean as it could, but it's a start.
To test, save this as a Ruby script and run with:
ruby script plain_text_password salt_in_base64
e.g.
ruby dotNetHash.rb password123 LU7hUk4MXAvlq6DksvP9SQ==
require "base64"
require "digest"
# Encode password as double-width characters
password_as_text = ARGV.first
double_width_password = []
double_width_password = password_as_text.encode("UTF-16LE").bytes.to_a
# Unencode the salt
salt = Base64.decode64(ARGV[1])
# Concatenate salt+pass
salt_pass_array = []
salt_pass_array = salt.bytes.to_a + double_width_password
# Repack array as string and hash it. Then encode.
salt_pass_str = salt_pass_array.pack('C*')
sha1_saltpass = Digest::SHA1.digest(salt_pass_str)
enc_sha1_saltpass = Base64.encode64(sha1_saltpass).strip()
puts "Encoded SHA1 saltpass is " + enc_sha1_saltpass
You are pretty close. Unfortunately Ruby has no built-in unicode support at the moment, and your hashing function relies on it. There are workarounds. Look around the site on how to do unicode in Ruby.
BTW, I think you forgot to base64 decode the salt, it looks like the ASP.net function does that.
You need to unencode the salt to convert it back to it's byte representation and then concatenate that with the password to get the hashed password value. You're using the encoding salt string directly (which is a different salt) and thus it is hashing to something different.
require "base64"
require "digest/sha1"
password = "password"
salt = Base64.decode64("1ptFxHq7ALe7yXIQDdzQ9Q==")
concat = salt+password
sha1 = Digest::SHA1.digest(concat)
encoded = Base64.encode64(sha1)
puts encoded

Resources