Example #1
0
        /// <summary>
        /// Computes the hash value of the specified byte array using the specified hash algorithm, and signs the resulting hash value.
        /// </summary>
        /// <param name="certificate">An <see cref="X509Certificate2"/> object of the signer certificate.</param>
        /// <param name="message">Message to be signed.</param>
        /// <param name="hashAlgorithm">The name of the hash algorithm to use in the signature.</param>
        /// <returns>The signature for the specified data.</returns>
        public static Byte[] SignMessage(X509Certificate2 certificate, Byte[] message, Oid hashAlgorithm)
        {
            IntPtr  phCryptProv      = IntPtr.Zero;
            UInt32  pdwKeySpec       = 0;
            Boolean pfCallerFreeProv = false;

            if (!Crypt32.CryptAcquireCertificatePrivateKey(certificate.Handle, 0x00010000, IntPtr.Zero, ref phCryptProv, ref pdwKeySpec, ref pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            Oid2 hashalgorithm = new Oid2(
                hashAlgorithm.FriendlyName.ToLower()
                .Replace("rsa", null)
                .Replace("ecdsa", null),
                OidGroupEnum.HashAlgorithm, true);
            String hashAlg;

            // true -> CNG, false -> legacy
            if (pdwKeySpec == UInt32.MaxValue)
            {
                Byte[] hashBytes = calculateHash(message, hashalgorithm, false, out hashAlg);
                try {
                    UInt32 pcbResult;
                    Int32  hresult = nCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, (UInt32)hashBytes.Length, null, 0, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    Byte[] pbSignature = new byte[pcbResult];
                    hresult = nCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, (UInt32)hashBytes.Length, pbSignature, (UInt32)pbSignature.Length, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    return(pbSignature);
                } finally {
                    if (pfCallerFreeProv)
                    {
                        nCrypt.NCryptFreeObject(phCryptProv);
                    }
                }
            }
            if (pfCallerFreeProv)
            {
                AdvAPI.CryptReleaseContext(phCryptProv, 0);
            }
            calculateHash(message, hashalgorithm, false, out hashAlg);
            RSACryptoServiceProvider key = (RSACryptoServiceProvider)certificate.PrivateKey;

            return(key.SignData(message, hashAlg));
        }
 /// <summary>
 /// Deletes private key material associated with a X.509 certificate from file system or hardware storage.
 /// </summary>
 /// <param name="cert">An instance of X.509 certificate.</param>
 /// <returns>
 /// <strong>True</strong> if associated private key was found and successfully deleted, otherwise <strong>False</strong>.
 /// </returns>
 public static Boolean DeletePrivateKey(this X509Certificate2 cert)
 {
     if (!Crypt32.CryptAcquireCertificatePrivateKey(
             cert.Handle,
             Wincrypt.CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG,
             IntPtr.Zero,
             out SafeNCryptKeyHandle phCryptProvOrNCryptKey,
             out UInt32 pdwKeySpec,
             out Boolean _))
     {
         return(false);
     }
     return(pdwKeySpec == UInt32.MaxValue
         ? deleteCngKey(phCryptProvOrNCryptKey)
         : deleteLegacyKey(cert.PrivateKey));
 }
Example #3
0
        public static PrivateKey ExtractKey(X509Certificate2 cert)
        {
            if (!cert.HasPrivateKey)
            {
                throw new ArgumentException("Certificate does not contain a private key.", nameof(cert));
            }
            NCryptKeyOrCryptProviderSafeHandle handle;
            KeySpec keySpec;
            bool    callerFree;
            var     flags = PlatformSupport.HasCngSupport ? AcquirePrivateKeyFlags.CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG : 0u;

            if (!Crypt32.CryptAcquireCertificatePrivateKey(cert.Handle, flags, IntPtr.Zero, out handle, out keySpec, out callerFree))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            handle.SetCallerFree(callerFree);
            return(new PrivateKey(handle, keySpec == KeySpec.NCRYPT ? KeyProviders.CNG : KeyProviders.CAPI, keySpec));
        }
Example #4
0
        /// <summary>
        /// Computes the hash value of the specified byte array using the specified hash algorithm, and signs the resulting hash value.
        /// </summary>
        /// <param name="certificate">An <see cref="X509Certificate2"/> object of the signer certificate.</param>
        /// <param name="message">Message to be signed.</param>
        /// <param name="hashAlgorithm">The name of the hash algorithm to use in the signature. For example, 'SHA256'</param>
        /// <returns>The signature for the specified data.</returns>
        public static Byte[] SignMessage(X509Certificate2 certificate, Byte[] message, Oid hashAlgorithm)
        {
            SafeNCryptKeyHandle phCryptProv = new SafeNCryptKeyHandle();
            UInt32  pdwKeySpec       = 0;
            Boolean pfCallerFreeProv = false;

            if (!Crypt32.CryptAcquireCertificatePrivateKey(certificate.Handle, Wincrypt.CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, IntPtr.Zero, out phCryptProv, out pdwKeySpec, out pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            // true -> CNG, false -> legacy
            if (pdwKeySpec == UInt32.MaxValue)
            {
                Byte[] hashBytes = calculateHash(message, hashAlgorithm.FriendlyName, false);
                try {
                    Int32 hresult = NCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, hashBytes.Length, null, 0, out Int32 pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    Byte[] pbSignature = new Byte[pcbResult];
                    hresult = NCrypt.NCryptSignHash(phCryptProv, IntPtr.Zero, hashBytes, hashBytes.Length, pbSignature, pbSignature.Length, out pcbResult, 0);
                    if (hresult != 0)
                    {
                        throw new CryptographicException(hresult);
                    }
                    return(pbSignature);
                } finally {
                    if (pfCallerFreeProv)
                    {
                        NCrypt.NCryptFreeObject(phCryptProv.DangerousGetHandle());
                    }
                }
            }
            if (pfCallerFreeProv)
            {
                AdvAPI.CryptReleaseContext(phCryptProv.DangerousGetHandle(), 0);
            }
            calculateHash(message, hashAlgorithm.FriendlyName, false);
            RSACryptoServiceProvider key = (RSACryptoServiceProvider)certificate.PrivateKey;

            return(key.SignData(message, hashAlgorithm.Value));
        }
Example #5
0
        void acquirePrivateKey()
        {
            if (disposed)
            {
                throw new ObjectDisposedException(nameof(SignerCertificate));
            }
            // the key is already acquired, so skip key retrieval
            if (checkPrivateKeyIsLoaded())
            {
                return;
            }
            // the key is not acquired, so attempt to get it
            UInt32              pdwKeySpec             = 0;
            Boolean             pfCallerFreeProv       = false;
            SafeNCryptKeyHandle phCryptProvOrNCryptKey = new SafeNCryptKeyHandle();

            if (!Crypt32.CryptAcquireCertificatePrivateKey(
                    SignerCertificate.Handle,
                    Wincrypt.CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG,
                    IntPtr.Zero,
                    ref phCryptProvOrNCryptKey,
                    ref pdwKeySpec,
                    ref pfCallerFreeProv))
            {
                throw new CryptographicException(Marshal.GetLastWin32Error());
            }
            if (pdwKeySpec == UInt32.MaxValue)
            {
                phPrivKey = phCryptProvOrNCryptKey;
                isCng     = true;
            }
            else
            {
                // translate legacy CSP key to CNG key handle
                getCngHandleFromLegacy(phCryptProvOrNCryptKey);
            }
        }
Example #6
0
 void acquirePrivateKeyFromCert()
 {
     // the key is not acquired, so attempt to get it
     if (!Crypt32.CryptAcquireCertificatePrivateKey(
             SignerCertificate.Handle,
             Wincrypt.CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG,
             IntPtr.Zero,
             out SafeNCryptKeyHandle phCryptProvOrNCryptKey,
             out UInt32 pdwKeySpec,
             out Boolean _))
     {
         throw new CryptographicException(Marshal.GetLastWin32Error());
     }
     if (pdwKeySpec == UInt32.MaxValue)
     {
         phPrivKey = phCryptProvOrNCryptKey;
         isCng     = true;
     }
     else
     {
         // translate legacy CSP key to CNG key handle
         getCngHandleFromLegacy(phCryptProvOrNCryptKey);
     }
 }