Beispiel #1
0
 private static void CreateKeys()
 {
     aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
     alicePubKeyBlod = aliceKey.Export(CngKeyBlobFormat.GenericPublicBlob);
     bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
     bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.GenericPublicBlob);
 }
Beispiel #2
0
        public static byte[] DeriveKey(CngKey externalPubKey, CngKey privateKey, int keyBitLength, byte[] algorithmId, byte[] partyVInfo, byte[] partyUInfo, byte[] suppPubInfo)
        {
            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);
                        }
                    }
                }
            }            

        }
Beispiel #3
0
        private static X509Certificate2 CreateSelfSignedCertificate(CngKey key, X500DistinguishedName subjectName)
        {
            using (SafeCertContextHandle selfSignedCertHandle = CreateSelfSignedCertificate(key,
                                                                                            true,
                                                                                            subjectName.RawData,
                                                                                            X509CertificateCreationOptions.None, // NONE
                                                                                            RsaSha1Oid,
                                                                                            DateTime.UtcNow,
                                                                                            DateTime.UtcNow.AddYears(1)))
            {
                X509Certificate2 certificate = null;
                bool addedRef = false;
                RuntimeHelpers.PrepareConstrainedRegions();
                try
                {
                    selfSignedCertHandle.DangerousAddRef(ref addedRef);
                    certificate = new X509Certificate2(selfSignedCertHandle.DangerousGetHandle());
                }
                finally
                {
                    if (addedRef)
                    {
                        selfSignedCertHandle.DangerousRelease();
                    }
                }

                key.Dispose();

                return certificate;
            }
        }
        /// <summary>
        /// Decrypts a ProcessedPacket.
        /// </summary>
        /// <param name="InitializationVector">Initialization vec to be used by AES.</param>
        /// <param name="PrivateKey">Private key to be used.</param>
        /// <param name="PubKeyBlob">Public key blob to be used.</param>
        /// <param name="StreamToDecrypt">The stream to decrypt.</param>
        /// <returns>A decrypted stream.</returns>
        public static byte[] DecryptData(byte[] InitializationVector, CngKey PrivateKey, byte[] PubKeyBlob,
            byte[] DataToDecrypt)
        {
            using (var Algorithm = new ECDiffieHellmanCng(PrivateKey))
            {
                using (CngKey PubKey = CngKey.Import(PubKeyBlob,
                      CngKeyBlobFormat.EccPublicBlob))
                {
                    byte[] SymmetricKey = Algorithm.DeriveKeyMaterial(PubKey);
                    Console.WriteLine("DecryptedStream: Created symmetric key with " +
                        "public key information: {0}", Convert.ToBase64String(SymmetricKey));

                    AesCryptoServiceProvider AES = new AesCryptoServiceProvider();
                    AES.Key = SymmetricKey;
                    AES.IV = InitializationVector;
                    int NBytes = AES.BlockSize >> 3; //No idea...

                    using (ICryptoTransform Decryptor = AES.CreateDecryptor())
                    {
                        using (MemoryStream DecryptedStream = new MemoryStream())
                        {
                            var cs = new CryptoStream(DecryptedStream, Decryptor, CryptoStreamMode.Write);
                            cs.Write(DataToDecrypt, NBytes, DataToDecrypt.Length - NBytes);
                            cs.FlushFinalBlock();

                            return DecryptedStream.ToArray();
                        }
                    }
                }
            }
        }
    public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey)
    {
      Contract.Ensures(Contract.Result<byte[]>() != null);
      Contract.Ensures(this.Key.Handle != null);

      return default(byte[]);
    }
Beispiel #6
0
        public override void Write(CngKey key, Stream stream)
        {
            int keySize;
            byte[] x;
            byte[] y;

            var keyBlob = key.Export(CngKeyBlobFormat.EccPublicBlob);

            unsafe
            {
                fixed(byte* pKeyBlob = keyBlob)
                {
                    var pBcryptBlob = (BCRYPT_ECCKEY_BLOB*) pKeyBlob;
                    var offset = Marshal.SizeOf(typeof (BCRYPT_ECCKEY_BLOB));

                    keySize = pBcryptBlob->KeySizeBytes;
                    x = new byte[keySize];
                    y = new byte[keySize];

                    Buffer.BlockCopy(keyBlob, offset, x, 0, keySize);
                    offset += keySize;
                    Buffer.BlockCopy(keyBlob, offset, y, 0, keySize);
                }
            }

            WriteInternal(keySize, x, y, stream);
        }
Beispiel #7
0
        internal static CngKey Import(byte[] keyBlob, string curveName, CngKeyBlobFormat format, CngProvider provider)
        {
            if (keyBlob == null)
                throw new ArgumentNullException(nameof(keyBlob));
            if (format == null)
                throw new ArgumentNullException(nameof(format));
            if (provider == null)
                throw new ArgumentNullException(nameof(provider));

            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle keyHandle = null;
            ErrorCode errorCode;
            
            if (curveName == null)
            {
                errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, IntPtr.Zero, out keyHandle, keyBlob, keyBlob.Length, 0);
                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
            }
            else
            {
#if !NETNATIVE
                keyHandle = ECCng.ImportKeyBlob(format.Format, keyBlob, curveName, providerHandle);
#endif //!NETNATIVE
            }

            CngKey key = new CngKey(providerHandle, keyHandle);

            // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not
            key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob;

            return key;
        }
        public ECDsaCng(CngKey key) {
            Contract.Ensures(LegalKeySizesValue != null);
            Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa);

            if (key == null) {
                throw new ArgumentNullException("key");
            }
            if (key.AlgorithmGroup != CngAlgorithmGroup.ECDsa) {
                throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDsaRequiresECDsaKey), "key");
            }

            if (!NCryptNative.NCryptSupported) {
                throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
            }

            LegalKeySizesValue = s_legalKeySizes;

            // Make a copy of the key so that we continue to work if it gets disposed before this algorithm
            //
            // This requires an assert for UnmanagedCode since we'll need to access the raw handles of the key
            // and the handle constructor of CngKey.  The assert is safe since ECDsaCng will never expose the
            // key handles to calling code (without first demanding UnmanagedCode via the Handle property of
            // CngKey).
            //
            // We also need to dispose of the key handle since CngKey.Handle returns a duplicate
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
            using (SafeNCryptKeyHandle keyHandle = key.Handle) {
                Key = CngKey.Open(keyHandle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None);
            }
            CodeAccessPermission.RevertAssert();

            KeySize = m_key.KeySize;
        }
Beispiel #9
0
        public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters)
        {
            if (algorithm == null)
                throw new ArgumentNullException("algorithm");

            if (creationParameters == null)
                creationParameters = new CngKeyCreationParameters();

            SafeNCryptProviderHandle providerHandle = creationParameters.Provider.OpenStorageProvider();
            SafeNCryptKeyHandle keyHandle;
            ErrorCode errorCode = Interop.NCrypt.NCryptCreatePersistedKey(providerHandle, out keyHandle, algorithm.Algorithm, keyName, 0, creationParameters.KeyCreationOptions);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
                throw errorCode.ToCryptographicException();

            InitializeKeyProperties(keyHandle, creationParameters);

            errorCode = Interop.NCrypt.NCryptFinalizeKey(keyHandle, 0);
            if (errorCode != ErrorCode.ERROR_SUCCESS)
                throw errorCode.ToCryptographicException();

            CngKey key = new CngKey(providerHandle, keyHandle);

            // No name translates to an ephemeral key
            if (keyName == null)
            {
                key.IsEphemeral = true;
            }

            return key;
        }
