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); }
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); }
public static byte[] DeriveKey(CngKey externalPubKey, CngKey privateKey, int keyBitLength, byte[] algorithmId, byte[] partyVInfo, byte[] partyUInfo, byte[] suppPubInfo) { #if NET40 || NET461 using (var cng = new ECDiffieHellmanCng(privateKey)) { using (SafeNCryptSecretHandle hSecretAgreement = cng.DeriveSecretAgreementHandle(externalPubKey)) { using (var algIdBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_ALGORITHMID, algorithmId)) using (var pviBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_PARTYVINFO, partyVInfo)) using (var pvuBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_PARTYUINFO, partyUInfo)) using (var spiBuffer = new NCrypt.NCryptBuffer(NCrypt.KDF_SUPPPUBINFO, suppPubInfo)) { using (var parameters = new NCrypt.NCryptBufferDesc(algIdBuffer, pviBuffer, pvuBuffer, spiBuffer)) { uint derivedSecretByteSize; uint status = NCrypt.NCryptDeriveKey(hSecretAgreement, "SP800_56A_CONCAT", parameters, null, 0, out derivedSecretByteSize, 0); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", status)); } var secretKey = new byte[derivedSecretByteSize]; status = NCrypt.NCryptDeriveKey(hSecretAgreement, "SP800_56A_CONCAT", parameters, secretKey, derivedSecretByteSize, out derivedSecretByteSize, 0); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", status)); } return(Arrays.LeftmostBits(secretKey, keyBitLength)); } } } } #elif NETSTANDARD1_4 throw new NotImplementedException("not yet"); #endif }
public static byte[] Decrypt(byte[] cipherText, CngKey key, CngAlgorithm hash) { var paddingInfo = new BCrypt.BCRYPT_OAEP_PADDING_INFO(hash.Algorithm); uint plainTextByteSize; uint status = NCrypt.NCryptDecrypt(key.Handle, cipherText, cipherText.Length, ref paddingInfo, null, 0, out plainTextByteSize, BCrypt.BCRYPT_PAD_OAEP); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.Decrypt() (plaintext buffer size) failed with status code:{0}", status)); } var plainText = new byte[plainTextByteSize]; status = NCrypt.NCryptDecrypt(key.Handle, cipherText, cipherText.Length, ref paddingInfo, plainText, plainTextByteSize, out plainTextByteSize, BCrypt.BCRYPT_PAD_OAEP); if (status != BCrypt.ERROR_SUCCESS) { throw new CryptographicException(string.Format("NCrypt.Decrypt() failed with status code:{0}", status)); } return(plainText); }