예제 #1
0
        private static CngKey Ecc256Public(CngKeyUsages usage = CngKeyUsages.Signing)
        {
            byte[] x = { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
            byte[] y = { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
            byte[] d = { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

            return(EccKey.New(x, y, usage: usage));
        }
예제 #2
0
        /// <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;               ;
            }

            return CngKey.Import(blob, blobType);
        }
예제 #3
0
        /// <summary>
        ///     Setup the key properties specified in the key creation parameters
        /// </summary>
        private static void InitializeKeyProperties(SafeNCryptKeyHandle keyHandle, CngKeyCreationParameters creationParameters)
        {
            unsafe
            {
                if (creationParameters.ExportPolicy.HasValue)
                {
                    CngExportPolicies exportPolicy = creationParameters.ExportPolicy.Value;
                    keyHandle.SetExportPolicy(exportPolicy);
                }

                if (creationParameters.KeyUsage.HasValue)
                {
                    CngKeyUsages keyUsage  = creationParameters.KeyUsage.Value;
                    ErrorCode    errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.KeyUsage, &keyUsage, sizeof(CngKeyUsages), CngPropertyOptions.Persist);
                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                }

                if (creationParameters.ParentWindowHandle != IntPtr.Zero)
                {
                    IntPtr    parentWindowHandle = creationParameters.ParentWindowHandle;
                    ErrorCode errorCode          = Interop.NCrypt.NCryptSetProperty(keyHandle, KeyPropertyName.ParentWindowHandle, &parentWindowHandle, sizeof(IntPtr), CngPropertyOptions.None);
                    if (errorCode != ErrorCode.ERROR_SUCCESS)
                    {
                        throw errorCode.ToCryptographicException();
                    }
                }

                CngUIPolicy uiPolicy = creationParameters.UIPolicy;
                if (uiPolicy != null)
                {
                    InitializeKeyUiPolicyProperties(keyHandle, uiPolicy);
                }

                // Iterate over the custom properties, setting those as well.
                foreach (CngProperty property in creationParameters.Parameters)
                {
                    byte[] value       = property.GetValueWithoutCopying();
                    int    valueLength = (value == null) ? 0 : value.Length;
                    fixed(byte *pValue = value.MapZeroLengthArrayToNonNullPointer())
                    {
                        ErrorCode errorCode = Interop.NCrypt.NCryptSetProperty(keyHandle, property.Name, pValue, valueLength, property.Options);

                        if (errorCode != ErrorCode.ERROR_SUCCESS)
                        {
                            throw errorCode.ToCryptographicException();
                        }
                    }
                }
            }
        }
예제 #4
0
        /// <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;;
            }

            return(CngKey.Import(blob, blobType));
        }
예제 #5
0
        //---------------------------------------------------------------------
        // IKeyStoreAdapter
        //---------------------------------------------------------------------

        public Task <RSA> CreateRsaKeyAsync(
            string name,
            CngKeyUsages usage,
            bool createNewIfNotExists,
            IWin32Window window)
        {
            using (ApplicationTraceSources.Default.TraceMethod().WithoutParameters())
            {
                //
                // Create or open CNG key in the user profile.
                //
                // NB. Keys are stored in %APPDATA%\Microsoft\Crypto\Keys when using
                // the default Microsoft Software Key Storage Provider.
                // (see https://docs.microsoft.com/en-us/windows/win32/seccng/key-storage-and-retrieval)
                //
                // For testing, you can list CNG keys using
                // certutil -csp "Microsoft Software Key Storage Provider" -key -user
                //

                return(Task.Run <RSA>(() =>
                {
                    if (CngKey.Exists(name))
                    {
                        var key = CngKey.Open(name);
                        if (key.Algorithm != CngAlgorithm.Rsa)
                        {
                            throw new CryptographicException(
                                $"Key {name} is not an RSA key");
                        }

                        if ((key.KeyUsage & usage) == 0)
                        {
                            throw new CryptographicException(
                                $"Key {name} exists, but does not support requested usage");
                        }

                        return new RSACng(key);
                    }

                    if (createNewIfNotExists)
                    {
                        var keyParams = new CngKeyCreationParameters
                        {
                            // Do not overwrite, store in user profile.
                            KeyCreationOptions = CngKeyCreationOptions.None,

                            // Do not allow exporting.
                            ExportPolicy = CngExportPolicies.None,

                            Provider = this.provider,
                            KeyUsage = usage
                        };

                        //
                        // NB. If we're using the Smart Card provider, the key store
                        // might show a UI dialog.
                        //
                        if (window != null && window.Handle != null)
                        {
                            keyParams.ParentWindowHandle = window.Handle;
                        }

                        keyParams.Parameters.Add(
                            new CngProperty(
                                "Length",
                                BitConverter.GetBytes(this.keySize),
                                CngPropertyOptions.None));

                        //
                        // Create the key. That's a bit expensive, so do it
                        // asynchronously.
                        //
                        return new RSACng(CngKey.Create(
                                              CngAlgorithm.Rsa,
                                              name,
                                              keyParams));
                    }

                    return null;
                }));
            }
        }
