コード例 #1
0
ファイル: HandleTests.cs プロジェクト: noahfalk/corefx
        public static void HandleDuplication()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                SafeNCryptKeyHandle keyHandle1 = key.Handle;
                SafeNCryptKeyHandle keyHandle2 = key.Handle;
                Assert.NotSame(keyHandle1, keyHandle2);

                keyHandle1.Dispose();
                keyHandle2.Dispose();

                // Make sure that disposing the spawned off handles didn't dispose the original. Set and get a custom property to ensure
                // the original is still in good condition.
                string propertyName = "Are you alive";
                bool hasProperty = key.HasProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.False(hasProperty);

                byte[] propertyValue = { 1, 2, 3 };
                CngProperty property = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                byte[] actualValue = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty).GetValue();
                Assert.Equal<byte>(propertyValue, actualValue);
            }
        }
コード例 #2
0
ファイル: CngAlgorithmCore.cs プロジェクト: ESgarbi/corefx
        public CngKey GetOrGenerateKey(int keySize, CngAlgorithm algorithm)
        {
            // If our key size was changed, we need to generate a new key.
            if (_lazyKey != null)
            {
                if (_lazyKey.KeySize != keySize)
                    DisposeKey();
            }

            // If we don't have a key yet, we need to generate one now.
            if (_lazyKey == null)
            {
                CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
                {
                    ExportPolicy = CngExportPolicies.AllowPlaintextExport,
                };

                CngProperty keySizeProperty = new CngProperty(KeyPropertyName.Length, BitConverter.GetBytes(keySize), CngPropertyOptions.None);
                creationParameters.Parameters.Add(keySizeProperty);

                _lazyKey = CngKey.Create(algorithm, null, creationParameters);
            }

            return _lazyKey;
        }
コード例 #3
0
 private void Reset()
 {
     if (IV != null)
     {
         CngProperty prop = new CngProperty(Interop.NCrypt.NCRYPT_INITIALIZATION_VECTOR, IV, CngPropertyOptions.None);
         _cngKey !.SetProperty(prop);
     }
 }
コード例 #4
0
ファイル: PropertyTests.cs プロジェクト: noahfalk/corefx
 public static void SetPropertyNullCornerCase()
 {
     using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
     {
         const string propertyName = "CustomNullProperty";
         CngProperty p = new CngProperty(propertyName, null, CngPropertyOptions.CustomProperty);
         Assert.ThrowsAny<CryptographicException>(() => key.SetProperty(p));
     }
 }
コード例 #5
0
 public static void SetPropertyNullCornerCase()
 {
     using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
     {
         const string propertyName = "CustomNullProperty";
         CngProperty  p            = new CngProperty(propertyName, null, CngPropertyOptions.CustomProperty);
         Assert.ThrowsAny <CryptographicException>(() => key.SetProperty(p));
     }
 }
コード例 #6
0
        public CngKey GetOrGenerateKey(ECCurve?curve)
        {
            ThrowIfDisposed();

            if (_lazyKey != null)
            {
                return(_lazyKey);
            }

            // We don't have a key yet so generate
            Debug.Assert(curve.HasValue);

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

            if (curve.Value.IsNamed)
            {
                creationParameters.Parameters.Add(CngKey.GetPropertyFromNamedCurve(curve.Value));
            }
            else if (curve.Value.IsPrime)
            {
                ECCurve     eccurve        = curve.Value;
                byte[]      parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref eccurve);
                CngProperty prop           = new CngProperty(
                    Interop.BCrypt.BCryptPropertyStrings.BCRYPT_ECC_PARAMETERS,
                    parametersBlob,
                    CngPropertyOptions.None);
                creationParameters.Parameters.Add(prop);
            }
            else
            {
                throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.Value.CurveType.ToString()));
            }

            try
            {
                _lazyKey = CngKey.Create(DefaultKeyType ?? CngAlgorithm.ECDsa, null, creationParameters);
            }
            catch (CryptographicException e)
            {
                // Map to PlatformNotSupportedException if appropriate
                ErrorCode errorCode = (ErrorCode)e.HResult;

                if (curve.Value.IsNamed &&
                    errorCode == ErrorCode.NTE_INVALID_PARAMETER || errorCode == ErrorCode.NTE_NOT_SUPPORTED)
                {
                    throw new PlatformNotSupportedException(SR.Format(SR.Cryptography_CurveNotSupported, curve.Value.Oid.FriendlyName), e);
                }
                throw;
            }

            return(_lazyKey);
        }