Beispiel #10
0
 public static void CreateKeys()
 {
     // 根据算法创建密钥对
     aliceKeySignature = CngKey.Create(CngAlgorithm.ECDsaP256);
     // 导出密钥对中的公钥
     alicePubKeyBlob = aliceKeySignature.Export(CngKeyBlobFormat.GenericPublicBlob);
 }
Beispiel #11
0
        private static byte[] Sign(byte[] message, byte[] prikey)
        {
            var Secp256r1_G = HexString2Bytes("04" + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5");

            var PublicKey = Neo.Cryptography.ECC.ECCurve.Secp256r1.G * prikey;
            var pubkey    = PublicKey.EncodePoint(false).Skip(1).ToArray();
            //#if NET461
            const int ECDSA_PRIVATE_P256_MAGIC = 0x32534345;

            prikey = BitConverter.GetBytes(ECDSA_PRIVATE_P256_MAGIC).Concat(BitConverter.GetBytes(32)).Concat(pubkey).Concat(prikey).ToArray();
            using (System.Security.Cryptography.CngKey key = System.Security.Cryptography.CngKey.Import(prikey, System.Security.Cryptography.CngKeyBlobFormat.EccPrivateBlob))
                using (System.Security.Cryptography.ECDsaCng ecdsa = new System.Security.Cryptography.ECDsaCng(key))
                //#else
                //            using (var ecdsa = System.Security.Cryptography.ECDsa.Create(new System.Security.Cryptography.ECParameters
                //            {
                //                Curve = System.Security.Cryptography.ECCurve.NamedCurves.nistP256,
                //                D = prikey,
                //                Q = new System.Security.Cryptography.ECPoint
                //                {
                //                    X = pubkey.Take(32).ToArray(),
                //                    Y = pubkey.Skip(32).ToArray()
                //                }
                //            }))
                //#endif
                {
                    return(ecdsa.SignData(message, System.Security.Cryptography.HashAlgorithmName.SHA256));
                }
        }
Beispiel #12
0
 public ECDSASigner(string privateKey) //konstruktor do importowania klucza
 {
     this.privateKey = Base58CheckEncoding.DecodePlain(privateKey);
     CngPrivateKey = CngKey.Import(this.privateKey, CngKeyBlobFormat.EccPrivateBlob);
     ECDSA = new ECDsaCng(CngPrivateKey);
     ECDSA.HashAlgorithm = CngAlgorithm.Sha256;
 }
Beispiel #13
0
 public static bool Verify(byte[] securedInput, byte[] signature, CngKey key, CngAlgorithm hash, int saltSize)
 {
     using (HashAlgorithm algo = HashAlgorithm(hash))
     {
         return VerifyHash(algo.ComputeHash(securedInput),signature, key, hash.Algorithm, saltSize);
     }
 }
Beispiel #14
0
 public static byte[] Sign(byte[] input, CngKey key, CngAlgorithm hash, int saltSize)
 {
     using (HashAlgorithm algo = HashAlgorithm(hash))
     {
         return SignHash(algo.ComputeHash(input), key, hash.Algorithm, saltSize);
     }
 }
 public static void CreateKey()
 {
     aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
     bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
     alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
     bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
 }
 private bool IsSignatureValid(byte[] hash, byte[] signature, CngKey key)
 {
     using (var signingAlg = new RSACng(key))
     {
         return signingAlg.VerifyHash(hash, signature, HashAlgorithmName.SHA384, RSASignaturePadding.Pss);
     }
 }
Beispiel #17
0
 public static CngKey Duplicate(CngKey key)
 {
     using (SafeNCryptKeyHandle keyHandle = key.Handle)
     {
         return CngKey.Open(keyHandle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None);
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="CngCryptographicKey"/> class.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="eccPrivateKeyBlob">The ECC Private key blob from which this key was imported, if applicable.</param>
        internal CngCryptographicKey(CngKey key, byte[] eccPrivateKeyBlob)
        {
            Requires.NotNull(key, "key");

            this.key = key;
            this.eccPrivateKeyBlob = eccPrivateKeyBlob.CloneArray();
        }
 internal ECDiffieHellmanCngPublicKey(CngKey key) : base(key.Export(CngKeyBlobFormat.EccPublicBlob))
 {
     this.m_format = CngKeyBlobFormat.EccPublicBlob;
     new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
     this.m_key = CngKey.Open(key.Handle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None);
     CodeAccessPermission.RevertAssert();
 }
 private void CreateKeys()
 {
   
     _aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP521);
     _bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP521);
     _alicePubKeyBlob = _aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
     _bobPubKeyBlob = _bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
 }
        private string Curve(CngKey key)
        {
            if (key.Algorithm == CngAlgorithm.ECDiffieHellmanP256) return "P-256";
            if (key.Algorithm == CngAlgorithm.ECDiffieHellmanP384) return "P-384";
            if (key.Algorithm == CngAlgorithm.ECDiffieHellmanP521) return "P-521";

            throw new ArgumentException("Unknown curve type " + key.Algorithm);
        }
 public override string ToXmlString()
 {
     if (this.m_key == null)
     {
         this.m_key = this.Import();
     }
     return Rfc4050KeyFormatter.ToXml(this.m_key);
 }
Beispiel #23
0
        public void WritePublicKey(CngKey cngKey)
        {
            var writer = GetWriterFor(cngKey.Algorithm);

            _stream.Write(Headerbytes, 0, Headerbytes.Count());
            writer.Write(cngKey, _stream);
            _stream.Write(Footerbytes, 0, Footerbytes.Count());
        }
 private byte[] AddSignatureToHash(byte[] hash, CngKey key)
 {
     using (var signingAlg = new RSACng(key))
     {
         byte[] signed = signingAlg.SignHash(hash, HashAlgorithmName.SHA384, RSASignaturePadding.Pss);
         return signed;
     }
 }
 /// <summary>
 /// Exports a private key.
 /// </summary>
 /// <param name="Path">The path to export to.</param>
 /// <param name="PrivateKey">The key to export.</param>
 public static void ExportKey(string Path, CngKey PrivateKey)
 {
     using (BinaryWriter Writer = new BinaryWriter(File.Create(Path)))
     {
         Writer.Write((byte)PrivateKey.Export(CngKeyBlobFormat.EccPrivateBlob).Length);
         Writer.Write(PrivateKey.Export(CngKeyBlobFormat.EccPrivateBlob));
     }
 }
Beispiel #26
0
        /// <summary>
        ///     Wrap an existing key handle with a CngKey object
        /// </summary>
        public static CngKey Open(SafeNCryptKeyHandle keyHandle, CngKeyHandleOpenOptions keyHandleOpenOptions)
        {
            if (keyHandle == null)
                throw new ArgumentNullException("keyHandle");
            if (keyHandle.IsClosed || keyHandle.IsInvalid)
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, "keyHandle");

            SafeNCryptKeyHandle keyHandleCopy = keyHandle.Duplicate();

            // Get a handle to the key's provider.
            SafeNCryptProviderHandle providerHandle = new SafeNCryptProviderHandle();
            IntPtr rawProviderHandle = keyHandle.GetPropertyAsIntPtr(KeyPropertyName.ProviderHandle, CngPropertyOptions.None);
            providerHandle.SetHandleValue(rawProviderHandle);

            // Set up a key object wrapping the handle
            CngKey key = null;
            try
            {
                key = new CngKey(providerHandle, keyHandleCopy);
                bool openingEphemeralKey = (keyHandleOpenOptions & CngKeyHandleOpenOptions.EphemeralKey) == CngKeyHandleOpenOptions.EphemeralKey;

                //
                // If we're wrapping a handle to an ephemeral key, we need to make sure that IsEphemeral is
                // set up to return true.  In the case that the handle is for an ephemeral key that was created
                // by the CLR, then we don't have anything to do as the IsEphemeral CLR property will already
                // be setup.  However, if the key was created outside of the CLR we will need to setup our
                // ephemeral detection property.
                // 
                // This enables consumers of CngKey objects to always be able to rely on the result of
                // calling IsEphemeral, and also allows them to safely access the Name property.
                // 
                // Finally, if we detect that this is an ephemeral key that the CLR created but we were not
                // told that it was an ephemeral key we'll throw an exception.  This prevents us from having
                // to decide who to believe -- the key property or the caller of the API.  Since other code
                // relies on the ephemeral flag being set properly to avoid tripping over bugs in CNG, we
                // need to reject the case that we suspect that the flag is incorrect.
                // 

                if (!key.IsEphemeral && openingEphemeralKey)
                {
                    key.IsEphemeral = true;
                }
                else if (key.IsEphemeral && !openingEphemeralKey)
                {
                    throw new ArgumentException(SR.Cryptography_OpenEphemeralKeyHandleWithoutEphemeralFlag, "keyHandleOpenOptions");
                }
            }
            catch
            {
                // Make sure that we don't leak the handle the CngKey duplicated
                if (key != null)
                    key.Dispose();

                throw;
            }

            return key;
        }
