Ejemplo n.º 1
0
        public static void Import(this ECDsaCng eCDsaCng, Dictionary <string, string> content)
        {
            var     ecParameters = new ECParameters();
            ECCurve curve        = default(ECCurve);

            if (content.ContainsKey(ECFields.CURVE))
            {
                switch (content[ECFields.CURVE])
                {
                case "P-256":
                    curve = ECCurve.NamedCurves.nistP256;
                    break;

                case "P-384":
                    curve = ECCurve.NamedCurves.nistP384;
                    break;

                case "P-521":
                    curve = ECCurve.NamedCurves.nistP521;
                    break;
                }
            }

            var q = new ECPoint
            {
                X = content.TryGet(ECFields.X),
                Y = content.TryGet(ECFields.Y)
            };

            ecParameters.Q     = q;
            ecParameters.Curve = curve;
            ecParameters.D     = content.TryGet(ECFields.D);
            eCDsaCng.ImportParameters(ecParameters);
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            byte[] data = new byte[] { 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[] x = new byte[] { 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 = new byte[] { 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 = new byte[] { 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 };

            ECParameters ecp = new ECParameters();

            ecp.Curve = ECCurve.NamedCurves.nistP256;
            ecp.Q.X   = x;
            ecp.Q.Y   = y;
            ecp.D     = d;

            ECDsaCng ecDsaCng = new ECDsaCng();

            ecDsaCng.ImportParameters(ecp);
            CngKey cngKey = ecDsaCng.Key;

            ECDsaCng eCDsaCng = new ECDsaCng(cngKey);

            byte[] sign = eCDsaCng.SignData(data);
            Console.WriteLine(eCDsaCng.VerifyData(data, sign));
            Console.ReadKey();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates an instance of the platform specific implementation of the cref="ECDsa" algorithm.
        /// </summary>
        /// <param name="parameters">
        /// The <see cref="ECParameters"/> representing the elliptic curve parameters.
        /// </param>
        public static partial ECDsa Create(ECParameters parameters)
        {
            ECDsa ec = new ECDsaCng();

            ec.ImportParameters(parameters);
            return(new ECDsaWrapper(ec));
        }
Ejemplo n.º 4
0
        /// <summary>创建ECDsa对象,支持Base64密钥和Pem密钥</summary>
        /// <param name="key"></param>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        public static ECDsaCng Create(String key, Boolean?privateKey = null)
        {
            key = key?.Trim();
            if (key.IsNullOrEmpty())
            {
                return(null);
            }

            if (key.StartsWith("-----") && key.EndsWith("-----"))
            {
                var ek = ReadPem(key);

                // netcore下优先使用ExportParameters,CngKey.Import有兼容问题
                var ec = new ECDsaCng();
                ec.ImportParameters(ek.ExportParameters());

                return(ec);

                //var buf = ek.ToArray();
                //var ckey = CngKey.Import(buf, ek.D == null ? CngKeyBlobFormat.EccPublicBlob : CngKeyBlobFormat.EccPrivateBlob);
                //return new ECDsaCng(ckey);
            }
            else
            {
                var buf  = key.ToBase64();
                var ckey =
                    privateKey != null?
                    CngKey.Import(buf, !privateKey.Value?CngKeyBlobFormat.EccPublicBlob : CngKeyBlobFormat.EccPrivateBlob) :
                        CngKey.Import(buf, buf.Length < 100 ? CngKeyBlobFormat.EccPublicBlob : CngKeyBlobFormat.EccPrivateBlob);

                return(new ECDsaCng(ckey));
            }
        }
Ejemplo n.º 5
0
        public void GenerateKey(Int32 keySize)
        {
            // 生成密钥
            var ks = ECDsaHelper.GenerateKey(keySize);

            Assert.NotNull(ks);
            Assert.Equal(2, ks.Length);

            //var magic = ks[0].ToBase64().ReadBytes(0, 4).ToInt();
            //var magic2 = ks[1].ToBase64().ReadBytes(0, 4).ToInt();

            {
                // 重新导入
                var data = ks[0].ToBase64();
                var key  = CngKey.Import(data, CngKeyBlobFormat.EccPrivateBlob);
                var ec   = new ECDsaCng(key);

                // 解码KeyBlob格式
                var eckey = new ECKey();
                eckey.Read(data);
                Assert.Equal(data.ToBase64(), eckey.ToArray().ToBase64());

                // 幻数(4) + 长度len(4) + X(len) + Y(len) + D(len)
                Assert.Equal($"ECDSA_PRIVATE_P{keySize}", eckey.Algorithm);

                // 构造参数
                var ecp = eckey.ExportParameters();

                // 再次以参数导入,然后导出key进行对比
                var ec2 = new ECDsaCng();
                ec2.ImportParameters(ecp);
                var key2 = ec2.Key.Export(CngKeyBlobFormat.EccPrivateBlob).ToBase64();
                Assert.Equal(ks[0], key2);
            }

            {
                // 重新导入
                var data = ks[1].ToBase64();
                var key  = CngKey.Import(data, CngKeyBlobFormat.EccPublicBlob);
                var ec   = new ECDsaCng(key);

                // 解码KeyBlob格式
                var eckey = new ECKey();
                eckey.Read(data);
                Assert.Equal(data.ToBase64(), eckey.ToArray().ToBase64());

                // 幻数(4) + 长度len(4) + X(len) + Y(len) + D(len)
                Assert.Equal($"ECDSA_PUBLIC_P{keySize}", eckey.Algorithm);

                // 构造参数
                var ecp = eckey.ExportParameters();

                // 再次以参数导入,然后导出key进行对比
                var ec2 = new ECDsaCng();
                ec2.ImportParameters(ecp);
                var key2 = ec2.Key.Export(CngKeyBlobFormat.EccPublicBlob).ToBase64();
                Assert.Equal(ks[1], key2);
            }
        }
        public static X509Certificate2 CopyWithPrivateKey(this X509Certificate2 certificate, ECDsa privateKey)
        {
            if (certificate == null)
            {
                throw new ArgumentNullException(nameof(certificate));
            }
            if (privateKey == null)
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            if (certificate.HasPrivateKey)
            {
                throw new InvalidOperationException(SR.GetString(SR.Cryptography_Cert_AlreadyHasPrivateKey));
            }

            using (ECDsa publicKey = GetECDsaPublicKey(certificate))
            {
                if (publicKey == null)
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_WrongAlgorithm));
                }

                if (!IsSameKey(publicKey, privateKey))
                {
                    throw new ArgumentException(SR.GetString(SR.Cryptography_PrivateKey_DoesNotMatch), nameof(privateKey));
                }
            }

            ECDsaCng         ecdsaCng = privateKey as ECDsaCng;
            X509Certificate2 newCert  = null;

            if (ecdsaCng != null)
            {
                newCert = CertificateExtensionsCommon.CopyWithPersistedCngKey(certificate, ecdsaCng.Key);
            }

            // No CAPI option for ECDSA

            if (newCert == null)
            {
                ECParameters parameters = privateKey.ExportParameters(true);

                using (PinAndClear.Track(parameters.D))
                    using (ecdsaCng = new ECDsaCng())
                    {
                        ecdsaCng.ImportParameters(parameters);

                        newCert = CertificateExtensionsCommon.CopyWithEphemeralCngKey(certificate, ecdsaCng.Key);
                    }
            }

            Debug.Assert(newCert != null);
            Debug.Assert(!ReferenceEquals(certificate, newCert));
            Debug.Assert(!certificate.HasPrivateKey);
            Debug.Assert(newCert.HasPrivateKey);
            return(newCert);
        }
        public static ECDsa GetECDsaPublicKey(this X509Certificate2 certificate)
        {
            if (LocalAppContextSwitches.UseLegacyPublicKeyBehavior)
            {
                return(LegacyGetECDsaPublicKey(certificate));
            }

            if (certificate == null)
            {
                throw new ArgumentNullException("certificate");
            }
            if (!IsECDsa(certificate))
            {
                return(null);
            }

            using (SafeCertContextHandle safeCertContext = X509Native.GetCertificateContext(certificate))
                using (SafeBCryptKeyHandle bcryptKeyHandle = ImportPublicKeyInfo(safeCertContext))
                {
                    if (bcryptKeyHandle.IsInvalid)
                    {
                        throw new CryptographicException("SR.GetString(SR.Cryptography_OpenInvalidHandle)");
                    }

                    string curveName = GetCurveName(bcryptKeyHandle);

                    if (curveName == null)
                    {
                        CngKeyBlobFormat blobFormat = HasExplicitParameters(bcryptKeyHandle) ?
                                                      CngKeyBlobFormat.EccFullPublicBlob : CngKeyBlobFormat.EccPublicBlob;

                        byte[] keyBlob = BCryptNative.ExportBCryptKey(bcryptKeyHandle, blobFormat.Format);
                        using (CngKey key = CngKey.Import(keyBlob, blobFormat))
                        {
                            return(new ECDsaCng(key));
                        }
                    }
                    else
                    {
                        CngKeyBlobFormat blobFormat = CngKeyBlobFormat.EccPublicBlob;
                        byte[]           keyBlob    = BCryptNative.ExportBCryptKey(bcryptKeyHandle, blobFormat.Format);
                        ECParameters     ecparams   = new ECParameters();
                        ExportNamedCurveParameters(ref ecparams, keyBlob, false);
                        ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
                        ECDsaCng ecdsa = new ECDsaCng();
                        ecdsa.ImportParameters(ecparams);

                        return(ecdsa);
                    }
                }
        }
Ejemplo n.º 8
0
        private static ECDsa DecodeECDsaPublicKey(CertificatePal certificatePal)
        {
            ECDsa ecdsa;

            using (SafeBCryptKeyHandle bCryptKeyHandle = ImportPublicKeyInfo(certificatePal.CertContext))
            {
                CngKeyBlobFormat blobFormat;
                byte[]           keyBlob;
#if NETNATIVE
                blobFormat = CngKeyBlobFormat.EccPublicBlob;
                keyBlob    = ExportKeyBlob(bCryptKeyHandle, blobFormat);
                using (CngKey cngKey = CngKey.Import(keyBlob, blobFormat))
                {
                    ecdsa = new ECDsaCng(cngKey);
                }
#else
                string curveName = GetCurveName(bCryptKeyHandle);

                if (curveName == null)
                {
                    if (HasExplicitParameters(bCryptKeyHandle))
                    {
                        blobFormat = CngKeyBlobFormat.EccFullPublicBlob;
                    }
                    else
                    {
                        blobFormat = CngKeyBlobFormat.EccPublicBlob;
                    }

                    keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat);
                    using (CngKey cngKey = CngKey.Import(keyBlob, blobFormat))
                    {
                        ecdsa = new ECDsaCng(cngKey);
                    }
                }
                else
                {
                    blobFormat = CngKeyBlobFormat.EccPublicBlob;
                    keyBlob    = ExportKeyBlob(bCryptKeyHandle, blobFormat);
                    ECParameters ecparams = new ECParameters();
                    ExportNamedCurveParameters(ref ecparams, keyBlob, false);
                    ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName);
                    ecdsa          = new ECDsaCng();
                    ecdsa.ImportParameters(ecparams);
                }
#endif
            }

            return(ecdsa);
        }
