public static void DeleteKeyContainer(SafeCertContextHandle pCertContext)
        {
            if (pCertContext.IsInvalid)
            {
                return;
            }

            int  cb = 0;
            bool containsPrivateKey = Interop.crypt32.CertGetCertificateContextProperty(pCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, null, ref cb);

            if (!containsPrivateKey)
            {
                return;
            }

            byte[] provInfoAsBytes = new byte[cb];
            if (!Interop.crypt32.CertGetCertificateContextProperty(pCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, provInfoAsBytes, ref cb))
            {
                return;
            }

            unsafe
            {
                fixed(byte *pProvInfoAsBytes = provInfoAsBytes)
                {
                    CRYPT_KEY_PROV_INFO *pProvInfo = (CRYPT_KEY_PROV_INFO *)pProvInfoAsBytes;

                    string providerName     = pwszToString((IntPtr)(pProvInfo->pwszProvName));
                    string keyContainerName = pwszToString((IntPtr)(pProvInfo->pwszContainerName));

                    if (pProvInfo->dwProvType == 0)
                    {
                        // dwProvType being 0 indicates that the key is stored in CNG.
                        // dwProvType being non-zero indicates that the key is stored in CAPI.
                        try
                        {
                            using (CngKey cngKey = CngKey.Open(keyContainerName, new CngProvider(providerName)))
                            {
                                cngKey.Delete();
                            }
                        }
                        catch (CryptographicException)
                        {
                            // While leaving the file on disk is undesirable, an inability to perform this cleanup
                            // should not manifest itself to a user.
                        }
                    }
                    else
                    {
                        CryptAcquireContextFlags flags = (pProvInfo->dwFlags & CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET) | CryptAcquireContextFlags.CRYPT_DELETEKEYSET;
                        IntPtr hProv;
                        bool   success = Interop.cryptoapi.CryptAcquireContext(out hProv, keyContainerName, providerName, pProvInfo->dwProvType, flags);

                        // Called CryptAcquireContext solely for the side effect of deleting the key containers. When called with these flags, no actual
                        // hProv is returned (so there's nothing to clean up.)
                        Debug.Assert(hProv == IntPtr.Zero);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public static void VerifyMachineKey(
            CngAlgorithm algorithm,
            int plainBytesCount,
            Func <string, SymmetricAlgorithm> persistedFunc,
            Func <SymmetricAlgorithm> ephemeralFunc)
        {
            string keyName = Guid.NewGuid().ToString();
            CngKeyCreationParameters creationParameters = new CngKeyCreationParameters
            {
                Provider           = CngProvider.MicrosoftSoftwareKeyStorageProvider,
                ExportPolicy       = CngExportPolicies.AllowPlaintextExport,
                KeyCreationOptions = CngKeyCreationOptions.MachineKey,
            };

            CngKey cngKey = CngKey.Create(algorithm, keyName, creationParameters);

            try
            {
                VerifyPersistedKey(
                    keyName,
                    plainBytesCount,
                    persistedFunc,
                    ephemeralFunc,
                    CipherMode.CBC,
                    PaddingMode.PKCS7);
            }
            finally
            {
                // Delete also Disposes the key, no using should be added here.
                cngKey.Delete();
            }
        }
Ejemplo n.º 3
0
        //[Fact] - Keeping this test for reference but we don't want to run it as an inner-loop test because
        //         it creates a key on disk.
        public static void AesRoundTrip256BitsNoneECBUsingStoredKey()
        {
            CngAlgorithm algname = new CngAlgorithm("AES");
            string       keyName = "CoreFxTest-" + Guid.NewGuid();
            CngKey       _cngKey = CngKey.Create(algname, keyName);

            try
            {
                using (Aes alg = new AesCng(keyName))
                {
                    try
                    {
                        alg.Padding = PaddingMode.None;
                        alg.Mode    = CipherMode.ECB;

                        int keySize = alg.KeySize;

                        byte[] plainText         = "15a818701f0f7c99fe4b1b4b860f131b".HexToByteArray();
                        byte[] cipher            = alg.Encrypt(plainText);
                        byte[] decrypted         = alg.Decrypt(cipher);
                        byte[] expectedDecrypted = "15a818701f0f7c99fe4b1b4b860f131b".HexToByteArray();
                        Assert.Equal <byte>(expectedDecrypted, decrypted);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }
            }
            finally
            {
                _cngKey.Delete();
            }
        }
Ejemplo n.º 4
0
        public static void RemoveKeyFromCng(string providerName, string containerName)
        {
            CngProvider cngProvider = new CngProvider(providerName);

            CngKey cngKey = CngKey.Open(containerName, cngProvider);

            cngKey.Delete();
        }
Ejemplo n.º 5
0
        public static void DeleteKeyContainer(SafeCertContextHandle pCertContext)
        {
            if (pCertContext.IsInvalid)
            {
                return;
            }

            int  cb = 0;
            bool containsPrivateKey = Interop.crypt32.CertGetCertificateContextProperty(pCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, null, ref cb);

            if (!containsPrivateKey)
            {
                return;
            }

            byte[] provInfoAsBytes = new byte[cb];
            if (!Interop.crypt32.CertGetCertificateContextProperty(pCertContext, CertContextPropId.CERT_KEY_PROV_INFO_PROP_ID, provInfoAsBytes, ref cb))
            {
                return;
            }

            unsafe
            {
                fixed(byte *pProvInfoAsBytes = provInfoAsBytes)
                {
                    CRYPT_KEY_PROV_INFO *pProvInfo = (CRYPT_KEY_PROV_INFO *)pProvInfoAsBytes;

                    // For UWP the key was opened in a CNG-only context, so it can/should be deleted via CngKey.Delete.
                    // In all other contexts, the key was loaded into CAPI, so deleting it via CryptAcquireContext is
                    // the correct action.
#if NETNATIVE
                    string providerName     = Marshal.PtrToStringUni((IntPtr)(pProvInfo->pwszProvName));
                    string keyContainerName = Marshal.PtrToStringUni((IntPtr)(pProvInfo->pwszContainerName));

                    try
                    {
                        using (CngKey cngKey = CngKey.Open(keyContainerName, new CngProvider(providerName)))
                        {
                            cngKey.Delete();
                        }
                    }
                    catch (CryptographicException)
                    {
                        // While leaving the file on disk is undesirable, an inability to perform this cleanup
                        // should not manifest itself to a user.
                    }
#else
                    CryptAcquireContextFlags flags = (pProvInfo->dwFlags & CryptAcquireContextFlags.CRYPT_MACHINE_KEYSET) | CryptAcquireContextFlags.CRYPT_DELETEKEYSET;
                    IntPtr hProv;
                    bool   success = Interop.advapi32.CryptAcquireContext(out hProv, pProvInfo->pwszContainerName, pProvInfo->pwszProvName, pProvInfo->dwProvType, flags);

                    // Called CryptAcquireContext solely for the side effect of deleting the key containers. When called with these flags, no actual
                    // hProv is returned (so there's nothing to clean up.)
                    Debug.Assert(hProv == IntPtr.Zero);
#endif
                }
            }
        }
Ejemplo n.º 6
0
 public static void DeleteAESKey(string keyName)
 {
     if (CngKey.Exists(keyName, CngProvider.MicrosoftSoftwareKeyStorageProvider))
     {
         Console.WriteLine("Deleting Existing Key -:" + keyName);
         CngKey deleteKey = CngKey.Open(keyName, CngProvider.MicrosoftSoftwareKeyStorageProvider);
         deleteKey.Delete();
     }
 }
Ejemplo n.º 7
0
        public static void AssociatePersistedKey_CNG_DSA()
        {
            const string KeyName = nameof(AssociatePersistedKey_CNG_DSA);

            CngKey            cngKey        = null;
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256;

            byte[] signature;

            try
            {
                CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
                {
                    ExportPolicy       = CngExportPolicies.None,
                    Provider           = CngProvider.MicrosoftSoftwareKeyStorageProvider,
                    KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
                    Parameters         =
                    {
                        new CngProperty("Length", BitConverter.GetBytes(1024), CngPropertyOptions.None),
                    }
                };

                cngKey = CngKey.Create(new CngAlgorithm("DSA"), KeyName, creationParameters);

                using (DSACng dsaCng = new DSACng(cngKey))
                {
                    X509SignatureGenerator dsaGen = new DSAX509SignatureGenerator(dsaCng);

                    CertificateRequest request = new CertificateRequest(
                        new X500DistinguishedName($"CN={KeyName}"),
                        dsaGen.PublicKey,
                        HashAlgorithmName.SHA256);

                    DateTimeOffset now = DateTimeOffset.UtcNow;

                    using (X509Certificate2 cert = request.Create(request.SubjectName, dsaGen, now, now.AddDays(1), new byte[1]))
                        using (X509Certificate2 certWithPrivateKey = cert.CopyWithPrivateKey(dsaCng))
                            using (DSA dsa = certWithPrivateKey.GetDSAPrivateKey())
                            {
                                signature = dsa.SignData(Array.Empty <byte>(), hashAlgorithm);

                                Assert.True(dsaCng.VerifyData(Array.Empty <byte>(), signature, hashAlgorithm));
                            }
                }

                // Some certs have disposed, did they delete the key?
                using (CngKey stillPersistedKey = CngKey.Open(KeyName, CngProvider.MicrosoftSoftwareKeyStorageProvider))
                    using (DSACng dsaCng = new DSACng(stillPersistedKey))
                    {
                        dsaCng.SignData(Array.Empty <byte>(), hashAlgorithm);
                    }
            }
            finally
            {
                cngKey?.Delete();
            }
        }
Ejemplo n.º 8
0
        public static void RemoveKeyFromCng(string providerName, string containerName)
        {
#if NET5_0_OR_GREATER
            System.Diagnostics.Debug.Assert(OperatingSystem.IsWindows());
#endif
            CngProvider cngProvider = new CngProvider(providerName);

            CngKey cngKey = CngKey.Open(containerName, cngProvider);
            cngKey.Delete();
        }
Ejemplo n.º 9
0
        public X509Certificate2 CreateNamedKeyCertificate(CertData data)
        {
            try
            {
                CngKeyCreationParameters keyCreationParameters
                    = new CngKeyCreationParameters
                    {
                    ExportPolicy =
                        CngExportPolicies.AllowExport |
                        CngExportPolicies.AllowPlaintextExport |
                        CngExportPolicies.AllowPlaintextArchiving |
                        CngExportPolicies.AllowArchiving,
                    KeyUsage = CngKeyUsages.AllUsages
                    };

                X509Certificate2 cert;
                X509CertificateCreationParameters configCreate
                    = new X509CertificateCreationParameters(new X500DistinguishedName(data.DistinguishedName))
                    {
                    EndTime =
                        DateTime.Parse("01/01/2020",
                                       System.Globalization.
                                       DateTimeFormatInfo.
                                       InvariantInfo),
                    StartTime =
                        DateTime.Parse("01/01/2010",
                                       System.Globalization.
                                       DateTimeFormatInfo.
                                       InvariantInfo)
                    };

                using (CngKey namedKey = CngKey.Create(CngAlgorithm2.Rsa, data.Key, keyCreationParameters))
                {
                    cert = namedKey.CreateSelfSignedCertificate(configCreate);
                    cert.FriendlyName = data.Friendlyname;
                    Assert.True(cert.HasPrivateKey);
                    Assert.True(cert.HasCngKey());
                    using (CngKey certKey = cert.GetCngPrivateKey())
                    {
                        Assert.Equal(CngAlgorithm2.Rsa, certKey.Algorithm);
                    }
                }
                return(cert);
            }
            finally
            {
                if (CngKey.Exists(data.Key))
                {
                    using (CngKey key = CngKey.Open(data.Key))
                    {
                        key.Delete();
                    }
                }
            }
        }
Ejemplo n.º 10
0
        private void btnDecrypt_Click(object sender, EventArgs e)
        {
            string sRet = "";

            byte[] bytIn = Convert.FromBase64String(tbCipher.Text);
            tbHexData.Text = ByteArrayToString(bytIn);
            if (cbAlg.SelectedIndex == 0)             // AES
            {
                MemoryStream       ms     = new MemoryStream(bytIn, 0, bytIn.Length);
                SymmetricAlgorithm symAlg = new RijndaelManaged();
                symAlg.KeySize   = 32 * 8;
                symAlg.BlockSize = 16 * 8;
                symAlg.Mode      = CipherMode.CBC;
                symAlg.Padding   = PaddingMode.PKCS7;

                symAlg.Key = GetLegalKey(symAlg);
                symAlg.IV  = GetLegalIV(symAlg);

                ICryptoTransform encrypto = symAlg.CreateDecryptor();
                CryptoStream     cs       = new CryptoStream(ms, encrypto, CryptoStreamMode.Read);
                StreamReader     sr       = new StreamReader(cs);
                sRet = sr.ReadToEnd();
            }
            else if (cbAlg.SelectedIndex == 1)             // RSA
            {
                //声明一个RSA算法的实例,指定了密钥长度为1024位,会自动生成密钥信息。
                RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024);
                rsaProvider.FromXmlString(tbKey2.Text);                 //将私钥导入到RSA对象
                byte[] bytOut = rsaProvider.Decrypt(bytIn, false);      //对数据data解密,并返回加密结果;
                sRet = Encoding.UTF8.GetString(bytOut);
            }
            else if (cbAlg.SelectedIndex == 2)             // ECC
            {
                CngKey             decKey  = CngKey.Import(Convert.FromBase64String(txPrvKey.Text), CngKeyBlobFormat.EccPrivateBlob);
                ECDiffieHellmanCng decoder = new ECDiffieHellmanCng(decKey);
                decoder.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                decoder.HashAlgorithm         = CngAlgorithm.Sha256;

                Aes aes = new AesCryptoServiceProvider();
                aes.IV = Convert.FromBase64String(this.tbKey2.Text);
                CngKey k = CngKey.Import(Convert.FromBase64String(this.tbKey1.Text), CngKeyBlobFormat.EccPublicBlob);
                aes.Key = decoder.DeriveKeyMaterial(k);

                MemoryStream plaintext = new MemoryStream();
                using (CryptoStream cs = new CryptoStream(plaintext, aes.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(bytIn, 0, bytIn.Length);
                    cs.Close();
                    sRet = Encoding.UTF8.GetString(plaintext.ToArray());
                }
                decKey.Delete();
            }
            textContent.Text = sRet;
        }
Ejemplo n.º 11
0
 public static void ClearRSAKey()
 {
     if (CngKey.Exists(PRIVATE_KEY))
     {
         using (CngKey algorithmKey = CngKey.Open(PRIVATE_KEY))
         {
             algorithmKey.Delete();
         }
     }
     ;
 }
Ejemplo n.º 12
0
        public static void AssociatePersistedKey_CNG_RSA()
        {
            const string KeyName = nameof(AssociatePersistedKey_CNG_RSA);

            CngKey            cngKey        = null;
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256;

            byte[] signature;

            try
            {
                CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
                {
                    ExportPolicy       = CngExportPolicies.None,
                    Provider           = CngProvider.MicrosoftSoftwareKeyStorageProvider,
                    KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
                };

                cngKey = CngKey.Create(CngAlgorithm.Rsa, KeyName, creationParameters);

                using (RSACng rsaCng = new RSACng(cngKey))
                {
                    CertificateRequest request = new CertificateRequest(
                        $"CN={KeyName}",
                        rsaCng,
                        HashAlgorithmName.SHA256,
                        RSASignaturePadding.Pkcs1);

                    DateTimeOffset now = DateTimeOffset.UtcNow;

                    using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1)))
                        using (RSA rsa = cert.GetRSAPrivateKey())
                        {
                            signature = rsa.SignData(Array.Empty <byte>(), hashAlgorithm, RSASignaturePadding.Pkcs1);

                            Assert.True(
                                rsaCng.VerifyData(Array.Empty <byte>(), signature, hashAlgorithm, RSASignaturePadding.Pkcs1));
                        }
                }

                // Some certs have disposed, did they delete the key?
                using (CngKey stillPersistedKey = CngKey.Open(KeyName, CngProvider.MicrosoftSoftwareKeyStorageProvider))
                    using (RSACng rsaCng = new RSACng(stillPersistedKey))
                    {
                        byte[] signature2 = rsaCng.SignData(Array.Empty <byte>(), hashAlgorithm, RSASignaturePadding.Pkcs1);

                        Assert.Equal(signature, signature2);
                    }
            }
            finally
            {
                cngKey?.Delete();
            }
        }
        /// <summary>
        /// Will destroy the key with keyname within the given provider with providerName.  Will throw CryptographicException if either Provider or Key don't exist
        /// </summary>
        /// <param name="providerName">Name of the provider</param>
        /// <param name="keyName">Name of the key to destroy</param>
        public void DestroyLocalRSAKey(string providerName, string keyName)
        {
            CngProvider provider = new CngProvider(providerName);

            if (CngKey.Exists(keyName, provider))
            {
                using (CngKey key = CngKey.Open(keyName, provider))
                {
                    key.Delete();
                }
            }
        }
Ejemplo n.º 14
0
        public static void AssociatePersistedKey_CNG_ECDsa()
        {
            const string KeyName = nameof(AssociatePersistedKey_CNG_ECDsa);

            CngKey            cngKey        = null;
            HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA256;

            byte[] signature;

            try
            {
                CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
                {
                    ExportPolicy       = CngExportPolicies.None,
                    Provider           = CngProvider.MicrosoftSoftwareKeyStorageProvider,
                    KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
                };

                cngKey = CngKey.Create(CngAlgorithm.ECDsaP384, KeyName, creationParameters);

                using (ECDsaCng ecdsaCng = new ECDsaCng(cngKey))
                {
                    CertificateRequest request = new CertificateRequest(
                        new X500DistinguishedName($"CN={KeyName}"),
                        ecdsaCng,
                        HashAlgorithmName.SHA256);

                    DateTimeOffset now = DateTimeOffset.UtcNow;

                    using (X509Certificate2 cert = request.CreateSelfSigned(now, now.AddDays(1)))
                        using (ECDsa ecdsa = cert.GetECDsaPrivateKey())
                        {
                            signature = ecdsa.SignData(Array.Empty <byte>(), hashAlgorithm);

                            Assert.True(ecdsaCng.VerifyData(Array.Empty <byte>(), signature, hashAlgorithm));
                        }
                }

                // Some certs have disposed, did they delete the key?
                using (CngKey stillPersistedKey = CngKey.Open(KeyName, CngProvider.MicrosoftSoftwareKeyStorageProvider))
                    using (ECDsaCng ecdsaCng = new ECDsaCng(stillPersistedKey))
                    {
                        ecdsaCng.SignData(Array.Empty <byte>(), hashAlgorithm);
                    }
            }
            finally
            {
                cngKey?.Delete();
            }
        }
        public static void LoadWrongKeyType()
        {
            string keyName = Guid.NewGuid().ToString();
            CngKey cngKey  = CngKey.Create(new CngAlgorithm("AES"), keyName);

            try
            {
                Assert.Throws <CryptographicException>(() => new TripleDESCng(keyName));
            }
            finally
            {
                cngKey.Delete();
            }
        }
Ejemplo n.º 16
0
        static void Main(string[] args)
        {
            var keyParams = new CngKeyCreationParameters
            {
                ExportPolicy       = CngExportPolicies.None,
                KeyCreationOptions = CngKeyCreationOptions.MachineKey,
                Provider           = new CngProvider("Microsoft Platform Crypto Provider"),
            };

            CngKey key = CngKey.Create(CngAlgorithm.Rsa, $"TPM-Import-Key", keyParams);

            Console.WriteLine($"Is the key a machine key? {key.IsMachineKey}");

            key.Delete();   // just for cleanup, not necessary for reproduction
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Will destroy the key with keyname within the given provider with providerName.  Will throw CryptographicException if either Provider or Key don't exist
        /// </summary>
        /// <param name="providerName">Name of the provider</param>
        /// <param name="keyName">Name of the key to destroy</param>
        public void DestroyLocalRSAKey(string providerName, string keyName)
        {
            CngProvider provider  = new CngProvider(providerName);
            bool        keyExists = doesKeyExists(provider, keyName);

            if (!keyExists)
            {
                //Nothing to destroy
                return;
            }

            using (CngKey key = CngKey.Open(keyName, provider, CngKeyOpenOptions.MachineKey))
            {
                key.Delete();
            }
        }
Ejemplo n.º 18
0
        public void GetCngPrivateKeyTest()
        {
            // The known Microsoft cert does not have a CNG private key
            Assert.IsNull(s_microsoftCert.GetCngPrivateKey());

            const string keyName = "Microsoft.Security.Cryptography.X509Certificates.Test.X509Certificate2Tests.GetCngPrivateKeyTest.RSA1";

            try
            {
                // Create a cert for a persisted CNG key
                CngKeyCreationParameters keyCreationParams = new CngKeyCreationParameters();
                keyCreationParams.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport;
                using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, keyName, keyCreationParams))
                {
                    X509CertificateCreationParameters creationParams =
                        new X509CertificateCreationParameters(new X500DistinguishedName("CN=CngCert"));
                    creationParams.CertificateCreationOptions = X509CertificateCreationOptions.None;
                    creationParams.TakeOwnershipOfKey         = false;

                    // A CNG certificate using a named key which is linked to the cert itself should return true
                    X509Certificate2 cngFullCert = key.CreateSelfSignedCertificate(creationParams);
                    using (CngKey certKey = cngFullCert.GetCngPrivateKey())
                    {
                        Assert.AreEqual(keyName, certKey.KeyName);
                    }

                    // Create a cert with just the public key - there should be no access to the private key
                    byte[]           publicCertData = cngFullCert.Export(X509ContentType.Cert);
                    X509Certificate2 cngPublicCert  = new X509Certificate2(publicCertData);
                    Assert.IsFalse(cngPublicCert.HasPrivateKey);
                    Assert.IsNull(cngPublicCert.GetCngPrivateKey());

                    key.Delete();
                }
            }
            finally
            {
                // Make sure to delete the persisted key so we're clean for the next run.
                if (CngKey.Exists(keyName))
                {
                    using (CngKey key = CngKey.Open(keyName))
                    {
                        key.Delete();
                    }
                }
            }
        }
Ejemplo n.º 19
0
        public void HasCngKeyTestCngCertTest()
        {
            const string keyName = "Microsoft.Security.Cryptography.X509Certificates.Test.X509Certificate2Tests.HasCngKeyTest.RSA1";

            try
            {
                // Create a cert for a persisted CNG key
                CngKeyCreationParameters keyCreationParams = new CngKeyCreationParameters();
                keyCreationParams.ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport;
                using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa, keyName, keyCreationParams))
                {
                    X509CertificateCreationParameters creationParams =
                        new X509CertificateCreationParameters(new X500DistinguishedName("CN=CngCert"));
                    creationParams.CertificateCreationOptions = X509CertificateCreationOptions.None;
                    creationParams.TakeOwnershipOfKey         = false;

                    // A CNG certificate using a named key which is linked to the cert itself should return true
                    X509Certificate2 cngCert = key.CreateSelfSignedCertificate(creationParams);
                    Assert.IsTrue(cngCert.HasCngKey());

                    // A CNG cert exported and then re-imported should also return true
                    byte[]           pfx           = cngCert.Export(X509ContentType.Pfx, "CngCertPassword");
                    X509Certificate2 cngCertImport = new X509Certificate2(pfx, "CngCertPassword");
                    Assert.IsTrue(cngCertImport.HasCngKey());

                    key.Delete();
                }

                using (CngKey key = CngKey.Create(CngAlgorithm2.Rsa))
                {
                    X509Certificate2 ephemeralCert = key.CreateSelfSignedCertificate(new X500DistinguishedName("CN=EphemeralCngCert"));
                    Assert.IsTrue(ephemeralCert.HasCngKey());
                }
            }
            finally
            {
                // Make sure to delete the persisted key so we're clean for the next run.
                if (CngKey.Exists(keyName))
                {
                    using (CngKey key = CngKey.Open(keyName))
                    {
                        key.Delete();
                    }
                }
            }
        }