Beispiel #27
0
        /// <summary>
        ///     Creates a new ECDsaCng object that will use the specified key. The key's
        ///     <see cref="CngKey.AlgorithmGroup" /> must be ECDsa. This constructor
        ///     creates a copy of the key. Hence, the caller can safely dispose of the 
        ///     passed in key and continue using the ECDsaCng object. 
        /// </summary>
        /// <param name="key">Key to use for ECDsa operations</param>
        /// <exception cref="ArgumentException">if <paramref name="key" /> is not an ECDsa key</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="key" /> is null.</exception>
        public ECDsaCng(CngKey key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            if (key.AlgorithmGroup != CngAlgorithmGroup.ECDsa)
                throw new ArgumentException(SR.Cryptography_ArgECDsaRequiresECDsaKey, "key");

            Key = CngAlgorithmCore.Duplicate(key);
        }
Beispiel #28
0
        /// <summary>
        ///     Creates a new DSACng object that will use the specified key. The key's
        ///     <see cref="CngKey.AlgorithmGroup" /> must be Dsa. This constructor
        ///     creates a copy of the key. Hence, the caller can safely dispose of the 
        ///     passed in key and continue using the DSACng object. 
        /// </summary>
        /// <param name="key">Key to use for DSA operations</param>
        /// <exception cref="ArgumentException">if <paramref name="key" /> is not an DSA key</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="key" /> is null.</exception>
        public DSACng(CngKey key)
        {
            if (key == null)
                throw new ArgumentNullException(nameof(key));

            if (key.AlgorithmGroup != CngAlgorithmGroup.Dsa)
                throw new ArgumentException(SR.Cryptography_ArgDSARequiresDSAKey, nameof(key));

            Key = CngAlgorithmCore.Duplicate(key);
        }
Beispiel #29
0
        /// <summary>
        ///     Creates a new ECDsaCng object that will use the specified key. The key's
        ///     <see cref="CngKey.AlgorithmGroup" /> must be ECDsa. This constructor
        ///     creates a copy of the key. Hence, the caller can safely dispose of the 
        ///     passed in key and continue using the ECDsaCng object. 
        /// </summary>
        /// <param name="key">Key to use for ECDsa operations</param>
        /// <exception cref="ArgumentException">if <paramref name="key" /> is not an ECDsa key</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="key" /> is null.</exception>
        public ECDsaCng(CngKey key)
        {
            if (key == null)
                throw new ArgumentNullException(nameof(key));

            if (!IsEccAlgorithmGroup(key.AlgorithmGroup))
                throw new ArgumentException(SR.Cryptography_ArgECDsaRequiresECDsaKey, nameof(key));

            Key = CngAlgorithmCore.Duplicate(key);
        }
Beispiel #30
0
        /// <summary>
        ///     Creates a new RSACng object that will use the specified key. The key's
        ///     <see cref="CngKey.AlgorithmGroup" /> must be Rsa. This constructor
        ///     creates a copy of the key. Hence, the caller can safely dispose of the 
        ///     passed in key and continue using the RSACng object. 
        /// </summary>
        /// <param name="key">Key to use for RSA operations</param>
        /// <exception cref="ArgumentException">if <paramref name="key" /> is not an RSA key</exception>
        /// <exception cref="ArgumentNullException">if <paramref name="key" /> is null.</exception>
        public RSACng(CngKey key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            if (key.AlgorithmGroup != CngAlgorithmGroup.Rsa)
                throw new ArgumentException(SR.Cryptography_ArgRSAaRequiresRSAKey, "key");

            _legalKeySizesValue = s_legalKeySizes;
            Key = CngAsymmetricAlgorithmCore.Duplicate(key);
        }
Beispiel #31
0
        public RSACng(CngKey key)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            LegalKeySizesValue = s_legalKeySizes;

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
            Key = CngKey.Open(key.Handle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None);
            CodeAccessPermission.RevertAssert();
        }
Beispiel #32
0
        public static byte[] SignData(byte[] prikey, byte[] data)
        {
            var PublicKey = ThinNeo.Cryptography.ECC.ECCurve.Secp256r1.G * prikey;

            byte[] pubkey = PublicKey.EncodePoint(false).Skip(1).ToArray();


            //签名的私钥
            byte[] first      = { 0x45, 0x43, 0x53, 0x32, 0x20, 0x00, 0x00, 0x00 };
            byte[] signprikey = first.Concat(pubkey).Concat(prikey).ToArray();

            using (System.Security.Cryptography.CngKey key = System.Security.Cryptography.CngKey.Import(signprikey, System.Security.Cryptography.CngKeyBlobFormat.EccPrivateBlob))
            {
                using (System.Security.Cryptography.ECDsaCng ecdsa = new System.Security.Cryptography.ECDsaCng(key))
                {
                    var hashsrc  = sha256.ComputeHash(data);
                    var signdata = ecdsa.SignHash(hashsrc);
                    return(signdata);
                }
            }
        }