Ejemplo n.º 9
0
        /// <summary>Constructor</summary>
        /// <param name="ecp">任意鍵</param>
        /// <param name="isPrivate">秘密鍵か否か</param>
        public DigitalSignECDsaCng(ECParameters ecp, bool isPrivate)
        {
            ECDsaCng ecDsaCng = new ECDsaCng();

            ecDsaCng.ImportParameters(ecp);
            CngKey cngKey = ecDsaCng.Key;

            this._publicKey = cngKey.Export(CngKeyBlobFormat.GenericPublicBlob);

            if (isPrivate)
            {
                this._privateKey = cngKey;
            }
        }
Ejemplo n.º 10
0
        public static void TestHashRoundTrip(CurveDef curveDef)
        {
            // This test is in the cng only tests because OpenSsl does not provide the hash algorithm
            using (var cng = new ECDsaCng(curveDef.Curve))
            {
                ECParameters param = cng.ExportExplicitParameters(false);

                // Add some dummy values and import
                Assert.True(param.Curve.IsExplicit);
                var curve = param.Curve;
                curve.Hash = HashAlgorithmName.SHA1;
                curve.Seed = new byte[1] { 0xFF }; // Hash should have a seed
                param.Curve = curve;
                cng.ImportParameters(param);

                // Export to see if the hash is there
                ECParameters param2 = cng.ExportExplicitParameters(false);
                Assert.Equal(HashAlgorithmName.SHA1.Name.ToUpper(), param2.Curve.Hash.Value.Name.ToUpper());
                Assert.Equal(0xFF, param2.Curve.Seed[0]);
            }
        }
