Example #1
0
        public void VerifyRandomness()
        {
            CryptoApiRandomGenerator instance = new CryptoApiRandomGenerator(true);

            Byte[] randomBytes = new Byte[32];

            Stopwatch stopwatch  = Stopwatch.StartNew();
            Int32     iterations = 2000;

            for (Int32 index = 0; index < iterations; index++)
            {
                instance.NextBytes(randomBytes);
                String output         = BitConverter.ToString(randomBytes);
                String outputAsBase64 = Convert.ToBase64String(randomBytes);

                Debug.WriteLine(output + " - " + outputAsBase64);

                //System.IO.File.AppendAllText(@"C:\Data\out.txt", output + " - " + outputAsBase64 + Environment.NewLine);

                if (index % (iterations / 10) == 0)
                {
                    Debug.WriteLine($"{index}/{iterations}");
                }
            }

            stopwatch.Stop();

            Double perSecond   = (Double)iterations / (Double)stopwatch.Elapsed.TotalSeconds;
            Double averageTime = (Double)stopwatch.Elapsed.TotalSeconds / (Double)iterations;

            Debug.WriteLine($"Elapsed: {stopwatch.Elapsed.ToString()} for {iterations.ToString()} iterations. ({perSecond:N1} iterations/second | Avg Time: {averageTime:N4})");

            Debugger.Break();
        }
        /// <summary>
        /// Make a new Alias Cert.  If refresh=false, a new DevID and Alias are created.  If refresh=true
        /// then just the Alias is created and re-certified using the stored DevID key.
        /// </summary>
        /// <param name="refresh"></param>
        /// <returns></returns>
        internal DeviceBundle MakeAliasCert(bool refresh, int fwidSeed)
        {
            DateTime now = DateTime.Now;

            byte[] fwid = Helpers.HashData(new byte[1] {
                (byte)fwidSeed
            }, 0, 1);

            const int keyStrength           = 256;
            CryptoApiRandomGenerator rg     = new CryptoApiRandomGenerator();
            SecureRandom             random = new SecureRandom(rg);
            KeyGenerationParameters  keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
            var keyPairGenerator = new ECKeyPairGenerator();

            keyPairGenerator.Init(keyGenerationParameters);

            AsymmetricCipherKeyPair devIdKey = null;

            if (refresh)
            {
                devIdKey = (AsymmetricCipherKeyPair)Helpers.ReadPemObject(ToPath(Program.DeviceIDPrivate));
            }
            else
            {
                devIdKey = keyPairGenerator.GenerateKeyPair();
            }

            // test - remove
            var oids = new List <Object>()
            {
                X509Name.UnstructuredName
            };
            var values = new List <Object>()
            {
                "ljkljljklkjlkjlkjlkjlkjlkjlkjlkjlkjljklkjlkjlkjlkjljk"
            };
            X509Name name = new X509Name(oids, values);



            AsymmetricCipherKeyPair aliasKey = keyPairGenerator.GenerateKeyPair();

            // make a string name based on DevID public.  Note that the authoritative information
            // is encoded in the RIoT-extension: this is just for quick-and-dirty device identification.
            var pubInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(devIdKey.Public);

            byte[] pubEncoded      = pubInfo.GetDerEncoded();
            var    pubHashed       = Helpers.HashData(pubEncoded, 0, pubEncoded.Length);
            var    shortNameBytes  = Helpers.CopyArray(pubHashed, 0, 8);
            var    shortNameString = Helpers.Hexify(shortNameBytes);

            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
            var serialNumber = new byte[8];

            rg.NextBytes(serialNumber);
            serialNumber[0] &= 0x7F;
            certGen.SetSerialNumber(new BigInteger(serialNumber));
            // The important name-related stuff is encoded in the RIoT extension
            certGen.SetIssuerDN(new X509Name($"CN=[I]DevID:{shortNameString}, O=MSR_TEST, C=US"));
            // test REMOVE
            //certGen.SetSubjectDN(name);
            certGen.SetSubjectDN(new X509Name($"CN=[S]DevID:{shortNameString}, O=MSR_TEST, C=US"));
            certGen.SetNotBefore(now);
            certGen.SetNotAfter(now + new TimeSpan(365 * 10, 0, 0, 0, 0));
            certGen.SetPublicKey(aliasKey.Public);

            // Add the extensions (todo: not sure about KeyUsage.DigitalSiganture
            certGen.AddExtension(X509Extensions.ExtendedKeyUsage, true,
                                 ExtendedKeyUsage.GetInstance(new DerSequence(KeyPurposeID.IdKPClientAuth)));
            certGen.AddExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.DigitalSignature));
            AddRIoTExtension(certGen, fwid, devIdKey);

            // sign it
            ISignatureFactory signatureFactory = new Asn1SignatureFactory("SHA256WITHECDSA", devIdKey.Private, random);
            var certificate = certGen.Generate(signatureFactory);
            // and return the bundle
            DeviceBundle bundle = new DeviceBundle
            {
                AliasCert      = certificate,
                DeviceIDPublic = devIdKey.Public,
                AliasKeyPair   = aliasKey
            };

            // Just the AliasCert
            Helpers.WritePEMObject(ToPath(Program.AliasCert), bundle.AliasCert);
            // The Alias Key Pair
            Helpers.WritePEMObject(ToPath(Program.AliasKey), bundle.AliasKeyPair);
            // The encoded DevID
            Helpers.WritePEMObject(ToPath(Program.DeviceIDPublic), bundle.DeviceIDPublic);
            // DeviceIDPrivate (just for the update demo)
            Helpers.WritePEMObject(ToPath(Program.DeviceIDPrivate), devIdKey.Private);

            return(bundle);
        }