Beispiel #33
0
        /// <summary>
        ///     Given a second party's public key, derive shared key material
        /// </summary>
        public override byte[] DeriveKeyMaterial(ECDiffieHellmanPublicKey otherPartyPublicKey)
        {
            Contract.Ensures(Contract.Result <byte[]>() != null);
            Contract.Assert(m_kdf >= ECDiffieHellmanKeyDerivationFunction.Hash &&
                            m_kdf <= ECDiffieHellmanKeyDerivationFunction.Tls);

            if (otherPartyPublicKey == null)
            {
                throw new ArgumentNullException("otherPartyPublicKey");
            }

            // We can only work with ECDiffieHellmanCngPublicKeys
            ECDiffieHellmanCngPublicKey otherKey = otherPartyPublicKey as ECDiffieHellmanCngPublicKey;

            if (otherPartyPublicKey == null)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_ArgExpectedECDiffieHellmanCngPublicKey));
            }

            using (CngKey import = otherKey.Import()) {
                return(DeriveKeyMaterial(import));
            }
        }
Beispiel #34
0
        public ECDsaCng(CngKey key)
        {
            Contract.Ensures(LegalKeySizesValue != null);
            Contract.Ensures(m_key != null && m_key.AlgorithmGroup == CngAlgorithmGroup.ECDsa);

            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            if (key.AlgorithmGroup != CngAlgorithmGroup.ECDsa)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDsaRequiresECDsaKey), "key");
            }

            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(SR.GetString(SR.Cryptography_PlatformNotSupported));
            }

            LegalKeySizesValue = s_legalKeySizes;

            // Make a copy of the key so that we continue to work if it gets disposed before this algorithm
            //
            // This requires an assert for UnmanagedCode since we'll need to access the raw handles of the key
            // and the handle constructor of CngKey.  The assert is safe since ECDsaCng will never expose the
            // key handles to calling code (without first demanding UnmanagedCode via the Handle property of
            // CngKey).
            //
            // We also need to dispose of the key handle since CngKey.Handle returns a duplicate
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
            using (SafeNCryptKeyHandle keyHandle = key.Handle) {
                Key = CngKey.Open(keyHandle, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None);
            }
            CodeAccessPermission.RevertAssert();

            KeySize = m_key.KeySize;
        }
Beispiel #35
0
        public static CngKey Create(CngAlgorithm algorithm, string keyName, CngKeyCreationParameters creationParameters)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            if (creationParameters == null)
            {
                creationParameters = new CngKeyCreationParameters();
            }
            if (!NCryptNative.NCryptSupported)
            {
                throw new PlatformNotSupportedException(System.SR.GetString("Cryptography_PlatformNotSupported"));
            }
            if (keyName != null)
            {
                KeyContainerPermissionAccessEntry accessEntry = new KeyContainerPermissionAccessEntry(keyName, KeyContainerPermissionFlags.Create)
                {
                    ProviderName = creationParameters.Provider.Provider
                };
                KeyContainerPermission permission = new KeyContainerPermission(KeyContainerPermissionFlags.NoFlags);
                permission.AccessEntries.Add(accessEntry);
                permission.Demand();
            }
            SafeNCryptProviderHandle provider  = NCryptNative.OpenStorageProvider(creationParameters.Provider.Provider);
            SafeNCryptKeyHandle      keyHandle = NCryptNative.CreatePersistedKey(provider, algorithm.Algorithm, keyName, creationParameters.KeyCreationOptions);

            SetKeyProperties(keyHandle, creationParameters);
            NCryptNative.FinalizeKey(keyHandle);
            CngKey key = new CngKey(provider, keyHandle);

            if (keyName == null)
            {
                key.IsEphemeral = true;
            }
            return(key);
        }
        /// <summary>
        /// Constructs the core to use a stored CNG key.
        /// </summary>
        public CngSymmetricAlgorithmCore(ICngSymmetricAlgorithm outer, string keyName, CngProvider provider, CngKeyOpenOptions openOptions)
        {
            ArgumentNullException.ThrowIfNull(keyName);
            ArgumentNullException.ThrowIfNull(provider);

            _outer = outer;

            _keyName       = keyName;
            _provider      = provider;
            _optionOptions = openOptions;

            using (CngKey cngKey = ProduceCngKey())
            {
                CngAlgorithm actualAlgorithm = cngKey.Algorithm;
                string       algorithm       = _outer.GetNCryptAlgorithmIdentifier();

                if (algorithm != actualAlgorithm.Algorithm)
                {
                    throw new CryptographicException(SR.Format(SR.Cryptography_CngKeyWrongAlgorithm, actualAlgorithm.Algorithm, algorithm));
                }

                _outer.BaseKeySize = cngKey.KeySize;
            }
        }
Beispiel #37
0
        /// <summary>
        ///     Restore a key from XML
        /// </summary>
        internal static CngKey FromXml(string xml)
        {
            Contract.Requires(xml != null);
            Contract.Ensures(Contract.Result <CngKey>() != null);

            // Load the XML into an XPathNavigator to access sub elements
            using (TextReader textReader = new StringReader(xml))
                using (XmlTextReader xmlReader = new XmlTextReader(textReader)) {
                    XPathDocument  document  = new XPathDocument(xmlReader);
                    XPathNavigator navigator = document.CreateNavigator();

                    // Move into the root element - we don't do a specific namespace check here for compatibility
                    // with XML that Windows generates.
                    if (!navigator.MoveToFirstChild())
                    {
                        throw new ArgumentException(SR.GetString(SR.Cryptography_MissingDomainParameters));
                    }

                    // First figure out which algorithm this key belongs to
                    CngAlgorithm algorithm = ReadAlgorithm(navigator);

                    // Then read out the public key value
                    if (!navigator.MoveToNext(XPathNodeType.Element))
                    {
                        throw new ArgumentException(SR.GetString(SR.Cryptography_MissingPublicKey));
                    }

                    BigInteger x;
                    BigInteger y;
                    ReadPublicKey(navigator, out x, out y);

                    // Finally, convert them into a key blob to import into a CngKey
                    byte[] keyBlob = NCryptNative.BuildEccPublicBlob(algorithm.Algorithm, x, y);
                    return(CngKey.Import(keyBlob, CngKeyBlobFormat.EccPublicBlob));
                }
        }
Beispiel #38
0
        /// <summary>
        ///     Get a handle to the secret agreement generated between two parties
        /// </summary>
        public SafeNCryptSecretHandle DeriveSecretAgreementHandle(ECDiffieHellmanPublicKey otherPartyPublicKey)
        {
            if (otherPartyPublicKey == null)
            {
                throw new ArgumentNullException(nameof(otherPartyPublicKey));
            }

            if (otherPartyPublicKey is ECDiffieHellmanCngPublicKey otherKey)
            {
                using (CngKey importedKey = otherKey.Import())
                {
                    return(DeriveSecretAgreementHandle(importedKey));
                }
            }

            ECParameters otherPartyParameters = otherPartyPublicKey.ExportParameters();

            using (ECDiffieHellmanCng otherPartyCng = (ECDiffieHellmanCng)Create(otherPartyParameters))
                using (otherKey = (ECDiffieHellmanCngPublicKey)otherPartyCng.PublicKey)
                    using (CngKey importedKey = otherKey.Import())
                    {
                        return(DeriveSecretAgreementHandle(importedKey));
                    }
        }
        public BasicSymmetricCipherLiteNCrypt(
            Func <CngKey> cngKeyFactory,
            CipherMode cipherMode,
            int blockSizeInBytes,
            ReadOnlySpan <byte> iv,
            bool encrypting,
            int paddingSizeInBytes)
        {
            BlockSizeInBytes   = blockSizeInBytes;
            PaddingSizeInBytes = paddingSizeInBytes;
            _encrypting        = encrypting;
            _key = cngKeyFactory();
            CngProperty chainingModeProperty = cipherMode switch
            {
                CipherMode.ECB => s_ECBMode,
                CipherMode.CBC => s_CBCMode,
                CipherMode.CFB => s_CFBMode,
                _ => throw new CryptographicException(SR.Cryptography_InvalidCipherMode),
            };

            _key.SetProperty(chainingModeProperty);

            Reset(iv);
        }
 public void Dispose()
 {
     _key?.Dispose();
     _key = null !;
 }
