예제 #1
0
        /// <summary>
        /// Constructor to be used to factor a new RSA key pair.
        /// <param name="passphrase">Client secret password used to encrypt the
        /// private key.</param>
        /// <param name="overwriteExisting">Flag allowing or denying to replace
        /// an existing PEM file.</param>
        /// </summary>
        public RsaKeyPair(string passphrase, bool overwriteExisting)
        {
            if (!IsConfigured)
            {
                Configure();
            }

            _overwriteExisting = overwriteExisting;

            AsymmetricCipherKeyPair keyPair = FactorKeyPair();

            PrivateKeyInfo pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);

            _privateKey = new EncryptionKey(KeyType.RSAPrivate,
                                            Convert.ToBase64String(pkInfo.GetDerEncoded()).ToSecureString(),
                                            EncryptionParameters.KEY_GENERATION_START);

            SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);

            _publicKey = new EncryptionKey(KeyType.RSAPublic,
                                           Convert.ToBase64String(info.GetDerEncoded()).ToSecureString(),
                                           EncryptionParameters.KEY_GENERATION_START);

            //// Encrypt private key info for later to be stored with the SavePrivateKeyAsPemFile method
            _pwd            = passphrase.ToSecureString();
            _privateKeyInfo = PrivateKeyFactory.CreateKey(pkInfo);

            keyPair = null;
            pkInfo  = null;
            info    = null;
            GC.Collect();
        }
예제 #2
0
        public GenerateKeysCommand()
        {
            Name        = "generate-key";
            Description = "Generate an RSA private and public key for usage as Licence generator";
            this.HelpOption();
            UsePagerForHelpText = false;
            OnExecute(() =>
            {
                var keyGen = new RsaKeyPairGenerator();
                keyGen.Init(new KeyGenerationParameters(new SecureRandom(), 4096));
                var keyPair = keyGen.GenerateKeyPair();

                PrivateKeyInfo pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
                String privateKey     = Convert.ToBase64String(pkInfo.GetDerEncoded());

                var textWriter = new StreamWriter(new FileStream("./keys/private.pem", FileMode.Create));
                var pemWriter  = new PemWriter(textWriter);
                pemWriter.WriteObject(keyPair.Private);
                pemWriter.Writer.Flush();
                textWriter.Close();

                SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);
                String publicKey          = Convert.ToBase64String(info.GetDerEncoded());

                var text2Writer = new StreamWriter(new FileStream("./keys/public.pub", FileMode.Create));
                var pubWriter   = new PemWriter(text2Writer);
                pubWriter.WriteObject(keyPair.Public);
                pubWriter.Writer.Flush();
                text2Writer.Close();

                Console.WriteLine("Public and private key generated successfully.");
                return(1);
            });
        }
예제 #3
0
        public void Generate()
        {
            var keyPair = GenerateKeyPair();

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);

            PrivateKey = privateKeyInfo.GetDerEncoded();

            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);

            PublicKey = publicKeyInfo.GetDerEncoded();
        }
예제 #4
0
        public KriptalKeyPair CreateKeyPair()
        {
            var kpgen = new RsaKeyPairGenerator();

            kpgen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));

            var keyPair = kpgen.GenerateKeyPair();

            PrivateKeyInfo pkInfo     = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
            var            privateKey = Convert.ToBase64String(pkInfo.GetDerEncoded());

            SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);
            var publicKey             = Convert.ToBase64String(info.GetDerEncoded());

            return(new KriptalKeyPair {
                PrivateKey = privateKey, PublicKey = publicKey
            });
        }
예제 #5
0
        public IEcKey GetSec1PrivateKeyAsPkcs8(byte[] sec1KeyContent)
        {
            var keySequence         = (DerSequence)Asn1Object.FromByteArray(sec1KeyContent);
            var privateKeyPrimitive = (DerOctetString)keySequence[1];
            var encodedOid          = (DerTaggedObject)keySequence[2];

            var d = new BigInteger(privateKeyPrimitive.GetOctets());
            DerObjectIdentifier oid = DerObjectIdentifier.GetInstance(encodedOid.GetObject());
            var key = new ECPrivateKeyParameters("EC", d, oid);

            int     keyLength = GetKeyLength(key);
            ECCurve curve     = key.Parameters.Curve;
            string  curveName = curveNameMapper.MapCurveToName(curve);

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(key);

            return(new EcKey(privateKeyInfo.GetDerEncoded(), AsymmetricKeyType.Private, keyLength, curveName));
        }