Ejemplo n.º 20
0
        public void CreateNamedKeyCertificate()
        {
            string keyName = "NamedKey_" + Guid.NewGuid().ToString();

            try
            {
                CngKeyCreationParameters keyCreationParameters = new CngKeyCreationParameters();
                keyCreationParameters.ExportPolicy = CngExportPolicies.AllowExport;

                X509Certificate2 cert = null;
                byte[]           pfx  = null;
                using (CngKey namedKey = CngKey.Create(CngAlgorithm2.Rsa, keyName, keyCreationParameters))
                {
                    cert = namedKey.CreateSelfSignedCertificate(new X500DistinguishedName("CN=TestNamedRSAKey"));
                    pfx  = cert.Export(X509ContentType.Pfx, "TestPassword");

                    Assert.IsTrue(cert.HasPrivateKey);
                    Assert.IsTrue(cert.HasCngKey());

                    using (CngKey certKey = cert.GetCngPrivateKey())
                    {
                        Assert.AreEqual(CngAlgorithm2.Rsa, certKey.Algorithm);
                    }
                }
                GC.KeepAlive(cert);

                X509Certificate2 rtCert = new X509Certificate2(pfx, "TestPassword");
                Assert.IsTrue(rtCert.HasPrivateKey);
                Assert.IsTrue(rtCert.HasCngKey());

                using (CngKey rtKey = rtCert.GetCngPrivateKey())
                {
                    Assert.AreEqual(CngAlgorithm2.Rsa, rtKey.Algorithm);
                }
            }
            finally
            {
                if (CngKey.Exists(keyName))
                {
                    using (CngKey key = CngKey.Open(keyName))
                    {
                        key.Delete();
                    }
                }
            }
        }