コード例 #7
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);
        }
コード例 #8
0
        public static void AddKeyToCng(string providerName, string containerName)
        {
            CngKeyCreationParameters keyParams = new CngKeyCreationParameters();

            keyParams.Provider           = new CngProvider(providerName);
            keyParams.KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey;

            CngProperty keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.None);

            keyParams.Parameters.Add(keySizeProperty);

            CngKey mycngKey = CngKey.Create(CngAlgorithm.Rsa, containerName, keyParams);
        }
コード例 #9
0
        /// <summary>
        /// Decrypts the message using an exchange private key that has a pin.
        /// </summary>
        /// <param name="encryptedMessage">Encrypted message as base64 string to be decrypted</param>
        /// <param name="privateKey">Private exchange key to decrypt the message</param>
        /// <param name="padding">Padding mode to be used with the decryption</param>
        /// <param name="pin">The private key pin</param>
        /// <returns>Decrypted message as byte array</returns>
        /// <exception cref="ArgumentException">There is null in the parameters or one of the parameters empty</exception>
        /// <exception cref="CryptographicException">The cryptographic service provider (CSP) cannot be acquired.-or- The parameters parameter has missing fields. -or- The padding mode is not supported. -or- The certificate context is invalid. -or- wrong pin has been inputed.</exception>
        /// <exception cref="FormatException">The length of string, ignoring white-space characters, is not zero or a multiple of 4. -or-The format of s is invalid. string contains a non-base-64 character, more than two padding characters, or a non-white space-character among the padding characters.</exception>
        public static byte[] Decrypt(string encryptedMessage, X509Certificate2 privateKey, RSAEncryptionPadding padding, string pin)
        {
            try
            {
                byte[] decodedEncryptedBytes = Convert.FromBase64String(encryptedMessage);
                RSA    rsa    = privateKey.GetRSAPrivateKey();
                RSACng rsaCng = rsa as RSACng;
                if (rsaCng != null)
                {
                    // Set the PIN, an explicit null terminator is required to this Unicode/UCS-2 string.

                    byte[] propertyBytes;

                    if (pin[pin.Length - 1] == '\0')
                    {
                        propertyBytes = Encoding.Unicode.GetBytes(pin);
                    }
                    else
                    {
                        propertyBytes = new byte[Encoding.Unicode.GetByteCount(pin) + 2];
                        Encoding.Unicode.GetBytes(pin, 0, pin.Length, propertyBytes, 0);
                    }

                    const string NCRYPT_PIN_PROPERTY = "SmartCardPin";

                    CngProperty pinProperty = new CngProperty(
                        NCRYPT_PIN_PROPERTY,
                        propertyBytes,
                        CngPropertyOptions.None);

                    rsaCng.Key.SetProperty(pinProperty);
                    return(rsaCng.Decrypt(decodedEncryptedBytes, padding));
                }
                throw new CryptographicException("The key is not compatible with Cryptography Next Generation (CNG)");
            }
            catch (CryptographicException ex)
            {
                throw ex;
            }
            catch (ArgumentNullException ex)
            {
                throw ex;
            }
            catch (FormatException ex)
            {
                throw ex;
            }
        }
コード例 #10
0
ファイル: PropertyTests.cs プロジェクト: noahfalk/corefx
        public static void SetPropertyZeroLengthCornerCase()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                const string propertyName = "CustomZeroLengthProperty";
                CngProperty p = new CngProperty(propertyName, new byte[0], CngPropertyOptions.CustomProperty);
                key.SetProperty(p);

                CngProperty p2 = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.Equal(propertyName, p2.Name);
                Assert.Equal(CngPropertyOptions.CustomProperty, p2.Options);

                // This one is odd. CNG keys can have properties with zero length but CngKey.GetProperty() transforms this into null.
                Assert.Equal(null, p2.GetValue());
            }
        }
コード例 #11
0
        //
        // The first parameter is a delegate that instantiates a CngKey rather than a CngKey itself. That's because CngKeys are stateful objects
        // and concurrent encryptions on the same CngKey will corrupt each other.
        //
        // The delegate must instantiate a new CngKey, based on a new underlying NCryptKeyHandle, each time is called.
        //
        public BasicSymmetricCipherNCrypt(Func <CngKey> cngKeyFactory, CipherMode cipherMode, int blockSizeInBytes, byte[] iv, bool encrypting)
            : base(iv, blockSizeInBytes)
        {
            _encrypting = encrypting;
            _cngKey     = cngKeyFactory();
            CngProperty chainingModeProperty = cipherMode switch
            {
                CipherMode.ECB => s_ECBMode,
                CipherMode.CBC => s_CBCMode,
                _ => throw new CryptographicException(SR.Cryptography_InvalidCipherMode),
            };

            _cngKey.SetProperty(chainingModeProperty);

            Reset();
        }
