Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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
        }
Example #4
0
        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);
        }