Ejemplo n.º 21
0
    public static void Main()
    {
        partyAKey();
        partyBKey();
        CngProvider luna  = new CngProvider("SafeNet Key Storage Provider");
        CngKey      ecKey = CngKey.Open("Party-A", luna);

        byte [] pubKey = softKey.Export(CngKeyBlobFormat.EccPublicBlob);
        softKey.Delete();
        publicKey = CngKey.Import(pubKey, CngKeyBlobFormat.EccPublicBlob, luna);

        ECDiffieHellmanCng xChg = new ECDiffieHellmanCng(ecKey);

        xChg.HashAlgorithm         = CngAlgorithm.Sha256;
        xChg.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hmac;
        byte[] data = xChg.DeriveKeyMaterial(publicKey);
        Console.ReadLine();
        ecKey.Delete();
    }
Ejemplo n.º 22
0
        public static void VerifyCfbPersistedUnsupportedFeedbackSize(
            CngAlgorithm algorithm,
            Func <string, SymmetricAlgorithm> persistedFunc,
            int notSupportedFeedbackSizeInBits)
        {
            string keyName            = Guid.NewGuid().ToString();
            string feedbackSizeString = notSupportedFeedbackSizeInBits.ToString();

            // We try to delete the key later which will also dispose of it, so no need
            // to put this in a using.
            CngKey cngKey = CngKey.Create(algorithm, keyName);

            try
            {
                using (SymmetricAlgorithm alg = persistedFunc(keyName))
                {
                    alg.Mode         = CipherMode.CFB;
                    alg.FeedbackSize = notSupportedFeedbackSizeInBits;
                    alg.Padding      = PaddingMode.None;

                    byte[] destination        = new byte[alg.BlockSize / 8];
                    CryptographicException ce = Assert.ThrowsAny <CryptographicException>(() =>
                                                                                          alg.EncryptCfb(Array.Empty <byte>(), destination, PaddingMode.None, notSupportedFeedbackSizeInBits));

                    Assert.Contains(feedbackSizeString, ce.Message);

                    ce = Assert.ThrowsAny <CryptographicException>(() =>
                                                                   alg.DecryptCfb(Array.Empty <byte>(), destination, PaddingMode.None, notSupportedFeedbackSizeInBits));

                    Assert.Contains(feedbackSizeString, ce.Message);

                    ce = Assert.ThrowsAny <CryptographicException>(() => alg.CreateDecryptor());
                    Assert.Contains(feedbackSizeString, ce.Message);

                    ce = Assert.ThrowsAny <CryptographicException>(() => alg.CreateEncryptor());
                    Assert.Contains(feedbackSizeString, ce.Message);
                }
            }
            finally
            {
                cngKey.Delete();
            }
        }