コード例 #12
0
        public static void SetPropertyZeroLengthCornerCase()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                const string propertyName = "CustomZeroLengthProperty";
                CngProperty  p            = new CngProperty(propertyName, new byte[0], CngPropertyOptions.CustomProperty);
                key.SetProperty(p);

                CngProperty p2 = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.Equal(propertyName, p2.Name);
                Assert.Equal(CngPropertyOptions.CustomProperty, p2.Options);

                // This one is odd. CNG keys can have properties with zero length but CngKey.GetProperty() transforms this into null.
                Assert.Null(p2.GetValue());
            }
        }
コード例 #13
0
        public static void GetAndSetProperties()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                string propertyName = "Are you there";
                bool   hasProperty  = key.HasProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.False(hasProperty);

                byte[]      propertyValue = { 1, 2, 3 };
                CngProperty property      = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                byte[] actualValue = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty).GetValue();
                Assert.Equal <byte>(propertyValue, actualValue);
            }
        }
コード例 #14
0
ファイル: PropertyTests.cs プロジェクト: noahfalk/corefx
        public static void GetAndSetProperties()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                string propertyName = "Are you there";
                bool hasProperty = key.HasProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.False(hasProperty);

                byte[] propertyValue = { 1, 2, 3 };
                CngProperty property = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                byte[] actualValue = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty).GetValue();
                Assert.Equal<byte>(propertyValue, actualValue);
            }
        }
コード例 #15
0
ファイル: CngKey.Properties.cs プロジェクト: ESgarbi/corefx
        /// <summary>
        ///     Set an arbitrary property on the key
        /// </summary>
        public void SetProperty(CngProperty property)
        {
            unsafe
            {
                byte[] propertyValue = property.GetValueWithoutCopying();

                // Desktop compat. It would have nicer to throw an ArgumentNull exception or something...
                if (propertyValue == null)
                    throw ErrorCode.NTE_INVALID_PARAMETER.ToCryptographicException();

                fixed (byte* pinnedPropertyValue = propertyValue.MapZeroLengthArrayToNonNullPointer())
                {
                    ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(_keyHandle, property.Name, pinnedPropertyValue, propertyValue.Length, property.Options);
                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                        throw errorCode.ToCryptographicException();
                }
            }
        }
コード例 #16
0
        internal static void SetAccessRuleOnKSPKey(CngKey key, string accountName, CryptoKeyRights keyAccessMask)
        {
            const string             NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr";
            const CngPropertyOptions DACL_SECURITY_INFORMATION      = (CngPropertyOptions)4;

            // retrieve existing permissions
            var existingACL = key.GetProperty(NCRYPT_SECURITY_DESCR_PROPERTY, DACL_SECURITY_INFORMATION);

            // add new rule
            CryptoKeySecurity keySec = new CryptoKeySecurity();

            keySec.SetSecurityDescriptorBinaryForm(existingACL.GetValue());
            keySec.AddAccessRule(new CryptoKeyAccessRule(accountName, keyAccessMask, AccessControlType.Allow));

            // put back
            CngProperty updatedACL = new CngProperty(existingACL.Name, keySec.GetSecurityDescriptorBinaryForm(), CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION);

            key.SetProperty(updatedACL);
        }