예제 #6
0
        /// <summary>
        /// Constructor to be used to recover the existing RSA key pair and server
        /// signed certificate found on the local file system.
        /// </summary>
        /// <param name="passphrase">Passphrase for private key.</param>
        public RsaKeyPair(string passphrase)
        {
            if (!IsConfigured)
            {
                Configure();
            }

            if (File.Exists(_clientPrivateKeyPemFile) && File.Exists(_clientCertPemFile))
            {
                byte[] pkData = File.ReadAllBytes(_clientPrivateKeyPemFile);
                _pwd = passphrase.ToSecureString();
                AsymmetricCipherKeyPair keyPair = PemDecodeKeyPair(pkData);
                // Generate key info's
                PrivateKeyInfo       pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
                SubjectPublicKeyInfo info   =
                    SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);

                _privateKey = new EncryptionKey(KeyType.RSAPrivate,
                                                Convert.ToBase64String(pkInfo.GetDerEncoded()).ToSecureString(),
                                                EncryptionParameters.KEY_GENERATION_START);

                _publicKey = new EncryptionKey(KeyType.RSAPublic,
                                               Convert.ToBase64String(info.GetDerEncoded()).ToSecureString(),
                                               EncryptionParameters.KEY_GENERATION_START);

                byte[] certData = File.ReadAllBytes(_clientCertPemFile);
                X509CertificateParser certParser = new X509CertificateParser();
                _certificate = certParser.ReadCertificate(certData);


                pkData   = null;
                certData = null;
                keyPair  = null;
                pkInfo   = null;
                info     = null;
                _pwd     = null;
                GC.Collect();
            }
            else
            {
                throw new Exception("Cannot find the PEM formatted certificate or private key file");
            }
        }
예제 #7
0
        public async Task <RsaKeyPair> CreateKeyPair()
        {
            var kpgen      = new RsaKeyPairGenerator();
            var privateKey = string.Empty;
            var publicKey  = string.Empty;

            kpgen.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
            await Task.Run(() =>
            {
                var keyPair = kpgen.GenerateKeyPair();

                PrivateKeyInfo pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
                privateKey            = Convert.ToBase64String(pkInfo.GetDerEncoded());

                SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);
                publicKey = Convert.ToBase64String(info.GetDerEncoded());
            });

            return(new RsaKeyPair {
                PrivateKey = privateKey, PublicKey = publicKey
            });
        }
예제 #8
0
        public byte[] GetBlob()
        {
            // get private key as byte array, and length of private key as byte array.
            PrivateKeyInfo info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(_keyPair.Private);

            byte[] priv    = info.GetDerEncoded();
            byte[] privLen = BitConverter.GetBytes((Int32)priv.Length);

            // get public key as byte array.
            AsymmetricKeyParameter pubKey = _keyPair.Public;
            SubjectPublicKeyInfo   spki   = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubKey);

            byte[] pub = spki.GetDerEncoded();

            // output byte array uses first 4 bytes for the length of the base64 private key,
            // followed by the base64 private key, then the base64 public key.
            // this is a completely homegrown non-standard format; for testing only.
            byte[] result = new byte[privLen.Length + priv.Length + pub.Length];
            privLen.CopyTo(result, 0);
            priv.CopyTo(result, privLen.Length);
            pub.CopyTo(result, privLen.Length + priv.Length);
            return(result);
        }
예제 #9
0
        public IActionResult Index()
        {
            var id   = _userManager.GetUserId(User);
            var user = _aadeDbIntegration.GetUser(id);

            // first time there is no public/private key pair for encryption
            // so generate now
            // generated keypair using RSA that is unique to this aade user
            // https://cryptobook.nakov.com/asymmetric-key-ciphers/the-rsa-cryptosystem-concepts
            if (string.IsNullOrEmpty(user.PrivateKey))
            {
                var keyGenerator = new RsaKeyPairGenerator();
                var param        = new KeyGenerationParameters(
                    new SecureRandom(),
                    4096);
                keyGenerator.Init(param);
                var keyPair = keyGenerator.GenerateKeyPair();

                // need to save these keys in the db so must serialize into strings
                // https://stackoverflow.com/questions/22008337/generating-keypair-using-bouncy-castle
                PrivateKeyInfo       pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
                SubjectPublicKeyInfo info   = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);

                var aadeprivateKey = Convert.ToBase64String(pkInfo.GetDerEncoded());
                var aadepublicKey  = Convert.ToBase64String(info.GetDerEncoded());

                user.PrivateKey = aadeprivateKey;
                user.PublicKey  = aadepublicKey;
                _aadeDbIntegration.UpdateUser(user);
            }

            var model = new HomeViewModel();
            var m     = _messageDbIntegration.GetMessageForAadeUser(id);

            model.MyMessages = m;
            return(View(model));
        }
