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); }
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); } } }