Пример #1
0
 public static byte[] ExportSubjectPublicKeyInfo(this ECDsa rsa, AsnFormat format)
 {
     return(format switch
     {
         AsnFormat.Der => rsa.ExportSubjectPublicKeyInfo(),
         AsnFormat.Pem => PemFormater.ToPemBytes(rsa.ExportSubjectPublicKeyInfo(), "PUBLIC KEY"),
         _ => throw new NotImplementedException()
     });
Пример #2
0
 public static byte[] ExportSubjectPublicKeyInfo(this ECDsa ecdsa, AsnFormat format)
 {
     return(format switch
     {
         AsnFormat.Der => ecdsa.ExportSubjectPublicKeyInfo(),
         AsnFormat.Pem => PemFormater.ToPemBytes(ecdsa.ExportSubjectPublicKeyInfo(), "PUBLIC KEY"),
         _ => ThrowHelpers.NotImplemented <byte[]>(nameof(ECDsaExtensions))
     });
        public static void PublicKeyConstructor_CannotSelfSign()
        {
            byte[] spki;

            using (ECDsa key = ECDsa.Create(EccTestData.Secp384r1Data.KeyParameters))
            {
                spki = key.ExportSubjectPublicKeyInfo();
            }

            PublicKey publicKey = PublicKey.CreateFromSubjectPublicKeyInfo(spki, out _);

            CertificateRequest req = new CertificateRequest(
                new X500DistinguishedName("CN=Test"),
                publicKey,
                HashAlgorithmName.SHA384);

            InvalidOperationException ex;

            ex = Assert.Throws <InvalidOperationException>(() => req.CreateSigningRequest());
            Assert.Contains(nameof(X509SignatureGenerator), ex.Message);

            DateTimeOffset notBefore = DateTimeOffset.UtcNow;
            DateTimeOffset notAfter  = notBefore.AddMinutes(1);

            ex = Assert.Throws <InvalidOperationException>(() => req.CreateSelfSigned(notBefore, notAfter));
            Assert.Contains(nameof(X509SignatureGenerator), ex.Message);
        }
Пример #4
0
        public static void GetECDsaPublicKey_ReturnsECDsaKey()
        {
            PublicKey key = GetTestECDsaKey();

            using (ECDsa ecdsa = key.GetECDsaPublicKey())
            {
                Assert.NotNull(ecdsa);
                Assert.Equal(ecdsa.ExportSubjectPublicKeyInfo(), key.ExportSubjectPublicKeyInfo());
            }
        }
Пример #5
0
        public static void CreateFromSubjectPublicKeyInfo_Roundtrip_ECDSA()
        {
            using ECDsa ecdsa = ECDsa.Create();
            ecdsa.ImportFromPem(TestData.ECDsaPkcs8PublicKey);
            byte[] spki = ecdsa.ExportSubjectPublicKeyInfo();

            PublicKey key = PublicKey.CreateFromSubjectPublicKeyInfo(spki, out int read);

            Assert.Throws <NotSupportedException>(() => key.Key);
            Assert.Equal("1.2.840.10045.2.1", key.Oid.Value);
            Assert.Equal(spki, key.ExportSubjectPublicKeyInfo());
            Assert.Equal(spki.Length, read);
        }
Пример #6
0
        public static void ExportSubjectPublicKeyInfo_ECDSA()
        {
            using ECDsa ecdsa = ECDsa.Create();
            ecdsa.ImportFromPem(TestData.ECDsaPkcs8PublicKey);
            PublicKey key = new PublicKey(ecdsa);

            Span <byte> algSpki = ecdsa.ExportSubjectPublicKeyInfo();

            Assert.True(algSpki.SequenceEqual(key.ExportSubjectPublicKeyInfo()), "SequenceEquals(ExportSubjectPublicKeyInfo)");

            // Just right
            Assert.True(key.TryExportSubjectPublicKeyInfo(algSpki, out int written), nameof(key.TryExportSubjectPublicKeyInfo));
            Assert.Equal(algSpki.Length, written);

            // Too small
            Assert.False(key.TryExportSubjectPublicKeyInfo(algSpki.Slice(1), out written), nameof(key.TryExportSubjectPublicKeyInfo));
            Assert.Equal(0, written);
        }
        public static void ECDSA_Signing_ECDSA_NoKeyUsageValidForECDSAAndECDH()
        {
            using ECDsa ecdsa     = ECDsa.Create(ECCurve.NamedCurves.nistP256);
            using ECDsa ecdsaLeaf = ECDsa.Create(ECCurve.NamedCurves.nistP256);

            CertificateRequest issuerRequest = new CertificateRequest(
                new X500DistinguishedName("CN=root"),
                ecdsa,
                HashAlgorithmName.SHA256);

            issuerRequest.CertificateExtensions.Add(
                new X509BasicConstraintsExtension(true, false, 0, true));

            CertificateRequest request = new CertificateRequest(
                new X500DistinguishedName("CN=test"),
                ecdsaLeaf,
                HashAlgorithmName.SHA256);

            request.CertificateExtensions.Add(
                new X509BasicConstraintsExtension(false, false, 0, true));

            DateTimeOffset notBefore = DateTimeOffset.UtcNow;
            DateTimeOffset notAfter  = notBefore.AddDays(30);

            byte[] serial = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            using X509Certificate2 issuer           = issuerRequest.CreateSelfSigned(notBefore, notAfter);
            using X509Certificate2 cert             = request.Create(issuer, notBefore, notAfter, serial);
            using ECDiffieHellman publicCertEcDhKey = cert.GetECDiffieHellmanPublicKey();
            using ECDsa publicCertEcDsaKey          = cert.GetECDsaPublicKey();
            byte[] expectedSubjectPublicKeyInfo = ecdsaLeaf.ExportSubjectPublicKeyInfo();

            Assert.NotNull(publicCertEcDhKey);
            Assert.NotNull(publicCertEcDsaKey);
            Assert.Equal(expectedSubjectPublicKeyInfo, publicCertEcDhKey.ExportSubjectPublicKeyInfo());
            Assert.Equal(expectedSubjectPublicKeyInfo, publicCertEcDsaKey.ExportSubjectPublicKeyInfo());
        }
Пример #8
0
        public void Initialize_key_Pair()
        {
            if (File.Exists("Keys/PUBkey.txt"))
            {
                Console.WriteLine("retreiving keys");
                using (FileStream fspub = File.OpenRead("Keys/PUBkey.txt"))
                    using (FileStream fsprv = File.OpenRead("Keys/PRVkey.txt"))
                    {
                        PublicKey   = new byte[fspub.Length];
                        private_key = new byte[fsprv.Length];

                        fspub.Read(PublicKey, 0, PublicKey.Length);
                        fsprv.Read(PrivateKey, 0, PrivateKey.Length);

                        //import the keys to the current ECDSA object
                        int         bytes, bytes2 = 0;
                        Span <byte> imported_prv_key = new Span <byte>(PrivateKey);
                        Span <byte> imported_pub_key = new Span <byte>(PublicKey);

                        Ecc.ImportECPrivateKey(imported_prv_key, out bytes);
                        Ecc.ImportSubjectPublicKeyInfo(imported_pub_key, out bytes2);
                    }
            }
            else
            {
                Console.WriteLine("creating new keys");

                using (FileStream fspub = File.Create("Keys/PUBkey.txt"))
                    using (FileStream fsprv = File.Create("Keys/PRVkey.txt"))
                    {
                        PublicKey   = Ecc.ExportSubjectPublicKeyInfo();
                        private_key = Ecc.ExportECPrivateKey();
                        fspub.Write(PublicKey, 0, PublicKey.Length);
                        fsprv.Write(PrivateKey, 0, PrivateKey.Length);
                    }
            }
        }
        public void ExportSubjectPublicKeyInfo(AsnFormat format)
        {
            using ECDsa ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256);
            byte[] exported = ecdsa.ExportSubjectPublicKeyInfo(format);

            if (format == AsnFormat.Der)
            {
                SubjectPublicKeyInfo info = SubjectPublicKeyInfo.GetInstance(Asn1Object.FromByteArray(exported));
                Assert.IsNotNull(info);
                Assert.IsNotNull(info.AlgorithmID);
                Assert.IsNotNull(info.PublicKeyData);
            }

            if (format == AsnFormat.Pem)
            {
                using MemoryStream ms = new MemoryStream(exported);
                using TextReader tr   = new StreamReader(ms, Encoding.ASCII);
                PemReader pemReader = new PemReader(tr);
                object    obj       = pemReader.ReadObject();
                Assert.IsNotNull(obj);
            }

            this.CheckFormat(format, exported);
        }
Пример #10
0
 public byte[] GetPublicKey() => _signAlgorithm.ExportSubjectPublicKeyInfo();
Пример #11
0
        /// <summary>
        /// Securely exchanges a secret key
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="ecParams">ECDSA public / private keypair used for signing</param>
        /// <returns>A tuple containing a 256 bit hashed secret key, and the fingerprint of the remote</returns>
        /// <exception cref="CryptographicException"></exception>
        /// <exception cref="InvalidDataException">Thrown when the remote sends invalid data</exception>
        public static async Task <(byte[], ECPoint)> ExchangeKeyAsync(this WsStream stream, ECParameters ecParams)
        {
            if (ecParams.D is null)
            {
                throw new CryptographicException("Private key must be provided");
            }
            ECDsa ecDsa = ECDsa.Create(ecParams);
            // TODO: Harden security (prevent abuse, double check everything)
            // host authentication
            var pubBytes = ecDsa.ExportSubjectPublicKeyInfo();

            // key exchange
            var ecdh       = ECDiffieHellman.Create();
            var kePubBytes = ecdh.ExportSubjectPublicKeyInfo();

            // sign ecdh key to authenticate
            var signed = ecDsa.SignData(kePubBytes, HashAlgorithmName.SHA256);

            var bw = new AsyncBinaryWriter(stream);
            var br = new AsyncBinaryReader(stream);
            //1
            await bw.WriteAsync(pubBytes.Length);

            await bw.WriteAsync(pubBytes);

            //2
            await bw.WriteAsync(signed.Length);

            await bw.WriteAsync(signed);

            //3
            await bw.WriteAsync(kePubBytes.Length);

            await bw.WriteAsync(kePubBytes);

            // read remote public key and verify signature
            //1
            var remotePubKey   = ECDsa.Create();
            var remotePubBytes = await br.ReadBytesAsync(await br.ReadAssertAsync(120));

            remotePubKey.ImportSubjectPublicKeyInfo(remotePubBytes, out _);
            //2
            var remoteSignature = await br.ReadBytesAsync(await br.ReadAssertAsync(96));

            //3
            var remoteKePub = await br.ReadBytesAsync(await br.ReadAssertAsync(158));

            var remoteEcdh = ECDiffieHellman.Create();

            remoteEcdh.ImportSubjectPublicKeyInfo(remoteKePub, out _);

            // verify signed public key exchange key
            if (!remotePubKey.VerifyData(remoteKePub, remoteSignature, HashAlgorithmName.SHA256))
            {
                throw new CryptographicException("Remote public key does not match hash!");
            }
            // derive shared secret
            var sharedSecret = ecdh.DeriveKeyMaterial(remoteEcdh.PublicKey);

            // return the public key (fingerprint) of the remote, and the hashed shared secret
            return(SHA256.HashData(sharedSecret), remotePubKey.ExportParameters(false).Q);
        }