private static byte[] SignHash(byte[] hash, CngKey key, string algorithm, int saltSize) { var paddingIndo = new BCrypt.BCRYPT_PSS_PADDING_INFO(algorithm, saltSize); uint size; uint status; status = NCrypt.NCryptSignHash(key.Handle, ref paddingIndo, hash, hash.Length, null, 0, out size, BCrypt.BCRYPT_PAD_PSS); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptSignHash() (signature size) failed with status code:{0}", status)); } byte[] signature = new byte[size]; status = NCrypt.NCryptSignHash(key.Handle, ref paddingIndo, hash, hash.Length, signature, signature.Length, out size, BCrypt.BCRYPT_PAD_PSS); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptSignHash() failed with status code:{0}", status)); } return(signature); }
internal static extern uint NCryptVerifySignature(SafeNCryptKeyHandle hKey, ref BCrypt.BCRYPT_PSS_PADDING_INFO pPaddingInfo, byte[] pbHashValue, int cbHashValue, byte[] pbSignature, int cbSignature, uint dwFlags);
internal static extern uint NCryptSignHash(SafeNCryptKeyHandle hKey, ref BCrypt.BCRYPT_PSS_PADDING_INFO pPaddingInfo, byte[] pbHashValue, int cbHashValue, byte[] pbSignature, int cbSignature, out uint pcbResult, uint dwFlags);
private static bool VerifyHash(byte[] hash, byte[] signature, CngKey key, string algorithm, int saltSize) { var paddingInfo = new BCrypt.BCRYPT_PSS_PADDING_INFO(algorithm, saltSize); uint status = NCrypt.NCryptVerifySignature(key.Handle, ref paddingInfo, hash, hash.Length, signature, signature.Length, BCrypt.BCRYPT_PAD_PSS); if (status == NCrypt.NTE_BAD_SIGNATURE) //honestly it always failing with NTE_INVALID_PARAMETER, but let's stick to public API { return(false); } if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptSignHash() (signature size) failed with status code:{0}", status)); } return(true); }