コード例 #17
0
        /// <summary>
        /// Computes the hash value of the specified byte array using the specified hash algorithm,
        /// and signs the resulting hash value using a certificate with a pin.
        /// https://stackoverflow.com/questions/42626742/how-can-i-set-pin-for-a-x509certificate2-programmatically
        /// </summary>
        /// <param name="data">Data (not hash) to be signed</param>
        /// <param name="privateKey">The private key used for signing</param>
        /// <param name="hashAlgorithm">The hash algorithm used in hashing the data before signing</param>
        /// <param name="padding">The padding that will be used in the signature</param>
        /// <param name="pin">The private key pin</param>
        /// <returns>Return signed hash as byte array, or null if fails</returns>
        /// <exception cref="ArgumentException">There is null in the parameters or one of the parameters empty</exception>
        /// <exception cref="CryptographicException">The cryptographic service provider (CSP) cannot be acquired.-or- The parameters parameter has missing fields. -or- The padding mode is not supported. -or- The certificate context is invalid. -or- wrong pin has been inputed.</exception>
        public static byte[] SignData(byte[] data, X509Certificate2 privateKey, HashAlgorithmName hashAlgorithm, RSASignaturePadding padding, string pin)
        {
            try
            {
                RSA    rsa    = privateKey.GetRSAPrivateKey();
                RSACng rsaCng = rsa as RSACng;
                if (rsaCng != null)
                {
                    // Set the PIN, an explicit null terminator is required to this Unicode/UCS-2 string.

                    byte[] propertyBytes;

                    if (pin[pin.Length - 1] == '\0')
                    {
                        propertyBytes = Encoding.Unicode.GetBytes(pin);
                    }
                    else
                    {
                        propertyBytes = new byte[Encoding.Unicode.GetByteCount(pin) + 2];
                        Encoding.Unicode.GetBytes(pin, 0, pin.Length, propertyBytes, 0);
                    }

                    const string NCRYPT_PIN_PROPERTY = "SmartCardPin";

                    CngProperty pinProperty = new CngProperty(
                        NCRYPT_PIN_PROPERTY,
                        propertyBytes,
                        CngPropertyOptions.None);

                    rsaCng.Key.SetProperty(pinProperty);
                    return(rsaCng.SignData(data, hashAlgorithm, padding));
                }
                throw new CryptographicException("The key is not compatible with Cryptography Next Generation (CNG)");
            }
            catch (ArgumentException ex)
            {
                throw ex;
            }
            catch (CryptographicException ex)
            {
                throw ex;
            }
        }
コード例 #18
0
        public static void AddKeyToCng(string providerName, string containerName)
        {
#if NET5_0_OR_GREATER
            System.Diagnostics.Debug.Assert(OperatingSystem.IsWindows());
#endif
            CngKeyCreationParameters keyParams = new CngKeyCreationParameters();

            keyParams.Provider           = new CngProvider(providerName);
            keyParams.KeyCreationOptions = CngKeyCreationOptions.None;

            CngProperty keySizeProperty = new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.None);
            keyParams.Parameters.Add(keySizeProperty);

            // Add Cng Key only if not exists.
            if (!CngKey.Exists(containerName))
            {
                CngKey mycngKey = CngKey.Create(CngAlgorithm.Rsa, containerName, keyParams);
            }
        }
コード例 #19
0
        public static RSACng GetOrCreateRSACng(string rsaKeyName)
        {
            Guard.AgainstNullOrEmpty(rsaKeyName, nameof(rsaKeyName));

            CngKey cngKey;

            if (CngKey.Exists(rsaKeyName))
            {
                cngKey = CngKey.Open(rsaKeyName);
            }
            else
            {
                var cngLengthProperty = new CngProperty(
                    _lengthPropertyName,
                    BitConverter.GetBytes(KeySize),
                    CngPropertyOptions.None);

                var cngKeyCreationParameters = new CngKeyCreationParameters
                {
                    KeyUsage     = CngKeyUsages.AllUsages,
                    ExportPolicy =
                        CngExportPolicies.AllowPlaintextExport
                        | CngExportPolicies.AllowExport
                        | CngExportPolicies.AllowArchiving
                        | CngExportPolicies.AllowPlaintextArchiving
                };

                cngKeyCreationParameters.Parameters.Add(cngLengthProperty);

                cngKey = CngKey.Create(CngAlgorithm.Rsa, rsaKeyName, cngKeyCreationParameters);
            }

            return(new RSACng(cngKey)
            {
                KeySize = KeySize
            });
        }
コード例 #20
0
        public CngKey GetOrGenerateKey(int keySize, CngAlgorithm algorithm)
        {
            // If our key size was changed from the key we're using, we need to generate a new key.
            if (_lazyKey != null && _lazyKey.KeySize != keySize)
            {
                _lazyKey.Dispose();
                _lazyKey = null;
            }

            // If we don't have a key yet, we need to generate a random one now.
            if (_lazyKey == null)
            {
                CngKeyCreationParameters creationParameters = new CngKeyCreationParameters()
                {
                    ExportPolicy = CngExportPolicies.AllowPlaintextExport,
                };

                CngProperty keySizeProperty = new CngProperty(KeyPropertyName.Length, BitConverter.GetBytes(keySize), CngPropertyOptions.None);
                creationParameters.Parameters.Add(keySizeProperty);
                _lazyKey = CngKey.Create(algorithm, null, creationParameters);
            }

            return(_lazyKey);
        }