예제 #10
0
        /// <summary>
        /// Create random EC private key based on secp256r1
        /// </summary>
        public static string CreatePrivateKey()
        {
            // creating private key
            SecureRandom              secureRandom = new SecureRandom();
            X9ECParameters            ecParams     = SecNamedCurves.GetByName("secp256r1");
            ECDomainParameters        ccdParams    = new ECDomainParameters(ecParams.Curve, ecParams.G, ecParams.N, ecParams.H, ecParams.GetSeed());
            ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(ccdParams, secureRandom);
            ECKeyPairGenerator        generator    = new ECKeyPairGenerator("ECDH");

            generator.Init(keyGenParams);

            // getting public key
            AsymmetricCipherKeyPair keyPair    = generator.GenerateKeyPair();
            ECPrivateKeyParameters  privParams = keyPair.Private as ECPrivateKeyParameters;
            PrivateKeyInfo          privInfo   = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privParams);
            ECPoint q = privParams.Parameters.G.Multiply(privParams.D);
            ECPublicKeyParameters pubParams = new ECPublicKeyParameters(privParams.AlgorithmName, q, privParams.Parameters);
            SubjectPublicKeyInfo  pubInfo   = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pubParams);

            // ugly hack
            byte[] der        = privInfo.GetDerEncoded();
            byte[] privateKey = der.Skip(der.Length - 32).ToArray();
            der = pubInfo.GetDerEncoded();
            byte[] publicKey = der.Skip(der.Length - 65).ToArray();

            // repack DER
            DerSequence seq = new DerSequence(
                new DerInteger(1),
                new DerOctetString(privateKey),
                new DerTaggedObject(0, new DerObjectIdentifier("1.2.840.10045.3.1.7")),
                new DerTaggedObject(1, new DerBitString(publicKey))
                );

            der = seq.GetDerEncoded();
            return(Hex.ToHexString(der));
        }