Beispiel #41
0
        private CngKey GetKey(
#if !NETNATIVE
            ECCurve?curve = null
#endif
            )
        {
            CngKey       key       = null;
            CngAlgorithm algorithm = null;
            int          keySize   = 0;

#if !NETNATIVE
            if (curve != null)
            {
                if (curve.Value.IsNamed)
                {
                    // Map curve name to algorithm to support pre-Win10 curves
                    CngAlgorithm alg = CngKey.EcdsaCurveNameToAlgorithm(curve.Value.Oid.FriendlyName);
                    if (CngKey.IsECNamedCurve(alg.Algorithm))
                    {
                        key = _core.GetOrGenerateKey(curve.Value);
                    }
                    else
                    {
                        // Get the proper KeySize from algorithm name
                        if (alg == CngAlgorithm.ECDsaP256)
                        {
                            keySize = 256;
                        }
                        else if (alg == CngAlgorithm.ECDsaP384)
                        {
                            keySize = 384;
                        }
                        else if (alg == CngAlgorithm.ECDsaP521)
                        {
                            keySize = 521;
                        }
                        else
                        {
                            Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString()));
                            throw new ArgumentException(SR.Cryptography_InvalidKeySize);
                        }
                        key = _core.GetOrGenerateKey(keySize, alg);
                    }
                    ForceSetKeySize(key.KeySize);
                }
                else if (curve.Value.IsExplicit)
                {
                    key = _core.GetOrGenerateKey(curve.Value);
                    ForceSetKeySize(key.KeySize);
                }
                else
                {
                    throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Value.CurveType.ToString()));
                }
            }
            else if (_core.IsKeyGeneratedNamedCurve())
            {
                key = _core.GetOrGenerateKey(null);
            }
            else
#endif
            {
                // Map the current key size to a CNG algorithm name
                keySize = KeySize;
                switch (keySize)
                {
                case 256: algorithm = CngAlgorithm.ECDsaP256; break;

                case 384: algorithm = CngAlgorithm.ECDsaP384; break;

                case 521: algorithm = CngAlgorithm.ECDsaP521; break;

                default:
                    Debug.Fail("Should not have invalid key size");
                    throw new ArgumentException(SR.Cryptography_InvalidKeySize);
                }
                key = _core.GetOrGenerateKey(keySize, algorithm);
            }

            return(key);
        }
Beispiel #42
0
 public ECDiffieHellmanCng(CngKey key !!)
 {
     if (key.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman)
Beispiel #43
0
        /// <summary>
        ///     Wrap an existing key handle with a CngKey object
        /// </summary>
        public static CngKey Open(SafeNCryptKeyHandle keyHandle, CngKeyHandleOpenOptions keyHandleOpenOptions)
        {
            if (keyHandle == null)
            {
                throw new ArgumentNullException(nameof(keyHandle));
            }
            if (keyHandle.IsClosed || keyHandle.IsInvalid)
            {
                throw new ArgumentException(SR.Cryptography_OpenInvalidHandle, nameof(keyHandle));
            }

            SafeNCryptKeyHandle keyHandleCopy = keyHandle.Duplicate();

            // Get a handle to the key's provider.
            SafeNCryptProviderHandle providerHandle = new SafeNCryptProviderHandle();
            IntPtr rawProviderHandle = keyHandle.GetPropertyAsIntPtr(KeyPropertyName.ProviderHandle, CngPropertyOptions.None);

            providerHandle.SetHandleValue(rawProviderHandle);

            // Set up a key object wrapping the handle
            CngKey?key = null;

            try
            {
                key = new CngKey(providerHandle, keyHandleCopy);
                bool openingEphemeralKey = (keyHandleOpenOptions & CngKeyHandleOpenOptions.EphemeralKey) == CngKeyHandleOpenOptions.EphemeralKey;

                //
                // If we're wrapping a handle to an ephemeral key, we need to make sure that IsEphemeral is
                // set up to return true.  In the case that the handle is for an ephemeral key that was created
                // by the CLR, then we don't have anything to do as the IsEphemeral CLR property will already
                // be setup.  However, if the key was created outside of the CLR we will need to setup our
                // ephemeral detection property.
                //
                // This enables consumers of CngKey objects to always be able to rely on the result of
                // calling IsEphemeral, and also allows them to safely access the Name property.
                //
                // Finally, if we detect that this is an ephemeral key that the CLR created but we were not
                // told that it was an ephemeral key we'll throw an exception.  This prevents us from having
                // to decide who to believe -- the key property or the caller of the API.  Since other code
                // relies on the ephemeral flag being set properly to avoid tripping over bugs in CNG, we
                // need to reject the case that we suspect that the flag is incorrect.
                //

                if (!key.IsEphemeral && openingEphemeralKey)
                {
                    key.IsEphemeral = true;
                }
                else if (key.IsEphemeral && !openingEphemeralKey)
                {
                    throw new ArgumentException(SR.Cryptography_OpenEphemeralKeyHandleWithoutEphemeralFlag, nameof(keyHandleOpenOptions));
                }
            }
            catch
            {
                // Make sure that we don't leak the handle the CngKey duplicated
                if (key != null)
                {
                    key.Dispose();
                }

                throw;
            }

            return(key);
        }
 public SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey)
 {
     throw new NotImplementedException();
 }
Beispiel #45
0
        internal static CngKey Import(byte[] keyBlob, ECCurve?curve, CngKeyBlobFormat format, CngProvider provider)
        {
#endif //!NETNATIVE
            if (keyBlob == null)
            {
                throw new ArgumentNullException(nameof(keyBlob));
            }
            if (format == null)
            {
                throw new ArgumentNullException(nameof(format));
            }
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

            SafeNCryptProviderHandle providerHandle = provider.OpenStorageProvider();
            SafeNCryptKeyHandle      keyHandle;
            ErrorCode errorCode;

#if !NETNATIVE
            if (curve == null)
#endif //!NETNATIVE
            {
                errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, IntPtr.Zero, out keyHandle, keyBlob, keyBlob.Length, 0);
                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    throw errorCode.ToCryptographicException();
                }
            }