コード例 #21
0
        public static void OverwriteProperties()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                string propertyName = "Are you there";
                bool   hasProperty  = key.HasProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.False(hasProperty);

                // Set it once.
                byte[]      propertyValue = { 1, 2, 3 };
                CngProperty property      = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                // Set it again.
                propertyValue = new byte[] { 5, 6, 7 };
                property      = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                CngProperty retrievedProperty = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.Equal(propertyName, retrievedProperty.Name);
                Assert.Equal <byte>(propertyValue, retrievedProperty.GetValue());
                Assert.Equal(CngPropertyOptions.CustomProperty, retrievedProperty.Options);
            }
        }
コード例 #22
0
 public void SetProperty(CngProperty property)
 {
     NCryptNative.SetProperty(this.m_keyHandle, property.Name, property.Value, property.Options);
 }
コード例 #23
0
 private void Reset()
 {
     if (IV != null)
     {
         CngProperty prop = new CngProperty(Interop.NCrypt.NCRYPT_INITIALIZATION_VECTOR, IV, CngPropertyOptions.None);
         _cngKey.SetProperty(prop);
     }
 }
コード例 #24
0
        /// <summary>
        /// Tries to generate and RSA Key in the given provider with this keyName.
        /// </summary>
        /// <param name="providerName">Name of the provider</param>
        /// <param name="keyName">Name of the key</param>
        /// <param name="keyLength">Length of the key to generate</param>
        /// <returns>true if successful, false if that key already exists.</returns>
        public bool TryGenerateLocalRSAKey(string providerName, string keyName, int keyLength = 2048)
        {
            CngProvider provider = new CngProvider(providerName);

            bool keyExists = doesKeyExists(provider, keyName);

            if (keyExists)
            {
                //Key already exists. Can't create it.
                return(false);
            }

            CryptoKeySecurity        sec       = new CryptoKeySecurity();
            CngKeyCreationParameters keyParams = null;

            if (IsMicrosoftSoftwareKSP(provider))
            {
                sec.AddAccessRule(
                    new CryptoKeyAccessRule(
                        new SecurityIdentifier(sidType: WellKnownSidType.BuiltinAdministratorsSid, domainSid: null),
                        cryptoKeyRights: CryptoKeyRights.FullControl,
                        type: AccessControlType.Allow));

                sec.AddAccessRule(
                    new CryptoKeyAccessRule(
                        new SecurityIdentifier(sidType: WellKnownSidType.BuiltinSystemOperatorsSid, domainSid: null),
                        cryptoKeyRights: CryptoKeyRights.GenericRead,
                        type: AccessControlType.Allow));

                const string             NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr";
                const CngPropertyOptions DACL_SECURITY_INFORMATION      = (CngPropertyOptions)4;

                CngProperty permissions = new CngProperty(
                    NCRYPT_SECURITY_DESCR_PROPERTY,
                    sec.GetSecurityDescriptorBinaryForm(),
                    CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION);
                keyParams = new CngKeyCreationParameters()
                {
                    ExportPolicy = CngExportPolicies.None,
                    Provider     = provider,
                    Parameters   = { new CngProperty("Length", BitConverter.GetBytes(keyLength), CngPropertyOptions.None),
                                     permissions },
                    KeyCreationOptions = CngKeyCreationOptions.MachineKey
                };
                using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams))
                {
                    if (key == null)
                    {
                        return(false);
                    }
                    return(true);
                }
            }
            else
            {
                keyParams = new CngKeyCreationParameters()
                {
                    ExportPolicy = CngExportPolicies.None,
                    Provider     = provider,
                    Parameters   = { new CngProperty("Length", BitConverter.GetBytes(keyLength), CngPropertyOptions.None) }
                };
                using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams))
                {
                    if (key == null)
                    {
                        return(false);
                    }
                    // nothing to do inside here, except to return without throwing an exception
                    return(true);
                }
            }
        }
