protected override bool ReleaseHandle() { if (!_callerFree) { return(true); } if (IsNCryptKey) { return(NCrypt.NCryptFreeObject(handle) == SECURITY_STATUS.ERROR_SUCCESS); } else { return(AdvApi32.CryptReleaseContext(handle, 0u)); } }
/// <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)); }
protected override bool ReleaseHandle() { return(NCrypt.NCryptFreeObject(handle) == SECURITY_STATUS.ERROR_SUCCESS); }