#if !NETNATIVE
            else
            {
                // Call with Oid.FriendlyName because .Value will result in an invalid parameter error
                Debug.Assert(curve.Value.IsNamed);
                string curveName = curve.Value.Oid.FriendlyName;
                using (SafeUnicodeStringHandle safeCurveName = new SafeUnicodeStringHandle(curveName))
                {
                    var desc = new Interop.BCrypt.BCryptBufferDesc();
                    var buff = new Interop.BCrypt.BCryptBuffer();

                    IntPtr descPtr = IntPtr.Zero;
                    IntPtr buffPtr = IntPtr.Zero;
                    try
                    {
                        descPtr         = Marshal.AllocHGlobal(Marshal.SizeOf(desc));
                        buffPtr         = Marshal.AllocHGlobal(Marshal.SizeOf(buff));
                        buff.cbBuffer   = (curveName.Length + 1) * 2; // Add 1 for null terminator
                        buff.BufferType = Interop.BCrypt.NCryptBufferDescriptors.NCRYPTBUFFER_ECC_CURVE_NAME;
                        buff.pvBuffer   = safeCurveName.DangerousGetHandle();
                        Marshal.StructureToPtr(buff, buffPtr, false);

                        desc.cBuffers  = 1;
                        desc.pBuffers  = buffPtr;
                        desc.ulVersion = Interop.BCrypt.BCRYPTBUFFER_VERSION;
                        Marshal.StructureToPtr(desc, descPtr, false);

                        errorCode = Interop.NCrypt.NCryptImportKey(providerHandle, IntPtr.Zero, format.Format, descPtr, out keyHandle, keyBlob, keyBlob.Length, 0);
                    }
                    finally
                    {
                        Marshal.FreeHGlobal(descPtr);
                        Marshal.FreeHGlobal(buffPtr);
                    }
                }

                if (errorCode != ErrorCode.ERROR_SUCCESS)
                {
                    Exception e = errorCode.ToCryptographicException();
                    if (errorCode == ErrorCode.NTE_INVALID_PARAMETER)
                    {
                        throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curveName), e);
                    }
                    throw e;
                }
            }
#endif //!NETNATIVE

            CngKey key = new CngKey(providerHandle, keyHandle);

            // We can't tell directly if an OpaqueTransport blob imported as an ephemeral key or not
            key.IsEphemeral = format != CngKeyBlobFormat.OpaqueTransportBlob;

            return(key);
        }
Beispiel #46
0
 public ECDsaCng(CngKey key)
 {
     Contract.Ensures(this.Key.AlgorithmGroup != null);
     Contract.Ensures(this.Key.AlgorithmGroup == System.Security.Cryptography.CngAlgorithmGroup.ECDsa);
     Contract.Ensures(this.LegalKeySizesValue != null);
 }
Beispiel #47
0
        public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey)
        {
            if (otherPartyPublicKey == null)
            {
                throw new ArgumentNullException(nameof(otherPartyPublicKey));
            }
            if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman)
            {
                throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey));
            }
            if (otherPartyPublicKey.KeySize != KeySize)
            {
                throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey));
            }

            // Setting the flag to UseSecretAsHmacKey even when the KDF isn't HMAC, because that's what NetFx does.
            Interop.NCrypt.SecretAgreementFlags flags =
                UseSecretAgreementAsHmacKey
                    ? Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey
                    : Interop.NCrypt.SecretAgreementFlags.None;

            using (SafeNCryptSecretHandle handle = DeriveSecretAgreementHandle(otherPartyPublicKey))
            {
                switch (KeyDerivationFunction)
                {
                case ECDiffieHellmanKeyDerivationFunction.Hash:
                    return(Interop.NCrypt.DeriveKeyMaterialHash(
                               handle,
                               HashAlgorithm.Algorithm,
                               _secretPrepend,
                               _secretAppend,
                               flags));

                case ECDiffieHellmanKeyDerivationFunction.Hmac:
                    return(Interop.NCrypt.DeriveKeyMaterialHmac(
                               handle,
                               HashAlgorithm.Algorithm,
                               _hmacKey,
                               _secretPrepend,
                               _secretAppend,
                               flags));

                case ECDiffieHellmanKeyDerivationFunction.Tls:
                    if (_label == null || _seed == null)
                    {
                        throw new InvalidOperationException(SR.Cryptography_TlsRequiresLabelAndSeed);
                    }

                    return(Interop.NCrypt.DeriveKeyMaterialTls(
                               handle,
                               _label,
                               _seed,
                               flags));

                default:
                    Debug.Fail($"Unknown KDF ({KeyDerivationFunction})");
                    // Match NetFx behavior
                    goto case ECDiffieHellmanKeyDerivationFunction.Tls;
                }
            }
        }
Beispiel #48
0
        internal static CngKey Create(ECCurve curve, Func <string, CngAlgorithm> algorithmResolver)
        {
            System.Diagnostics.Debug.Assert(algorithmResolver != null);

            curve.Validate();

            CngKeyCreationParameters creationParameters = new CngKeyCreationParameters
            {
                ExportPolicy = CngExportPolicies.AllowPlaintextExport,
            };

            CngAlgorithm alg;

            if (curve.IsNamed)
            {
                if (string.IsNullOrEmpty(curve.Oid.FriendlyName))
                {
                    throw new PlatformNotSupportedException(string.Format(SR.Cryptography_InvalidCurveOid, curve.Oid.Value));
                }

                // Map curve name to algorithm to support pre-Win10 curves
                alg = algorithmResolver(curve.Oid.FriendlyName);

                if (CngKey.IsECNamedCurve(alg.Algorithm))
                {
                    creationParameters.Parameters.Add(GetPropertyFromNamedCurve(curve));
                }
                else
                {
                    if (alg == CngAlgorithm.ECDsaP256 || alg == CngAlgorithm.ECDiffieHellmanP256 ||
                        alg == CngAlgorithm.ECDsaP384 || alg == CngAlgorithm.ECDiffieHellmanP384 ||
                        alg == CngAlgorithm.ECDsaP521 || alg == CngAlgorithm.ECDiffieHellmanP521)
                    {
                        // No parameters required, the algorithm ID has everything built-in.
                    }
                    else
                    {
                        Debug.Fail(string.Format("Unknown algorithm {0}", alg.ToString()));
                        throw new ArgumentException(SR.Cryptography_InvalidKeySize);
                    }
                }
            }
            else if (curve.IsPrime)
            {
                byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref curve);

                CngProperty prop = new CngProperty(
                    KeyPropertyName.ECCParameters,
                    parametersBlob,
                    CngPropertyOptions.None);

                creationParameters.Parameters.Add(prop);
                alg = algorithmResolver(null);
            }
            else
            {
                throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.CurveType.ToString()));
            }

            try
            {
                return(Create(alg, null, creationParameters));
            }
            catch (CryptographicException e)
            {
                Interop.NCrypt.ErrorCode errorCode = (Interop.NCrypt.ErrorCode)e.HResult;

                if (errorCode == Interop.NCrypt.ErrorCode.NTE_INVALID_PARAMETER ||
                    errorCode == Interop.NCrypt.ErrorCode.NTE_NOT_SUPPORTED)
                {
                    string target = curve.IsNamed ? curve.Oid.FriendlyName : curve.CurveType.ToString();
                    throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, target), e);
                }

                throw;
            }
        }
        internal static byte[] ExportFullKeyBlob(CngKey key, bool includePrivateParameters)
        {
            CngKeyBlobFormat blobFormat = includePrivateParameters ? CngKeyBlobFormat.EccFullPrivateBlob : CngKeyBlobFormat.EccFullPublicBlob;

            return(key.Export(blobFormat));
        }