コード例 #25
0
        /// <summary>
        /// Sign an XML file.
        /// </summary>
        /// <param name="xmlDoc"> XML document object that holds the XML data</param>
        /// <param name="signingKey">The certificate which will be used in signing the XML document</param>
        /// <param name="addKey">Flag to indicate if the public key should be included in the signed XML document or not</param>
        /// <param name="pin">The pin of the CNG certificate.</param>
        /// <exception cref="ArgumentNullException">Private key is null or any of the passed arguments is null.</exception>
        /// <exception cref="CryptographicException">The key value is not an RSA key, or the key is unreadable.</exception>
        /// <exception cref="NotSupportedException">The key algorithm for this private key is not supported.</exception>
        /// <exception cref="CryptographicUnexpectedOperationException">The X.509 keys do not match.</exception>
        /// <exception cref="ArgumentException">The cryptographic service provider key is null.</exception>
        private static void SignXml(XmlDocument xmlDoc, X509Certificate2 signingKey, bool addKey, string pin)
        {
            if (signingKey == null)
            {
                throw new ArgumentNullException("signingKey is null");
            }

            // Create RSA signing key and save it in the container.
            RSACng key = null;

            // Try to load the RSA CNG key into key container.
            try
            {
                RSA rsa = signingKey.GetRSAPrivateKey();
                key = rsa as RSACng;
                if (key != null)
                {
                    // Set the PIN, an explicit null terminator is required to this Unicode/UCS-2 string.

                    byte[] propertyBytes;

                    if (pin[pin.Length - 1] == '\0')
                    {
                        propertyBytes = Encoding.Unicode.GetBytes(pin);
                    }
                    else
                    {
                        propertyBytes = new byte[Encoding.Unicode.GetByteCount(pin) + 2];
                        Encoding.Unicode.GetBytes(pin, 0, pin.Length, propertyBytes, 0);
                    }

                    const string NCRYPT_PIN_PROPERTY = "SmartCardPin";

                    CngProperty pinProperty = new CngProperty(
                        NCRYPT_PIN_PROPERTY,
                        propertyBytes,
                        CngPropertyOptions.None);

                    key.Key.SetProperty(pinProperty);
                }
                else
                {
                    throw new CryptographicException("The key is not compatible with Cryptography Next Generation (CNG)");
                }
            }
            catch (ArgumentException ex)
            {
                throw ex;
            }
            catch (CryptographicException ex)
            {
                throw ex;
            }

            // Check arguments.
            if (xmlDoc == null)
            {
                throw new ArgumentNullException("xmlDoc is null");
            }

            // Create a SignedXml object.
            SignedXml signedXml = new SignedXml(xmlDoc)
            {
                // Add the key to the SignedXml document.
                SigningKey = key ?? throw new ArgumentNullException("Private key is null")
            };

            // Add public key of the certificate
            if (addKey)
            {
                KeyInfo         keyInfo     = new KeyInfo();
                KeyInfoX509Data keyInfoData = new KeyInfoX509Data(signingKey);
                keyInfo.AddClause(keyInfoData);
                signedXml.KeyInfo = keyInfo;
            }

            // Create a reference to be signed.
            Reference reference = new Reference();

            reference.Uri = "";

            // Add an enveloped transformation to the reference.
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();

            reference.AddTransform(env);

            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);

            // Compute the signature.
            signedXml.ComputeSignature();

            // Get the XML representation of the signature and save
            // it to an XmlElement object.
            XmlElement xmlDigitalSignature = signedXml.GetXml();

            // Append the element to the XML document.
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
        }
コード例 #26
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));
        }
コード例 #27
0
ファイル: CngKey.cs プロジェクト: ItsVeryWindy/mono
 public void SetProperty(CngProperty property) {
     Contract.Assert(m_keyHandle != null);
     NCryptNative.SetProperty(m_keyHandle, property.Name, property.Value, property.Options);
 }