Ejemplo n.º 23
0
        internal static void VerifyMismatchAlgorithmFails(
            CngAlgorithm algorithm,
            Func <string, SymmetricAlgorithm> createFromKey)
        {
            string keyName = Guid.NewGuid().ToString();

            // We try to delete the key later which will also dispose of it, so no need
            // to put this in a using.
            CngKey cngKey = CngKey.Create(algorithm, keyName);

            try
            {
                CryptographicException ce = Assert.Throws <CryptographicException>(() => createFromKey(keyName));
                Assert.Contains($"'{algorithm.Algorithm}'", ce.Message);
            }
            finally
            {
                cngKey.Delete();
            }
        }
Ejemplo n.º 24
0
        public static void GetKey_NonExportable(
            CngAlgorithm algorithm,
            Func <string, SymmetricAlgorithm> persistedFunc)
        {
            string keyName = Guid.NewGuid().ToString();
            CngKey cngKey  = CngKey.Create(algorithm, keyName);

            try
            {
                using (SymmetricAlgorithm persisted = persistedFunc(keyName))
                {
                    Assert.ThrowsAny <CryptographicException>(() => persisted.Key);
                }
            }
            finally
            {
                // Delete also Disposes the key, no using should be added here.
                cngKey.Delete();
            }
        }