예제 #6
0
        public static CngKey New(byte[] x, byte[] y, byte[] d = null, CngKeyUsages usage = CngKeyUsages.Signing)
        {
            byte[]           numArray;
            CngKeyBlobFormat eccPrivateBlob;

            byte[] numArray1;
            byte[] numArray2;
            byte[] numArray3;
            byte[] numArray4;
            if ((int)x.Length != (int)y.Length)
            {
                throw new ArgumentException("X,Y and D must be same size");
            }
            if (d != null && (int)x.Length != (int)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 flag   = usage == CngKeyUsages.Signing;
            int  length = (int)x.Length;

            if (length == 32)
            {
                if (d == null)
                {
                    numArray4 = (flag ? EccKey.BCRYPT_ECDSA_PUBLIC_P256_MAGIC : EccKey.BCRYPT_ECDH_PUBLIC_P256_MAGIC);
                }
                else
                {
                    numArray4 = (flag ? EccKey.BCRYPT_ECDSA_PRIVATE_P256_MAGIC : EccKey.BCRYPT_ECDH_PRIVATE_P256_MAGIC);
                }
                numArray = numArray4;
            }
            else if (length != 48)
            {
                if (length != 66)
                {
                    throw new ArgumentException("Size of X,Y or D must equal to 32, 48 or 66 bytes");
                }
                if (d == null)
                {
                    numArray2 = (flag ? EccKey.BCRYPT_ECDSA_PUBLIC_P521_MAGIC : EccKey.BCRYPT_ECDH_PUBLIC_P521_MAGIC);
                }
                else
                {
                    numArray2 = (flag ? EccKey.BCRYPT_ECDSA_PRIVATE_P521_MAGIC : EccKey.BCRYPT_ECDH_PRIVATE_P521_MAGIC);
                }
                numArray = numArray2;
            }
            else
            {
                if (d == null)
                {
                    numArray3 = (flag ? EccKey.BCRYPT_ECDSA_PUBLIC_P384_MAGIC : EccKey.BCRYPT_ECDH_PUBLIC_P384_MAGIC);
                }
                else
                {
                    numArray3 = (flag ? EccKey.BCRYPT_ECDSA_PRIVATE_P384_MAGIC : EccKey.BCRYPT_ECDH_PRIVATE_P384_MAGIC);
                }
                numArray = numArray3;
            }
            byte[] bytes = BitConverter.GetBytes(length);
            if (d != null)
            {
                numArray1      = Arrays.Concat(new byte[][] { numArray, bytes, x, y, d });
                eccPrivateBlob = CngKeyBlobFormat.EccPrivateBlob;
            }
            else
            {
                numArray1      = Arrays.Concat(new byte[][] { numArray, bytes, x, y });
                eccPrivateBlob = CngKeyBlobFormat.EccPublicBlob;
            }
            return(CngKey.Import(numArray1, eccPrivateBlob));
        }
예제 #7
0
        private CngKey Ecc256Private(CngKeyUsages usage=CngKeyUsages.Signing)
        {
            byte[] x = { 4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9 };
            byte[] y = { 131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53 };
            byte[] d = { 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 };

            return EccKey.New(x, y, d, usage);

        }