예제 #11
0
        public void TestCertMangling()
        {
            string certString = @"MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
3yILeYQzllt/g0rKVRk=";

            X509Certificate2 c = new X509Certificate2();

            c.Import(Convert.FromBase64String(certString));
            Assert.AreEqual("[email protected], CN=www.google.com, O=\"Google, Inc\", L=Mountain View, S=California, C=US", c.Issuer);
            //Assert.AreEqual("CN=Microsoft Corporate Root CA, O=Microsoft Corporation", c.Subject);
            Assert.AreEqual("X509", c.GetFormat());
            Assert.AreEqual("1.2.840.10045.2.1", c.GetKeyAlgorithm());
            Assert.AreEqual("06052B81040022", c.GetKeyAlgorithmParametersString());
            Assert.AreEqual("ECC", c.PublicKey.Oid.FriendlyName);
            ECDiffieHellmanPublicKey certKey = CryptoUtils.ImportEccPublicKeyFromCertificate(c);
            //Console.WriteLine(certKey.ToXmlString());

            // https://blogs.msdn.microsoft.com/shawnfa/2007/01/22/elliptic-curve-diffie-hellman/
            // http://stackoverflow.com/questions/11266711/using-cngkey-to-generate-rsa-key-pair-in-pem-dkim-compatible-using-c-simi
            {
                string input = "eyJhbGciOiJFUzM4NCIsIng1dSI6Ik1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFN25uWnBDZnhtQ3JTd0RkQnY3ZUJYWE10S2hyb3hPcmlFcjNobU1PSkF1dy9acFFYajFLNUdHdEhTNENwRk50dGQxSllBS1lvSnhZZ2F5a3BpZTBFeUF2M3FpSzZ1dElIMnFuT0F0M1ZOclFZWGZJWkpTL1ZSZTNJbDhQZ3U5Q0IifQo.eyJleHAiOjE0NjQ5ODM4NDUsImV4dHJhRGF0YSI6eyJkaXNwbGF5TmFtZSI6Imd1cnVueCIsImlkZW50aXR5IjoiYWY2ZjdjNWUtZmNlYS0zZTQzLWJmM2EtZTAwNWU0MDBlNTc4In0sImlkZW50aXR5UHVibGljS2V5IjoiTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUU3bm5acENmeG1DclN3RGRCdjdlQlhYTXRLaHJveE9yaUVyM2htTU9KQXV3L1pwUVhqMUs1R0d0SFM0Q3BGTnR0ZDFKWUFLWW9KeFlnYXlrcGllMEV5QXYzcWlLNnV0SUgycW5PQXQzVk5yUVlYZklaSlMvVlJlM0lsOFBndTlDQiIsIm5iZiI6MTQ2NDk4Mzg0NH0K.4OrvYYbX09iwOkz-7_N_5yEejuATcUogEbe69fB-kr7r6sH_qSu6bxp9L64SEgABb0rU7tyYCLVnaCSQjd9Dvb34WI9EducgOPJ92qHspcpXr7j716LDfhZE31ksMtWQ";

                ECDiffieHellmanPublicKey rootKey = CryptoUtils.CreateEcDiffieHellmanPublicKey("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V");

                Console.WriteLine($"Root Public Key:\n{rootKey.ToXmlString()}");
                CngKey key = CngKey.Import(rootKey.ToByteArray(), CngKeyBlobFormat.EccPublicBlob);

                Console.WriteLine("Key family: " + key.AlgorithmGroup);
                //   "identityPublicKey": "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7nnZpCfxmCrSwDdBv7eBXXMtKhroxOriEr3hmMOJAuw/ZpQXj1K5GGtHS4CpFNttd1JYAKYoJxYgaykpie0EyAv3qiK6utIH2qnOAt3VNrQYXfIZJS/VRe3Il8Pgu9CB",

                var    newKey  = CryptoUtils.ImportECDsaCngKeyFromString("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7nnZpCfxmCrSwDdBv7eBXXMtKhroxOriEr3hmMOJAuw/ZpQXj1K5GGtHS4CpFNttd1JYAKYoJxYgaykpie0EyAv3qiK6utIH2qnOAt3VNrQYXfIZJS/VRe3Il8Pgu9CB");
                string decoded = JWT.Decode(input, newKey);
                //Assert.AreEqual("", decoded);


                //ECDsaCng t = new ECDsaCng();
                //t.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP384;
                //t.KeySize = 384;
                //byte[] test = t.Key.Export(CngKeyBlobFormat.EccPublicBlob);
                //Assert.AreEqual(test, newKey);

                //string decoded = JWT.Decode(input, t.Key);
            }

            // Private key (in reality this is not necessary since we will generate it)
            AsymmetricKeyParameter privKey     = PrivateKeyFactory.CreateKey(Base64Url.Decode("MB8CAQAwEAYHKoZIzj0CAQYFK4EEACIECDAGAgEBBAEB"));
            PrivateKeyInfo         privKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privKey);

            byte[] derKey     = privKeyInfo.GetDerEncoded();
            CngKey privCngKey = CngKey.Import(derKey, CngKeyBlobFormat.Pkcs8PrivateBlob);


            Console.WriteLine(privKeyInfo.PrivateKeyAlgorithm.Algorithm);
            Console.WriteLine(privCngKey.Algorithm.Algorithm);

            // Public key
            ECDiffieHellmanPublicKey clientKey = CryptoUtils.CreateEcDiffieHellmanPublicKey("MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEDEKneqEvcqUqqFMM1HM1A4zWjJC+I8Y+aKzG5dl+6wNOHHQ4NmG2PEXRJYhujyodFH+wO0dEr4GM1WoaWog8xsYQ6mQJAC0eVpBM96spUB1eMN56+BwlJ4H3Qx4TAvAs");

            // EC key to generate shared secret

            ECDiffieHellmanCng ecKey = new ECDiffieHellmanCng(privCngKey);

            ecKey.HashAlgorithm         = CngAlgorithm.Sha256;
            ecKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            ecKey.SecretPrepend         = new byte[128];     // Server token
            //ecKey.SecretPrepend = new byte[0]; // Server token

            Console.WriteLine(ecKey.HashAlgorithm);
            Console.WriteLine(ecKey.KeyExchangeAlgorithm);

            byte[] secret = ecKey.DeriveKeyMaterial(clientKey);

            Console.WriteLine(Package.HexDump(secret));
            Console.WriteLine(Package.HexDump(Base64Url.Decode("ZOBpyzki/M8UZv5tiBih048eYOBVPkQE3r5Fl0gmUP4=")));
            Console.WriteLine(Package.HexDump(Base64Url.Decode("DEKneqEvcqUqqFMM1HM1A4zWjJC+I8Y+aKzG5dl+6wNOHHQ4NmG2PEXRJYhujyod")));

            //Console.WriteLine(Package.HexDump(Base64Url.Decode("DEKneqEvcqUqqFMM1HM1A4zWjJC+I8Y+aKzG5dl+6wNOHHQ4NmG2PEXRJYhujyod")));
        }