Ejemplo n.º 25
0
        // The ephemeral key has already been validated by the AesCipherTests suite.
        // Therefore we can use the ephemeral key to validate the persisted key.
        internal static void VerifyPersistedKey(
            CngAlgorithm algorithm,
            int keySize,
            int plainBytesCount,
            Func <string, SymmetricAlgorithm> persistedFunc,
            Func <SymmetricAlgorithm> ephemeralFunc,
            CipherMode cipherMode,
            PaddingMode paddingMode,
            int feedbackSizeInBits)
        {
            string keyName = Guid.NewGuid().ToString();
            CngKeyCreationParameters creationParameters = new CngKeyCreationParameters
            {
                Provider     = CngProvider.MicrosoftSoftwareKeyStorageProvider,
                ExportPolicy = CngExportPolicies.AllowPlaintextExport,
                Parameters   =
                {
                    new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None),
                }
            };

            CngKey cngKey = CngKey.Create(algorithm, keyName, creationParameters);

            try
            {
                VerifyPersistedKey(
                    keyName,
                    plainBytesCount,
                    persistedFunc,
                    ephemeralFunc,
                    cipherMode,
                    paddingMode,
                    feedbackSizeInBits);
            }
            finally
            {
                // Delete also Disposes the key, no using should be added here.
                cngKey.Delete();
            }
        }