コード例 #28
0
ファイル: EccKey.cs プロジェクト: zzyzy/jose-jwt
        /// <summary>
        /// Creates CngKey Elliptic Curve Key from given (x,y) curve point - public part
        /// and optional d - private part
        /// </summary>
        /// <param name="x">x coordinate of curve point</param>
        /// <param name="y">y coordinate of curve point</param>
        /// <param name="d">optional private part</param>
        /// <returns>CngKey for given (x,y) and d</returns>
        public static CngKey New(byte[] x, byte[] y, byte[] d = null, CngKeyUsages usage = CngKeyUsages.Signing)
        {
            if (x.Length != y.Length)
            {
                throw new ArgumentException("X,Y and D must be same size");
            }

            if (d != null && x.Length != d.Length)
            {
                throw new ArgumentException("X,Y and D must be same size");
            }

            if (usage != CngKeyUsages.Signing && usage != CngKeyUsages.KeyAgreement)
            {
                throw new ArgumentException("Usage parameter expected to be set either 'CngKeyUsages.Signing' or 'CngKeyUsages.KeyAgreement");
            }

            bool signing = usage == CngKeyUsages.Signing;

            int partSize = x.Length;

            byte[] magic;

            if (partSize == 32)
            {
                magic = (d == null)
                            ? signing ? BCRYPT_ECDSA_PUBLIC_P256_MAGIC : BCRYPT_ECDH_PUBLIC_P256_MAGIC
                            : signing ? BCRYPT_ECDSA_PRIVATE_P256_MAGIC : BCRYPT_ECDH_PRIVATE_P256_MAGIC;
            }
            else if (partSize == 48)
            {
                magic = (d == null)
                            ? signing ? BCRYPT_ECDSA_PUBLIC_P384_MAGIC : BCRYPT_ECDH_PUBLIC_P384_MAGIC
                            : signing ? BCRYPT_ECDSA_PRIVATE_P384_MAGIC : BCRYPT_ECDH_PRIVATE_P384_MAGIC;
            }
            else if (partSize == 66)
            {
                magic = (d == null)
                            ? signing ? BCRYPT_ECDSA_PUBLIC_P521_MAGIC : BCRYPT_ECDH_PUBLIC_P521_MAGIC
                            : signing ? BCRYPT_ECDSA_PRIVATE_P521_MAGIC : BCRYPT_ECDH_PRIVATE_P521_MAGIC;
            }
            else
            {
                throw new ArgumentException("Size of X,Y or D must equal to 32, 48 or 66 bytes");
            }

            byte[] partLength = BitConverter.GetBytes(partSize);

            CngKeyBlobFormat blobType;

            byte[] blob;

            if (d == null)
            {
                blob     = Arrays.Concat(magic, partLength, x, y);
                blobType = CngKeyBlobFormat.EccPublicBlob;
            }
            else
            {
                blob     = Arrays.Concat(magic, partLength, x, y, d);
                blobType = CngKeyBlobFormat.EccPrivateBlob;
            }

            CngKey key = CngKey.Import(blob, blobType);

            CngProperty exportable = new CngProperty(
                "Export Policy",
                BitConverter.GetBytes((int)(CngExportPolicies.AllowPlaintextExport)),
                CngPropertyOptions.Persist
                );

            key.SetProperty(exportable);

            return(key);
        }
コード例 #29
0
ファイル: CngKey.cs プロジェクト: ItsVeryWindy/mono
 public void SetProperty(CngProperty property) {
     throw new NotImplementedException ();
 }
コード例 #30
0
ファイル: PropertyTests.cs プロジェクト: noahfalk/corefx
        public static void OverwriteProperties()
        {
            using (CngKey key = CngKey.Import(TestData.Key_ECDiffieHellmanP256, CngKeyBlobFormat.GenericPublicBlob))
            {
                string propertyName = "Are you there";
                bool hasProperty = key.HasProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.False(hasProperty);

                // Set it once.
                byte[] propertyValue = { 1, 2, 3 };
                CngProperty property = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                // Set it again.
                propertyValue = new byte[] { 5, 6, 7 };
                property = new CngProperty(propertyName, propertyValue, CngPropertyOptions.CustomProperty);
                key.SetProperty(property);

                CngProperty retrievedProperty = key.GetProperty(propertyName, CngPropertyOptions.CustomProperty);
                Assert.Equal(propertyName, retrievedProperty.Name);
                Assert.Equal<byte>(propertyValue, retrievedProperty.GetValue());
                Assert.Equal(CngPropertyOptions.CustomProperty, retrievedProperty.Options);
            }
        }
コード例 #31
0
ファイル: PropertyTests.cs プロジェクト: pedrobsaila/runtime
        public static void NullValueRoundtrip()
        {
            CngProperty property = new CngProperty("banana", null, CngPropertyOptions.CustomProperty);

            Assert.Null(property.GetValue());
        }