Ejemplo n.º 11
0
        public static void TestHashRoundTrip(CurveDef curveDef)
        {
            // This test is in the cng only tests because OpenSsl does not provide the hash algorithm
            using (var cng = new ECDsaCng(curveDef.Curve))
            {
                ECParameters param = cng.ExportExplicitParameters(false);

                // Add some dummy values and import
                Assert.True(param.Curve.IsExplicit);
                var curve = param.Curve;
                curve.Hash = HashAlgorithmName.SHA1;
                curve.Seed = new byte[1] {
                    0xFF
                };                                 // Hash should have a seed
                param.Curve = curve;
                cng.ImportParameters(param);

                // Export to see if the hash is there
                ECParameters param2 = cng.ExportExplicitParameters(false);
                Assert.Equal(HashAlgorithmName.SHA1.Name.ToUpper(), param2.Curve.Hash.Value.Name.ToUpper());
                Assert.Equal(0xFF, param2.Curve.Seed[0]);
            }
        }
Ejemplo n.º 12
0
        public ICertificatePal CopyWithPrivateKey(ECDsa ecdsa)
        {
            ECDsaCng ecdsaCng = ecdsa as ECDsaCng;

            if (ecdsaCng != null)
            {
                ICertificatePal clone = CopyWithPersistedCngKey(ecdsaCng.Key);

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

            ECParameters privateParameters = ecdsa.ExportParameters(true);

            using (PinAndClear.Track(privateParameters.D))
                using (ECDsaCng clonedKey = new ECDsaCng())
                {
                    clonedKey.ImportParameters(privateParameters);

                    return(CopyWithEphemeralKey(clonedKey.Key));
                }
        }