Ejemplo n.º 26
0
        //[Fact] - Keeping this test for reference but we don't want to run it as an inner-loop test because
        //         it creates a key on disk.
        public static void StoredKeyTripleDES()
        {
            CngAlgorithm algname = new CngAlgorithm("3DES");
            string       keyName = "CoreFxTest-" + Guid.NewGuid();
            CngKey       _cngKey = CngKey.Create(algname, keyName);

            try
            {
                using (TripleDES alg = new TripleDESCng(keyName))
                {
                    int keySize = alg.KeySize;
                    Assert.Equal(192, keySize);

                    // Since this is a stored key, it's not going to surrender the actual key bytes.
                    Assert.ThrowsAny <CryptographicException>(() => alg.Key);
                }
            }
            finally
            {
                _cngKey.Delete();
            }
        }
Ejemplo n.º 27
0
        public static void SetKey_DetachesFromPersistedKey(
            CngAlgorithm algorithm,
            Func <string, SymmetricAlgorithm> persistedFunc)
        {
            // This test verifies that:
            // * [Algorithm]Cng.set_Key does not change the persisted key value
            // * [Algorithm]Cng.GenerateKey is "the same" as set_Key
            // * ICryptoTransform objects opened before the change do not react to it

            string keyName = Guid.NewGuid().ToString();
            CngKey cngKey  = CngKey.Create(algorithm, keyName);

            try
            {
                using (SymmetricAlgorithm replaceKey = persistedFunc(keyName))
                    using (SymmetricAlgorithm regenKey = persistedFunc(keyName))
                        using (SymmetricAlgorithm stable = persistedFunc(keyName))
                        {
                            // Ensure that we get no padding violations on decrypting with a bad key
                            replaceKey.Padding = regenKey.Padding = stable.Padding = PaddingMode.None;

                            stable.GenerateIV();

                            // Generate (4 * 8) = 32 blocks of plaintext
                            byte[] plainTextBytes = GenerateRandom(4 * stable.BlockSize);
                            byte[] iv             = stable.IV;

                            regenKey.IV = replaceKey.IV = iv;

                            byte[] encryptedBytes;

                            using (ICryptoTransform encryptor = replaceKey.CreateEncryptor())
                            {
                                encryptedBytes = encryptor.TransformFinalBlock(plainTextBytes, 0, plainTextBytes.Length);
                            }

                            using (ICryptoTransform replaceBefore = replaceKey.CreateDecryptor())
                                using (ICryptoTransform replaceBeforeDelayed = replaceKey.CreateDecryptor())
                                    using (ICryptoTransform regenBefore = regenKey.CreateDecryptor())
                                        using (ICryptoTransform regenBeforeDelayed = regenKey.CreateDecryptor())
                                            using (ICryptoTransform stableBefore = stable.CreateDecryptor())
                                                using (ICryptoTransform stableBeforeDelayed = stable.CreateDecryptor())
                                                {
                                                    // Before we regenerate the regen key it should validly decrypt
                                                    AssertTransformsEqual(plainTextBytes, regenBefore, encryptedBytes);

                                                    // Before we regenerate the replace key it should validly decrypt
                                                    AssertTransformsEqual(plainTextBytes, replaceBefore, encryptedBytes);

                                                    // The stable handle definitely should validly read before.
                                                    AssertTransformsEqual(plainTextBytes, stableBefore, encryptedBytes);

                                                    regenKey.GenerateKey();
                                                    replaceKey.Key = regenKey.Key;

                                                    using (ICryptoTransform replaceAfter = replaceKey.CreateDecryptor())
                                                        using (ICryptoTransform regenAfter = regenKey.CreateDecryptor())
                                                            using (ICryptoTransform stableAfter = stable.CreateDecryptor())
                                                            {
                                                                // All of the Befores, and the BeforeDelayed (which have not accessed their key material)
                                                                // should still decrypt correctly.  And so should stableAfter.
                                                                AssertTransformsEqual(plainTextBytes, regenBefore, encryptedBytes);
                                                                AssertTransformsEqual(plainTextBytes, regenBeforeDelayed, encryptedBytes);
                                                                AssertTransformsEqual(plainTextBytes, replaceBefore, encryptedBytes);
                                                                AssertTransformsEqual(plainTextBytes, replaceBeforeDelayed, encryptedBytes);
                                                                AssertTransformsEqual(plainTextBytes, stableBefore, encryptedBytes);
                                                                AssertTransformsEqual(plainTextBytes, stableBeforeDelayed, encryptedBytes);
                                                                AssertTransformsEqual(plainTextBytes, stableAfter, encryptedBytes);

                                                                // There's a 1 in 2^128 chance that the regenerated key matched the original generated key.
                                                                byte[] badDecrypt = replaceAfter.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
                                                                Assert.NotEqual(plainTextBytes, badDecrypt);

                                                                // Regen and replace should come up with the same bad value, since they have the same
                                                                // key value.
                                                                AssertTransformsEqual(badDecrypt, regenAfter, encryptedBytes);
                                                            }
                                                }

                            // And, finally, a newly opened handle to the key is also unaffected.
                            using (SymmetricAlgorithm openedAfter = persistedFunc(keyName))
                            {
                                openedAfter.Padding = PaddingMode.None;
                                openedAfter.IV      = iv;

                                using (ICryptoTransform decryptor = openedAfter.CreateDecryptor())
                                {
                                    AssertTransformsEqual(plainTextBytes, decryptor, encryptedBytes);
                                }
                            }
                        }
            }
            finally
            {
                // Delete also Disposes the key, no using should be added here.
                cngKey.Delete();
            }
        }