예제 #12
0
        public FirstTimeSetup()
        {
            InitializeComponent();

            //create the password entry view
            PasswordEntryView pep = new PasswordEntryView();

            pep.OnSave += new EventHandler((o, e) =>
            {
                //get the public key ASN1
                SubjectPublicKeyInfo pubki = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(m_keypair.Public);
                //get the private key ASN1
                PrivateKeyInfo privki = PrivateKeyInfoFactory.CreatePrivateKeyInfo(m_keypair.Private);

                //encrypt the private key
                byte[] encPrivKey = Crypto.EncryptKey(privki.GetDerEncoded(), pep.Text);
                m_keypair         = null;

                //delete the old notebooks
                if (Directory.Exists(NoteManager.GetNotebookDir()))
                {
                    Directory.Delete(NoteManager.GetNotebookDir(), true);
                }

                //save the keys to file
                KeyManager.SaveKeys(encPrivKey, pubki.GetDerEncoded());

                //erase the data
                Eraser.SecureErase(encPrivKey);

                //ask if the user wants to use a fingerprint
                IFingerprint fp = FingerprintFactory.GetInstance();
                fp.InitReader();
                if (fp.IsReady())
                {
                    Application.Current.MainPage = new FingerprintPage(new EventHandler((oo, ee) =>
                    {
                        byte[] data = (byte[])oo; //page returns the encrypted password
                        if (data != null)
                        {                         //only if was not skipped
                            //encrypt the password and save it
                            ConfigFactory.GetInstance().EncryptedPassword = data;
                            ConfigFactory.GetInstance().UseFingerprint    = true;
                        }
                        else
                        {
                            ConfigFactory.GetInstance().EncryptedPassword = new byte[] { 0 };
                            ConfigFactory.GetInstance().UseFingerprint    = false;
                        }
                        //trigger the setup complete event
                        if (OnSetupComplete != null)
                        {
                            OnSetupComplete(this, new EventArgs());
                        }
                    }), fp, pep.Text);
                }
                else
                {
                    //trigger the setup complete event
                    if (OnSetupComplete != null)
                    {
                        OnSetupComplete(this, new EventArgs());
                    }
                }
            });

            //create the activity indicator layout
            StackLayout actLayout = new StackLayout()
            {
                VerticalOptions = LayoutOptions.CenterAndExpand
            };
            ActivityIndicator actInd = new ActivityIndicator();;

            actLayout.Children.Add(actInd);
            actLayout.Children.Add(new Label()
            {
                Text = "Generating key pair", TextColor = Color.DarkGray, HorizontalTextAlignment = TextAlignment.Center
            });

            TapRandomizer tapRnd = new TapRandomizer();

            tapRnd.OnRandomized += new EventHandler((o, e) =>
            {
                m_seed = tapRnd.Seed;
                //show wait animation
                actInd.IsRunning = true;
                this.Content     = actLayout;
                //generate the key pair
                Crypto.StartGenerateKeypair(m_seed, new Crypto.GenCompleteEventHandler((keypair) =>
                {
                    m_keypair = keypair;
                    //hide wait animation
                    actInd.IsRunning = false;
                    //show the password entry page
                    this.Content = pep;
                }));
            });

            this.Content = tapRnd;
        }