Beispiel #50
0
 public ECDsaCng(CngKey key !!)
 {
     if (!IsEccAlgorithmGroup(key.AlgorithmGroup))
 public CngKey Import()
 {
     return(CngKey.Import(this.ToByteArray(), this.BlobFormat));
 }
Beispiel #52
0
        public Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle DeriveSecretAgreementHandle(CngKey otherPartyPublicKey)
        {
            Contract.Ensures(this.Key.Handle != null);

            return(default(Microsoft.Win32.SafeHandles.SafeNCryptSecretHandle));
        }
Beispiel #53
0
 public DSACng(CngKey key !!)
 {
     if (key.AlgorithmGroup != CngAlgorithmGroup.Dsa)
 public DSACng(System.Security.Cryptography.CngKey key)
 {
 }
Beispiel #55
0
        public override void ImportParameters(RSAParameters parameters)
        {
            if (parameters.Exponent == null || parameters.Modulus == null)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_InvalidRsaParameters));
            }
            bool publicOnly = parameters.P == null || parameters.Q == null;

            //
            // We need to build a key blob structured as follows:
            //     BCRYPT_RSAKEY_BLOB   header
            //     byte[cbPublicExp]    publicExponent      - Exponent
            //     byte[cbModulus]      modulus             - Modulus
            //     -- Private only --
            //     byte[cbPrime1]       prime1              - P
            //     byte[cbPrime2]       prime2              - Q
            //

            int blobSize = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB)) +
                           parameters.Exponent.Length +
                           parameters.Modulus.Length;

            if (!publicOnly)
            {
                blobSize += parameters.P.Length +
                            parameters.Q.Length;
            }

            byte[] rsaBlob = new byte[blobSize];
            unsafe
            {
                fixed(byte *pRsaBlob = rsaBlob)
                {
                    // Build the header
                    BCryptNative.BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCryptNative.BCRYPT_RSAKEY_BLOB *)pRsaBlob;
                    pBcryptBlob->Magic = publicOnly ? BCryptNative.KeyBlobMagicNumber.RsaPublic :
                                         BCryptNative.KeyBlobMagicNumber.RsaPrivate;

                    pBcryptBlob->BitLength = parameters.Modulus.Length * 8;

                    pBcryptBlob->cbPublicExp = parameters.Exponent.Length;
                    pBcryptBlob->cbModulus   = parameters.Modulus.Length;

                    if (!publicOnly)
                    {
                        pBcryptBlob->cbPrime1 = parameters.P.Length;
                        pBcryptBlob->cbPrime2 = parameters.Q.Length;
                    }

                    int offset = Marshal.SizeOf(typeof(BCryptNative.BCRYPT_RSAKEY_BLOB));

                    // Copy the exponent
                    Buffer.BlockCopy(parameters.Exponent, 0, rsaBlob, offset, parameters.Exponent.Length);
                    offset += parameters.Exponent.Length;

                    // Copy the modulus
                    Buffer.BlockCopy(parameters.Modulus, 0, rsaBlob, offset, parameters.Modulus.Length);
                    offset += parameters.Modulus.Length;

                    if (!publicOnly)
                    {
                        // Copy P
                        Buffer.BlockCopy(parameters.P, 0, rsaBlob, offset, parameters.P.Length);
                        offset += parameters.P.Length;

                        // Copy Q
                        Buffer.BlockCopy(parameters.Q, 0, rsaBlob, offset, parameters.Q.Length);
                        offset += parameters.Q.Length;
                    }
                }
            }
            Key = CngKey.Import(rsaBlob, publicOnly ? s_rsaPublicBlob : s_rsaPrivateBlob);
        }
Beispiel #56
0
 public ECDsaCng(CngKey key)
 {
     throw new NotImplementedException();
 }
Beispiel #57
0
 public static CngKey Duplicate(CngKey key)
 {
     return(CngKey.Open(key.HandleNoDuplicate, key.IsEphemeral ? CngKeyHandleOpenOptions.EphemeralKey : CngKeyHandleOpenOptions.None));
 }