Ejemplo n.º 28
0
        public static void ExportDoesNotCorruptPrivateKeyMethods()
        {
            string    keyName = $"clrtest.{Guid.NewGuid():D}";
            X509Store cuMy    = new X509Store(StoreName.My, StoreLocation.CurrentUser);

            cuMy.Open(OpenFlags.ReadWrite);
            X509Certificate2 createdCert = null;
            X509Certificate2 foundCert   = null;
            X509Certificate2 foundCert2  = null;

            try
            {
                string commonName = nameof(ExportDoesNotCorruptPrivateKeyMethods);
                string subject    = $"CN={commonName},OU=.NET";

                using (ImportedCollection toClean = new ImportedCollection(cuMy.Certificates))
                {
                    X509Certificate2Collection coll = toClean.Collection;

                    using (ImportedCollection matches =
                               new ImportedCollection(coll.Find(X509FindType.FindBySubjectName, commonName, false)))
                    {
                        foreach (X509Certificate2 cert in matches.Collection)
                        {
                            cuMy.Remove(cert);
                        }
                    }
                }

                foreach (X509Certificate2 cert in cuMy.Certificates)
                {
                    if (subject.Equals(cert.Subject))
                    {
                        cuMy.Remove(cert);
                    }

                    cert.Dispose();
                }

                CngKeyCreationParameters options = new CngKeyCreationParameters
                {
                    ExportPolicy = CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport,
                };

                using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, options))
                    using (RSACng rsaCng = new RSACng(key))
                    {
                        CertificateRequest certReq = new CertificateRequest(
                            subject,
                            rsaCng,
                            HashAlgorithmName.SHA256,
                            RSASignaturePadding.Pkcs1);

                        DateTimeOffset now = DateTimeOffset.UtcNow.AddMinutes(-5);
                        createdCert = certReq.CreateSelfSigned(now, now.AddDays(1));
                    }

                cuMy.Add(createdCert);

                using (ImportedCollection toClean = new ImportedCollection(cuMy.Certificates))
                {
                    X509Certificate2Collection matches = toClean.Collection.Find(
                        X509FindType.FindBySubjectName,
                        commonName,
                        validOnly: false);

                    Assert.Equal(1, matches.Count);
                    foundCert = matches[0];
                }

                Assert.False(HasEphemeralKey(foundCert));
                foundCert.Export(X509ContentType.Pfx, "");
                Assert.False(HasEphemeralKey(foundCert));

                using (ImportedCollection toClean = new ImportedCollection(cuMy.Certificates))
                {
                    X509Certificate2Collection matches = toClean.Collection.Find(
                        X509FindType.FindBySubjectName,
                        commonName,
                        validOnly: false);

                    Assert.Equal(1, matches.Count);
                    foundCert2 = matches[0];
                }

                Assert.False(HasEphemeralKey(foundCert2));
            }
            finally
            {
                if (createdCert != null)
                {
                    cuMy.Remove(createdCert);
                    createdCert.Dispose();
                }

                cuMy.Dispose();

                foundCert?.Dispose();
                foundCert2?.Dispose();

                try
                {
                    CngKey key = CngKey.Open(keyName);
                    key.Delete();
                    key.Dispose();
                }
                catch (Exception)
                {
                }
            }

            bool HasEphemeralKey(X509Certificate2 c)
            {
                using (RSA key = c.GetRSAPrivateKey())
                {
                    // This code is not defensive against the type changing, because it
                    // is in the source tree with the code that produces the value.
                    // Don't blind-cast like this in library or application code.
                    RSACng rsaCng = (RSACng)key;
                    return(rsaCng.Key.IsEphemeral);
                }
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Create a RSA based certificate (to be used with encryption) with the given options
        /// </summary>
        /// <param name="buildOptions">Allows for more advanced configuration</param>
        /// <returns>An exportable X509Certificate2 object (with private key)</returns>
        public static X509Certificate2 CreateNewCertificate(RSACertificateBuilderOptions buildOptions)
        {
            if (buildOptions == null)
            {
                throw new ArgumentNullException("buildOptions");
            }

            string keyName = buildOptions.RSAKeyName ?? "RSAKey";

            CngKey objCngKey = null;

            if (CngKey.Exists(keyName))
            {
                objCngKey = CngKey.Open(keyName);
                objCngKey.Delete();
            }

            var creationParameters = new CngKeyCreationParameters();

            creationParameters.ExportPolicy = CngExportPolicies.AllowExport;
            creationParameters.KeyUsage     = CngKeyUsages.AllUsages;
            creationParameters.Provider     = CngProvider.MicrosoftSoftwareKeyStorageProvider;
            var keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(buildOptions.KeySize ?? 4096), CngPropertyOptions.None);

            creationParameters.Parameters.Add(keySizeProperty);

            objCngKey = CngKey.Create(CngAlgorithm2.Rsa, keyName, creationParameters);

            var name = new X500DistinguishedName(buildOptions.FullSubjectName);

            X509CertificateSignatureAlgorithm certAlg;

            switch (buildOptions.HashingMethod ?? HashingMethods.Sha256)
            {
            case HashingMethods.Sha1:
                certAlg = X509CertificateSignatureAlgorithm.RsaSha1;
                break;

            case HashingMethods.Sha256:
                certAlg = X509CertificateSignatureAlgorithm.RsaSha256;
                break;

            case HashingMethods.Sha384:
                certAlg = X509CertificateSignatureAlgorithm.RsaSha384;
                break;

            case HashingMethods.Sha512:
                certAlg = X509CertificateSignatureAlgorithm.RsaSha512;
                break;

            default:
                throw new InvalidOperationException("Selected hashing method is not supported");
            }

            var options = new X509CertificateCreationParameters(name)
            {
                SignatureAlgorithm = certAlg,
                TakeOwnershipOfKey = true
            };

            return(objCngKey.CreateSelfSignedCertificate(options));
        }
        /// <summary>
        /// Create a ECDSA based certificate with the given options
        /// </summary>
        /// <param name="buildOptions">Allows for more advanced configuration</param>
        /// <returns>An exportable X509Certificate2 object (with private key)</returns>
        public static X509Certificate2 CreateNewSigningCertificate(ECCertificateBuilderOptions buildOptions)
        {
            if (buildOptions == null)
            {
                throw new ArgumentNullException("buildOptions");
            }

            string keyName = buildOptions.ECKeyName ?? "ECDSAKey";

            CngKey objCngKey = null;

            if (CngKey.Exists(keyName))
            {
                objCngKey = CngKey.Open(keyName);
                objCngKey.Delete();
            }

            var creationParameters = new CngKeyCreationParameters();

            creationParameters.ExportPolicy = CngExportPolicies.AllowExport;
            creationParameters.KeyUsage     = CngKeyUsages.Signing;

            CngAlgorithm keyAlg;

            switch (buildOptions.ECCurve ?? ECNamedCurves.P521)
            {
            case ECNamedCurves.P521:
                keyAlg = CngAlgorithm.ECDsaP521;
                break;

            case ECNamedCurves.P384:
                keyAlg = CngAlgorithm.ECDsaP384;
                break;

            case ECNamedCurves.P256:
                keyAlg = CngAlgorithm.ECDsaP256;
                break;

            default:
                throw new InvalidOperationException("Selected curve is not supported");
            }

            objCngKey = CngKey.Create(keyAlg, keyName, creationParameters);

            var name = new X500DistinguishedName(buildOptions.FullSubjectName);

            X509CertificateSignatureAlgorithm certAlg;

            switch (buildOptions.HashingMethod ?? HashingMethods.Sha256)
            {
            case HashingMethods.Sha1:
                certAlg = X509CertificateSignatureAlgorithm.ECDsaSha1;
                break;

            case HashingMethods.Sha256:
                certAlg = X509CertificateSignatureAlgorithm.ECDsaSha256;
                break;

            case HashingMethods.Sha384:
                certAlg = X509CertificateSignatureAlgorithm.ECDsaSha384;
                break;

            case HashingMethods.Sha512:
                certAlg = X509CertificateSignatureAlgorithm.ECDsaSha512;
                break;

            default:
                throw new InvalidOperationException("Selected hashing method is not supported");
            }

            var options = new X509CertificateCreationParameters(name)
            {
                SignatureAlgorithm = certAlg,
                TakeOwnershipOfKey = true
            };

            return(objCngKey.CreateSelfSignedCertificate(options));
        }