Exemple #1
0
        public static byte[] DeriveKey(CngKey externalPubKey, CngKey privateKey, int keyBitLength, byte[] algorithmId, byte[] partyVInfo, byte[] partyUInfo, byte[] suppPubInfo)
        {
            uint num;

            byte[] numArray;
            using (ECDiffieHellmanCng eCDiffieHellmanCng = new ECDiffieHellmanCng(privateKey))
            {
                using (SafeNCryptSecretHandle safeNCryptSecretHandle = eCDiffieHellmanCng.DeriveSecretAgreementHandle(externalPubKey))
                {
                    using (NCrypt.NCryptBuffer nCryptBuffer = new NCrypt.NCryptBuffer(8, algorithmId))
                    {
                        using (NCrypt.NCryptBuffer nCryptBuffer1 = new NCrypt.NCryptBuffer(10, partyVInfo))
                        {
                            using (NCrypt.NCryptBuffer nCryptBuffer2 = new NCrypt.NCryptBuffer(9, partyUInfo))
                            {
                                using (NCrypt.NCryptBuffer nCryptBuffer3 = new NCrypt.NCryptBuffer(11, suppPubInfo))
                                {
                                    using (NCrypt.NCryptBufferDesc nCryptBufferDesc = new NCrypt.NCryptBufferDesc(new NCrypt.NCryptBuffer[] { nCryptBuffer, nCryptBuffer1, nCryptBuffer2, nCryptBuffer3 }))
                                    {
                                        uint num1 = NCrypt.NCryptDeriveKey(safeNCryptSecretHandle, "SP800_56A_CONCAT", nCryptBufferDesc, null, 0, out num, 0);
                                        if (num1 != 0)
                                        {
                                            throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", num1));
                                        }
                                        byte[] numArray1 = new byte[num];
                                        num1 = NCrypt.NCryptDeriveKey(safeNCryptSecretHandle, "SP800_56A_CONCAT", nCryptBufferDesc, numArray1, num, out num, 0);
                                        if (num1 != 0)
                                        {
                                            throw new CryptographicException(string.Format("NCrypt.NCryptDeriveKey() failed with status code:{0}", num1));
                                        }
                                        numArray = Arrays.LeftmostBits(numArray1, keyBitLength);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(numArray);
        }
Exemple #2
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
        }
        public static byte[] DeriveKeyMaterial(
            this ECDiffieHellmanCng provider,
            ECDiffieHellmanPublicKey otherPartyPublicKey,
            byte[] algorithmId,
            byte[] partyUInfo,
            byte[] partyVInfo)
        {
            Collection <IntPtr> ResourcesToFree = new Collection <IntPtr>();

            try
            {
                using SafeNCryptSecretHandle Agreement = provider.DeriveSecretAgreementHandle(otherPartyPublicKey);

                IntPtr AlgorithmIdPtr = Marshal.AllocHGlobal(algorithmId.Length);
                ResourcesToFree.Add(AlgorithmIdPtr);
                Marshal.Copy(algorithmId, 0, AlgorithmIdPtr, algorithmId.Length);

                IntPtr PartyUPtr = Marshal.AllocHGlobal(partyUInfo.Length);
                ResourcesToFree.Add(PartyUPtr);
                Marshal.Copy(partyUInfo, 0, PartyUPtr, partyUInfo.Length);

                IntPtr PartyVPtr = Marshal.AllocHGlobal(partyVInfo.Length);
                ResourcesToFree.Add(PartyVPtr);
                Marshal.Copy(partyVInfo, 0, PartyVPtr, partyVInfo.Length);

                NativeMethods.NCryptBuffer[] Buffers = new NativeMethods.NCryptBuffer[]
                {
                    new NativeMethods.NCryptBuffer
                    {
                        cbBuffer   = (uint)algorithmId.Length,
                        BufferType = NativeMethods.BufferType.KDF_ALGORITHMID,
                        pvBuffer   = AlgorithmIdPtr
                    },
                    new NativeMethods.NCryptBuffer
                    {
                        cbBuffer   = (uint)partyUInfo.Length,
                        BufferType = NativeMethods.BufferType.KDF_PARTYUINFO,
                        pvBuffer   = PartyUPtr
                    },
                    new NativeMethods.NCryptBuffer
                    {
                        cbBuffer   = (uint)partyVInfo.Length,
                        BufferType = NativeMethods.BufferType.KDF_PARTYVINFO,
                        pvBuffer   = PartyVPtr
                    }
                };

                IntPtr BufferPtr = Marshal.AllocHGlobal(Buffers.Length * Marshal.SizeOf(typeof(NativeMethods.NCryptBuffer)));

                ResourcesToFree.Add(BufferPtr);

                IntPtr Location = BufferPtr;
                for (int i = 0; i < Buffers.Length; i++)
                {
                    Marshal.StructureToPtr(Buffers[i], Location, false);
                    Location = new IntPtr(Location.ToInt64() + Marshal.SizeOf(typeof(NativeMethods.NCryptBuffer)));
                }

                NativeMethods.NCryptBufferDesc ParameterList = new NativeMethods.NCryptBufferDesc
                {
                    cBuffers = Buffers.Length,
                    pBuffers = BufferPtr
                };

                byte[] DerivedKey = new byte[32];

                NativeMethods.ErrorCode ErrorCode = NativeMethods.NCryptDeriveKey(
                    Agreement,
                    "SP800_56A_CONCAT",
                    ref ParameterList,
                    DerivedKey,
                    DerivedKey.Length,
                    out int NumberOfBytesDerived,
                    0);

                if (ErrorCode != NativeMethods.ErrorCode.Success)
                {
                    throw new InvalidOperationException($"KeyMaterial could not be derived. ErrorCode [{ErrorCode}], Win32Error [{Marshal.GetLastWin32Error()}] returned.");
                }

                if (NumberOfBytesDerived != 32)
                {
                    throw new InvalidOperationException("KeyMaterial size was invalid.");
                }

                return(DerivedKey);
            }
            finally
            {
                foreach (IntPtr Resource in ResourcesToFree)
                {
                    Marshal.FreeHGlobal(Resource);
                }
            }
        }