EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Signature verification using RSAPKCS1SignatureDeformatter

Also by EldoS: RawDisk
Access locked and protected files in Windows, read and write disks and partitions and more.
#22241
Posted: 10/29/2012 02:55:18
by Martin Frey (Basic support level)
Joined: 10/26/2012
Posts: 3

Hello,

I’d like to verify a signature which I’ve created by the TElRSAPublicKeyCrypto class by using the RSAPKCS1SignatureDeformatter class of the the System.Security.Cryptography namespace.
I know I can also do this by using the TElRSAPublicKeyCrypto class but the verification should also be done by our customers.

My signing code using the TElRSAPublicKeyCrypto class:

Code
protected byte[] Sign(byte[] hash)
        {
            int iSize = 0;
            byte[] signedHash = new byte[0];

            TElRSAPublicKeyCrypto rsa = new TElRSAPublicKeyCrypto(3, sbbCert.CryptoProvider);
            rsa.KeyMaterial = sbbCert.KeyMaterial;
            rsa.SignDetached(hash, 0, hash.Count(), ref signedHash, 0, ref iSize);
            signedHash = new byte[iSize];
            rsa.SignDetached(hash, 0, hash.Count(), ref signedHash, 0, ref iSize);

            return signedHash;
        }


Any idea?

Thanks
#22242
Posted: 10/29/2012 02:57:54
by Eugene Mayevski (EldoS Corp.)

And what have you tried already? I.e. what particular problem are you having?


Sincerely yours
Eugene Mayevski
#22243
Posted: 10/29/2012 03:34:42
by Martin Frey (Basic support level)
Joined: 10/26/2012
Posts: 3

We cannot verify the signature by the code below. We used this code before we used the TElRSAPublicKeyCrypto class for signing. Is there maybe an easier way to get the RSACryptoServiceProvider?

Code
public bool VerifySignatureOld(byte[] hash, byte[] signedHash)
        {
            RSACryptoServiceProvider rsa = GetPublicKeyFromX509Certificate(sbbCert.ToX509Certificate2(true));
            RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
            rsaDeformatter.SetHashAlgorithm("SHA1");

            bool isVerified = rsaDeformatter.VerifySignature(hash, signedHash);
            return isVerified;
        }



Code
public RSACryptoServiceProvider GetPublicKeyFromX509Certificate(X509Certificate x509)
        {
            RSACryptoServiceProvider rsacsp = null;
            uint hProv = 0;
            IntPtr pPublicKeyBlob = IntPtr.Zero;
            // Get a pointer to a CERT_CONTEXT structure from the raw certificate data.
            IntPtr pCertContext = IntPtr.Zero;

            pCertContext = (IntPtr)CryptoAPI.CertCreateCertificateContext(
                                        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                        x509.GetRawCertData(),
                                        x509.GetRawCertData().Length);

            if (pCertContext == IntPtr.Zero)
                throw new Exception("CertCreateCertificateContext failed: ");// + Marshal.GetLastWin32Error().ToString());

            if (!CryptoAPI.CryptAcquireContext(ref hProv, null, null, PROV_RSA_FULL, 0))
            {
                if (!CryptoAPI.CryptAcquireContext(ref hProv, null, null, PROV_RSA_FULL, CRYPT_NEWKEYSET))
                    throw new Exception("CryptAcquireContext failed: ");// + Marshal.GetLastWin32Error().ToString());
            }

            // Get a pointer to the CERT_INFO structure.
            // This pointer is the fourth DWORD of the CERT_CONTEXT structure.

            IntPtr pCertInfo = (IntPtr)Marshal.ReadInt32(pCertContext, 12);

            // Get a pointer to the CERT_PUBLIC_KEY_INFO structure.
            // This structure is located starting at the fifty-seventh byte
            // of the CERT_INFO structure.

            IntPtr pSubjectPublicKeyInfo = (IntPtr)(pCertInfo.ToInt32() + 56);

            // Import the public key information from the certificate context
            // into a key container by passing the pointer to the SubjectPublicKeyInfo
            // member of the CERT_INFO structure to the CryptImportPublicKeyInfoEx
            // Win32 API function.

            uint hKey = 0;
            if (!CryptoAPI.CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                    pSubjectPublicKeyInfo, ref hKey))
                throw new Exception("CryptImportPublicKeyInfoEx failed: " + Marshal.GetLastWin32Error().ToString());

            // Get the size of the buffer that is needed to contain the PUBLICKEYBLOB structure, and then
            // call the CryptExportKey Win32 API function to export the public key to the PUBLICKEYBLOB format.

            uint dwDataLen = 0;
            if (!CryptoAPI.CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, 0, ref dwDataLen))
                throw new Exception("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString());

            // Export the public key to the PUBLICKEYBLOB format.

            pPublicKeyBlob = Marshal.AllocHGlobal((int)dwDataLen);
            if (!CryptoAPI.CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, (uint)pPublicKeyBlob.ToInt32(), ref dwDataLen))
                throw new Exception("CryptExportKey failed: " + Marshal.GetLastWin32Error().ToString());

            // Get the public exponent.
            // The public exponent is located in bytes 17 through 20 of the
            // earlier PUBLICKEYBLOB structure.

            byte[] Exponent = new byte[4];
            Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 16), Exponent, 0, 4);
            Array.Reverse(Exponent);

            // Reverse the byte order.
            // Get the length of the modulus.
            // To do this, extract the bit length of the modulus from the PUBLICKEYBLOB structure.
            // The bit length of the modulus is located in bytes 13 through 17 of the PUBLICKEYBLOB structure.

            int BitLength = Marshal.ReadInt32(pPublicKeyBlob, 12);

            // Get the modulus.
            // The modulus starts at the twenty-first byte of the PUBLICKEYBLOB structure,
            // and is BitLength/8 bytes in length.

            byte[] Modulus = new byte[BitLength / 8];
            Marshal.Copy((IntPtr)(pPublicKeyBlob.ToInt32() + 20), Modulus, 0, BitLength / 8);
            Array.Reverse(Modulus);

            // Reverse the byte order.
            // Put the modulus and the exponent into an RSAParameters object.

            RSAParameters rsaparms = new RSAParameters();
            rsaparms.Exponent = Exponent;
            rsaparms.Modulus = Modulus;

            // Import the modulus and the exponent into an RSACryptoServiceProvider object
            // by using the RSAParameters object.

            rsacsp = new RSACryptoServiceProvider();

            rsacsp.ImportParameters(rsaparms);
            // Cleanup:

            if (pCertContext != IntPtr.Zero)
                CryptoAPI.CertFreeCertificateContext(pCertContext.ToInt32());

            if (hProv != 0)
                CryptoAPI.CryptReleaseContext(hProv, 0);

            if (pPublicKeyBlob != IntPtr.Zero)
                Marshal.FreeHGlobal(pPublicKeyBlob);

            // use machines key store for impersonating use because of com+
            //RSACryptoServiceProvider.UseMachineKeyStore = true;

            return rsacsp;
        }


Regards,
Martin
#22245
Posted: 10/29/2012 03:39:27
by Vsevolod Ievgiienko (EldoS Corp.)

Hello.

Could you send us (via Helpdesk) a sample project with a set of input data that can be used to reproduce the problem.

Reply

Statistics

Topic viewed 1697 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!