コード例 #32
0
ファイル: CngAlgorithmCore.cs プロジェクト: ESgarbi/corefx
        public CngKey GetOrGenerateKey(ECCurve? curve)
        {
            if (_lazyKey != null)
            {
                return _lazyKey;
            }

            // We don't have a key yet so generate
            Debug.Assert(curve.HasValue);

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

            if (curve.Value.IsNamed)
            {
                creationParameters.Parameters.Add(CngKey.GetPropertyFromNamedCurve(curve.Value));
            }
            else if (curve.Value.IsPrime)
            {
                ECCurve eccurve = curve.Value;
                byte[] parametersBlob = ECCng.GetPrimeCurveParameterBlob(ref eccurve);
                CngProperty prop = new CngProperty(
                    Interop.BCrypt.BCryptPropertyStrings.BCRYPT_ECC_PARAMETERS,
                    parametersBlob,
                    CngPropertyOptions.None);
                creationParameters.Parameters.Add(prop);
            }
            else
            {
                throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Value.CurveType.ToString()));
            }

            try
            {
                _lazyKey = CngKey.Create(CngAlgorithm.ECDsa, null, creationParameters);
            }
            catch (CryptographicException e)
            {
                // Map to PlatformNotSupportedException if appropriate
                ErrorCode errorCode = (ErrorCode)e.HResult;

                if (curve.Value.IsNamed &&
                    errorCode == ErrorCode.NTE_INVALID_PARAMETER || errorCode == ErrorCode.NTE_NOT_SUPPORTED)
                {
                    throw new PlatformNotSupportedException(string.Format(SR.Cryptography_CurveNotSupported, curve.Value.Oid.FriendlyName), e);
                }
                throw;
            }

            return _lazyKey;
        }
コード例 #33
0
        /// <summary>
        /// Import a key from a file for use on the machine.
        /// </summary>
        /// <param name="providerName"></param>
        /// <param name="filePath"></param>
        public bool ImportKeyToKSP(string providerName, string keyName, string filePath, bool makeExportable = false)
        {
            CngProvider provider = new CngProvider(providerName);

            bool keyExists = doesKeyExists(provider, keyName);

            if (keyExists)
            {
                //Key already exists. Can't create it.
                return(false);
            }

            CryptoKeySecurity        sec       = new CryptoKeySecurity();
            CngKeyCreationParameters keyParams = null;

            byte[] keyBlob = File.ReadAllBytes(filePath);

            CngProperty keyBlobProp = new CngProperty(new CngKeyBlobFormat("RSAFULLPRIVATEBLOB").Format, keyBlob, CngPropertyOptions.None);

            if (IsMicrosoftSoftwareKSP(provider))
            {
                sec.AddAccessRule(
                    new CryptoKeyAccessRule(
                        new SecurityIdentifier(sidType: WellKnownSidType.BuiltinAdministratorsSid, domainSid: null),
                        cryptoKeyRights: CryptoKeyRights.FullControl,
                        type: AccessControlType.Allow));

                sec.AddAccessRule(
                    new CryptoKeyAccessRule(
                        new SecurityIdentifier(sidType: WellKnownSidType.BuiltinSystemOperatorsSid, domainSid: null),
                        cryptoKeyRights: CryptoKeyRights.GenericRead,
                        type: AccessControlType.Allow));

                const string             NCRYPT_SECURITY_DESCR_PROPERTY = "Security Descr";
                const CngPropertyOptions DACL_SECURITY_INFORMATION      = (CngPropertyOptions)4;

                CngProperty permissions = new CngProperty(
                    NCRYPT_SECURITY_DESCR_PROPERTY,
                    sec.GetSecurityDescriptorBinaryForm(),
                    CngPropertyOptions.Persist | DACL_SECURITY_INFORMATION);
                keyParams = new CngKeyCreationParameters()
                {
                    ExportPolicy       = makeExportable ? CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport : CngExportPolicies.None,
                    Provider           = provider,
                    Parameters         = { permissions, keyBlobProp },
                    KeyCreationOptions = CngKeyCreationOptions.MachineKey
                };
                using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams))
                {
                    if (key == null)
                    {
                        return(false);
                    }
                    return(true);
                }
            }
            else
            {
                keyParams = new CngKeyCreationParameters()
                {
                    ExportPolicy       = makeExportable ? CngExportPolicies.AllowExport | CngExportPolicies.AllowPlaintextExport : CngExportPolicies.None,
                    Provider           = provider,
                    Parameters         = { keyBlobProp },
                    KeyCreationOptions = CngKeyCreationOptions.MachineKey
                };
                using (CngKey key = CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams))
                {
                    if (key == null)
                    {
                        return(false);
                    }
                    // nothing to do inside here, except to return without throwing an exception
                    return(true);
                }
            }
        }
コード例 #34
0
 public void SetProperty(CngProperty property)
 {
 }