Beispiel #58
0
        internal static ECParameters ExportPrimeCurveParameters(CngKey key, bool includePrivateParameters)
        {
            byte[] ecBlob = ExportFullKeyBlob(key, includePrivateParameters);
            // We now have a buffer laid out as follows:
            //     BCRYPT_ECCFULLKEY_BLOB       header
            //     byte[cbFieldLength]          P
            //     byte[cbFieldLength]          A
            //     byte[cbFieldLength]          B
            //     byte[cbFieldLength]          G.X
            //     byte[cbFieldLength]          G.Y
            //     byte[cbSubgroupOrder]        Order (n)
            //     byte[cbCofactor]             Cofactor (h)
            //     byte[cbSeed]                 Seed
            //     byte[cbFieldLength]          Q.X
            //     byte[cbFieldLength]          Q.Y
            //     -- Private only --
            //     byte[cbSubgroupOrder]        D

            ECParameters ecParams = new ECParameters();

            KeyBlobMagicNumber magic = (KeyBlobMagicNumber)BitConverter.ToInt32(ecBlob, 0);

            // Check the magic value in the key blob header. If the blob does not have the required magic,
            // then throw a CryptographicException.
            CheckMagicValueOfKey(magic, includePrivateParameters);

            unsafe
            {
                // Fail-fast if a rogue provider gave us a blob that isn't even the size of the blob header.
                if (ecBlob.Length < sizeof(BCRYPT_ECCFULLKEY_BLOB))
                    throw ErrorCode.E_FAIL.ToCryptographicException();

                fixed(byte *pEcBlob = ecBlob)
                {
                    BCRYPT_ECCFULLKEY_BLOB *pBcryptBlob = (BCRYPT_ECCFULLKEY_BLOB *)pEcBlob;

                    var primeCurve = new ECCurve();

                    primeCurve.CurveType = ConvertToCurveTypeEnum(pBcryptBlob->CurveType);
                    primeCurve.Hash      = GetHashAlgorithmName(pBcryptBlob->CurveGenerationAlgId);

                    int offset = sizeof(BCRYPT_ECCFULLKEY_BLOB);

                    primeCurve.Prime = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength);
                    primeCurve.A     = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength);
                    primeCurve.B     = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength);
                    primeCurve.G     = new ECPoint()
                    {
                        X = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength),
                        Y = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength),
                    };
                    primeCurve.Order    = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbSubgroupOrder);
                    primeCurve.Cofactor = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbCofactor);

                    // Optional parameters
                    primeCurve.Seed = pBcryptBlob->cbSeed == 0 ? null : Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbSeed);

                    ecParams.Q = new ECPoint
                    {
                        X = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength),
                        Y = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbFieldLength)
                    };

                    if (includePrivateParameters)
                    {
                        ecParams.D = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbSubgroupOrder);
                    }

                    ecParams.Curve = primeCurve;
                    return(ecParams);
                }
            }
        }
        /// <summary>
        ///     <para>
        ///         ImportParameters will replace the existing key that RSACng is working with by creating a
        ///         new CngKey for the parameters structure. If the parameters structure contains only an
        ///         exponent and modulus, then only a public key will be imported. If the parameters also
        ///         contain P and Q values, then a full key pair will be imported.
        ///     </para>
        /// </summary>
        /// <exception cref="ArgumentException">
        ///     if <paramref name="parameters" /> contains neither an exponent nor a modulus.
        /// </exception>
        /// <exception cref="CryptographicException">
        ///     if <paramref name="parameters" /> is not a valid RSA key or if <paramref name="parameters"
        ///     /> is a full key pair and the default KSP is used.
        /// </exception>
        public override void ImportParameters(RSAParameters parameters)
        {
            unsafe
            {
                if (parameters.Exponent == null || parameters.Modulus == null)
                {
                    throw new CryptographicException(SR.Cryptography_InvalidRsaParameters);
                }

                bool includePrivate;
                if (parameters.D == null)
                {
                    includePrivate = false;
                    if (parameters.P != null || parameters.DP != null || parameters.Q != null || parameters.DQ != null || parameters.InverseQ != null)
                    {
                        throw new CryptographicException(SR.Cryptography_InvalidRsaParameters);
                    }
                }
                else
                {
                    includePrivate = true;
                    if (parameters.P == null || parameters.DP == null || parameters.Q == null || parameters.DQ == null || parameters.InverseQ == null)
                    {
                        throw new CryptographicException(SR.Cryptography_InvalidRsaParameters);
                    }
                }

                //
                // We need to build a key blob structured as follows:
                //
                //     BCRYPT_RSAKEY_BLOB   header
                //     byte[cbPublicExp]    publicExponent      - Exponent
                //     byte[cbModulus]      modulus             - Modulus
                //     -- Only if "includePrivate" is true --
                //     byte[cbPrime1]       prime1              - P
                //     byte[cbPrime2]       prime2              - Q
                //     ------------------
                //

                int blobSize = sizeof(BCRYPT_RSAKEY_BLOB) +
                               parameters.Exponent.Length +
                               parameters.Modulus.Length;
                if (includePrivate)
                {
                    blobSize += parameters.P.Length +
                                parameters.Q.Length;
                }

                byte[] rsaBlob = new byte[blobSize];
                fixed(byte *pRsaBlob = rsaBlob)
                {
                    // Build the header
                    BCRYPT_RSAKEY_BLOB *pBcryptBlob = (BCRYPT_RSAKEY_BLOB *)pRsaBlob;

                    pBcryptBlob->Magic       = includePrivate ? KeyBlobMagicNumber.BCRYPT_RSAPRIVATE_MAGIC : KeyBlobMagicNumber.BCRYPT_RSAPUBLIC_MAGIC;
                    pBcryptBlob->BitLength   = parameters.Modulus.Length * 8;
                    pBcryptBlob->cbPublicExp = parameters.Exponent.Length;
                    pBcryptBlob->cbModulus   = parameters.Modulus.Length;

                    if (includePrivate)
                    {
                        pBcryptBlob->cbPrime1 = parameters.P.Length;
                        pBcryptBlob->cbPrime2 = parameters.Q.Length;
                    }

                    int offset = sizeof(BCRYPT_RSAKEY_BLOB);

                    Emit(rsaBlob, ref offset, parameters.Exponent);
                    Emit(rsaBlob, ref offset, parameters.Modulus);

                    if (includePrivate)
                    {
                        Emit(rsaBlob, ref offset, parameters.P);
                        Emit(rsaBlob, ref offset, parameters.Q);
                    }

                    // We better have computed the right allocation size above!
                    Debug.Assert(offset == blobSize, "offset == blobSize");
                }

                CngKeyBlobFormat blobFormat = includePrivate ? s_rsaPrivateBlob : s_rsaPublicBlob;

                CngKey newKey = CngKey.Import(rsaBlob, blobFormat);
                newKey.ExportPolicy |= CngExportPolicies.AllowPlaintextExport;

                Key = newKey;
            }
        }
Beispiel #60
0
        public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey)
        {
            Contract.Ensures(Contract.Result <byte[]>() != null);
            Contract.Assert(m_kdf >= ECDiffieHellmanKeyDerivationFunction.Hash &&
                            m_kdf <= ECDiffieHellmanKeyDerivationFunction.Tls);

            if (otherPartyPublicKey == null)
            {
                throw new ArgumentNullException("otherPartyPublicKey");
            }
            if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHRequiresECDHKey), "otherPartyPublicKey");
            }
            if (otherPartyPublicKey.KeySize != KeySize)
            {
                throw new ArgumentException(SR.GetString(SR.Cryptography_ArgECDHKeySizeMismatch), "otherPartyPublicKey");
            }

            NCryptNative.SecretAgreementFlags flags =
                UseSecretAgreementAsHmacKey ? NCryptNative.SecretAgreementFlags.UseSecretAsHmacKey : NCryptNative.SecretAgreementFlags.None;

            // We require access to the handles for generating key material. This is safe since we will never
            // expose these handles to user code
            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();

            // This looks horribly wrong - but accessing the handle property actually returns a duplicate handle, which
            // we need to dispose of - otherwise, we're stuck keepign the resource alive until the GC runs.  This explicitly
            // is not disposing of the handle underlying the key dispite what the syntax looks like.
            using (SafeNCryptKeyHandle localKey = Key.Handle)
                using (SafeNCryptKeyHandle otherKey = otherPartyPublicKey.Handle) {
                    CodeAccessPermission.RevertAssert();

                    //
                    // Generating key material is a two phase process.
                    //   1. Generate the secret agreement
                    //   2. Pass the secret agreement through a KDF to get key material
                    //

                    using (SafeNCryptSecretHandle secretAgreement = NCryptNative.DeriveSecretAgreement(localKey, otherKey)) {
                        if (KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hash)
                        {
                            byte[] secretAppend  = SecretAppend == null ? null : SecretAppend.Clone() as byte[];
                            byte[] secretPrepend = SecretPrepend == null ? null : SecretPrepend.Clone() as byte[];

                            return(NCryptNative.DeriveKeyMaterialHash(secretAgreement,
                                                                      HashAlgorithm.Algorithm,
                                                                      secretPrepend,
                                                                      secretAppend,
                                                                      flags));
                        }
                        else if (KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Hmac)
                        {
                            byte[] hmacKey       = HmacKey == null ? null : HmacKey.Clone() as byte[];
                            byte[] secretAppend  = SecretAppend == null ? null : SecretAppend.Clone() as byte[];
                            byte[] secretPrepend = SecretPrepend == null ? null : SecretPrepend.Clone() as byte[];

                            return(NCryptNative.DeriveKeyMaterialHmac(secretAgreement,
                                                                      HashAlgorithm.Algorithm,
                                                                      hmacKey,
                                                                      secretPrepend,
                                                                      secretAppend,
                                                                      flags));
                        }
                        else
                        {
                            Debug.Assert(KeyDerivationFunction == ECDiffieHellmanKeyDerivationFunction.Tls, "Unknown KDF");

                            byte[] label = Label == null ? null : Label.Clone() as byte[];
                            byte[] seed  = Seed == null ? null : Seed.Clone() as byte[];

                            if (label == null || seed == null)
                            {
                                throw new InvalidOperationException(SR.GetString(SR.Cryptography_TlsRequiresLabelAndSeed));
                            }

                            return(NCryptNative.DeriveKeyMaterialTls(secretAgreement, label, seed, flags));
                        }
                    }
                }
        }