Ejemplo n.º 1
0
        private void button4_Click(object sender, EventArgs e)
        {
            if (loadedPartnerKey && loadedKeychain)
            {
                OpenFileDialog theDialog = new OpenFileDialog();
                theDialog.Title  = "Open file to decrypt";
                theDialog.Filter = "CurveBox encrypted file |*.curvebox";
                if (theDialog.ShowDialog() == DialogResult.OK)
                {
                    string filename = theDialog.FileName;

                    dataPath   = filename;
                    loadedFile = true;
                }

                if (!loadedFile)
                {
                    MessageBox.Show("No file loaded!");
                    return;
                }

                byte[] sharedKey = Curve25519.GetSharedSecret(loadedPrivateKey, loadedPartnerPublicKey);
                byte[] hashedKey = sha256(System.Text.Encoding.UTF8.GetString(sharedKey));
                AES_Decrypt(dataPath, Encoding.UTF8.GetString(sharedKey));
                MessageBox.Show(String.Format("Wrote decrypted data to {0}", dataPath + ".decrypted"));
            }
            else
            {
                MessageBox.Show("Please load your keychain and your partners public key");
                return;
            }
        }
Ejemplo n.º 2
0
        public byte[] CalculateAndHashSharedSecret(byte[] privateKey, byte[] publicKey)
        {
            Guard.NotNull(privateKey, publicKey);
            var sharedSecret     = Curve25519.GetSharedSecret(privateKey, publicKey);
            var sharedSecretHash = this._platform.ComputeSHA256(sharedSecret);

            return(sharedSecretHash);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 交换密钥
        /// </summary>
        /// <param name="exchange">交换流程(输入值是我方公钥,返回值是对端公钥)</param>
        /// <returns>密钥</returns>
        public byte[] ExchangeSecret(Func <byte[], byte[]> exchange)
        {
            Guard.Requires <ArgumentNullException>(exchange != null);
            var randBytes = new byte[32];

            RandomNumberGenerator.Create().GetBytes(randBytes);
            var privateKey = Curve25519.ClampPrivateKey(randBytes);
            var publicKey  = Curve25519.GetPublicKey(privateKey);

            return(Curve25519.GetSharedSecret(privateKey, exchange.Invoke(publicKey)));
        }
Ejemplo n.º 4
0
        public void DiffieHellmanSuccess()
        {
            Random random = TestHelpers.CreateSemiRandomGenerator(); // not truly random in case we need to reproduce test values

            for (int i = 0; i < 1000; i++)
            {
                byte[] alicePrivate = Curve25519.ClampPrivateKey(TestHelpers.GetRandomBytes(random, 32));
                byte[] alicePublic  = Curve25519.GetPublicKey(alicePrivate);

                byte[] bobPrivate = Curve25519.ClampPrivateKey(TestHelpers.GetRandomBytes(random, 32));
                byte[] bobPublic  = Curve25519.GetPublicKey(bobPrivate);

                byte[] aliceShared = Curve25519.GetSharedSecret(alicePrivate, bobPublic);
                byte[] bobShared   = Curve25519.GetSharedSecret(bobPrivate, alicePublic);

                Assert.AreEqual(aliceShared, bobShared);
            }
        }
Ejemplo n.º 5
0
        public void DiffieHellmanFail()
        {
            Random random = TestHelpers.CreateSemiRandomGenerator();

            for (int i = 0; i < 1000; i++)
            {
                byte[] alicePrivate = Curve25519.ClampPrivateKey(TestHelpers.GetRandomBytes(random, 32));
                byte[] alicePublic  = Curve25519.GetPublicKey(alicePrivate);

                byte[] bobPrivate = Curve25519.ClampPrivateKey(TestHelpers.GetRandomBytes(random, 32));
                byte[] bobPublic  = Curve25519.GetPublicKey(bobPrivate);

                byte[] aliceShared = Curve25519.GetSharedSecret(alicePrivate, bobPublic);

                byte[] alicePublicWithBitToggled = TestHelpers.ToggleBitInKey(alicePublic, random);
                byte[] bobShared = Curve25519.GetSharedSecret(bobPrivate, alicePublicWithBitToggled);

                Assert.AreNotEqual(aliceShared, bobShared);
            }
        }
Ejemplo n.º 6
0
        public void TestMethod1()
        {
            byte[] aliceRandomBytes = new byte[32];

            byte[] privateKeyBytes = new byte[]
            {
                40, 146, 87, 95, 87, 167, 114, 250, 89, 24, 160, 144, 158, 233, 161, 185,
                9, 153, 71, 88, 153, 107, 3, 49, 159, 174, 55, 184, 136, 80, 214, 123
            };

            //RNGCryptoServiceProvider.Create().GetBytes(aliceRandomBytes);
            //var clampPrivateKey = Curve25519.ClampPrivateKey(privateKeyBytes);
            //var publicKey = Curve25519.GetPublicKey(clampPrivateKey);
            //var result = Curve25519.GetSharedSecret(clampPrivateKey, publicKey);
            var priv = new byte[]
            {
                0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d,
                0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45,
                0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a,
                0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
            };
            var pub = new byte[]
            {
                0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4,
                0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37,
                0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d,
                0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f
            };
            var res = new byte[]
            {
                0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1,
                0x72, 0x8e, 0x3b, 0xf4, 0x80, 0x35, 0x0f, 0x25,
                0xe0, 0x7e, 0x21, 0xc9, 0x47, 0xd1, 0x9e, 0x33,
                0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16, 0x17, 0x42
            };

            var sharedSecret = Curve25519.GetSharedSecret(Curve25519.ClampPrivateKey(priv), pub);

            Assert.IsTrue(sharedSecret.SequenceEqual(res));
        }
Ejemplo n.º 7
0
        private void DisplayNewMessage(EncMessage message)
        {
            if (!message.UsedForDHExchange)
            {
                // TODO: Here we will decrypt the message and show it
                using (Aes aes = Aes.Create())
                {
                    this.messagesListBox.Items.Add($"{message.Sender.Username}> " +
                                                   $"{AesEncryption.DecryptStringFromBytes(message.Payload, _clientsPrivateKeys[message.Sender.Username], new byte[16])}");
                }
            }
            else
            {
                if (message.Payload[0] == 0x34 && message.Payload.Length == 1)
                {
                    byte[] rndBytes = new byte[32];
                    RNGCryptoServiceProvider.Create().GetBytes(rndBytes);

                    privateKey = Curve25519.ClampPrivateKey(rndBytes);
                    byte[] publicKey = Curve25519.GetPublicKey(privateKey);

                    var pubKeyMessage = new EncMessage()
                    {
                        Recipient         = message.Sender,
                        Sender            = message.Recipient,
                        UsedForDHExchange = true,
                        Payload           = publicKey
                    };
                    _serverChannel.SendMessage(pubKeyMessage);
                }
                else
                {
                    if (!_clientsPrivateKeys.ContainsKey(message.Sender.Username))
                    {
                        _clientsPrivateKeys[message.Sender.Username] = Curve25519.GetSharedSecret(privateKey, message.Payload);
                    }
                }
            }
        }
Ejemplo n.º 8
0
 public byte[] GetSharedSecret(byte[] peerPublicKey)
 {
     return(Curve25519.GetSharedSecret(m_privateKey, peerPublicKey));
 }
Ejemplo n.º 9
0
 static byte[] curve25519GenerateKeyAgreement(byte[] privateKey, byte[] publicKey)
 {
     return(Curve25519.GetSharedSecret(privateKey, publicKey));
 }
Ejemplo n.º 10
0
 // call this method when the public key has been received from the endpoint.
 public void GenerateSharedSecret(byte[] OtherPublicKey)
 {
     _sharedKey        = Curve25519.GetSharedSecret(_privateKey, OtherPublicKey);
     _allKeysGenerated = true;
 }
Ejemplo n.º 11
0
        public Tuple <string, byte[]> Post(byte[] body, ControllerSession session)
        {
            var parts = TLVParser.Parse(body);

            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1)
            {
                Console.WriteLine("* Pair Verify Step 1/4");
                Console.WriteLine("* Verify Start Request");

                var clientPublicKey = parts.GetType(Constants.PublicKey);

                byte[]       privateKey = new byte[32];
                SecureRandom random     = new SecureRandom();
                random.NextBytes(privateKey);

                var publicKey = Curve25519.GetPublicKey(privateKey);

                var sharedSecret = Curve25519.GetSharedSecret(privateKey, clientPublicKey);

                var serverUsername = Encoding.UTF8.GetBytes(Program.ID);

                byte[] material = publicKey.Concat(serverUsername).Concat(clientPublicKey).ToArray();

                var accessoryLTSK = File.ReadAllBytes("PrivateKey");

                byte[] proof = Ed25519.Sign(material, accessoryLTSK);

                HKDF g         = new HKDF(() => { return(new HMACSHA512()); }, sharedSecret, Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Salt"), Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Info"));
                var  outputKey = g.GetBytes(32);

                TLV encoder = new TLV();
                encoder.AddType(Constants.Identifier, serverUsername);
                encoder.AddType(Constants.Signature, proof);

                byte[] plaintext = TLVParser.Serialise(encoder);

                var nonce = Cnv.FromHex("00000000").Concat(Encoding.UTF8.GetBytes("PV-Msg02")).ToArray();
                var aad   = new byte[0];

                byte[] outputTag = new byte[0];

                var encryptedOutput = Aead.Encrypt(out outputTag, plaintext, outputKey, nonce, aad, Aead.Algorithm.Chacha20_Poly1305);

                byte[] ret = encryptedOutput.Concat(outputTag).ToArray();

                TLV responseTLV = new TLV();
                responseTLV.AddType(Constants.State, 2);
                responseTLV.AddType(Constants.PublicKey, publicKey);
                responseTLV.AddType(Constants.EncryptedData, ret);

                // Store the details on the session.
                //
                session.ClientPublicKey = clientPublicKey;
                session.PrivateKey      = privateKey;
                session.PublicKey       = publicKey;
                session.SharedSecret    = sharedSecret;
                session.HkdfPairEncKey  = outputKey;

                var encSalt   = Encoding.UTF8.GetBytes("Control-Salt");
                var infoRead  = Encoding.UTF8.GetBytes("Control-Read-Encryption-Key");
                var infoWrite = Encoding.UTF8.GetBytes("Control-Write-Encryption-Key");

                g = new HKDF(() => { return(new HMACSHA512()); }, sharedSecret, encSalt, infoRead);
                session.AccessoryToControllerKey = g.GetBytes(32);

                g = new HKDF(() => { return(new HMACSHA512()); }, sharedSecret, encSalt, infoWrite);
                session.ControllerToAccessoryKey = g.GetBytes(32);

                var output = TLVParser.Serialise(responseTLV);

                return(new Tuple <string, byte[]>("application/pairing+tlv8", output));
            }
            else if (state == 3)
            {
                Console.WriteLine("* Pair Verify Step 3/4");
                Console.WriteLine("* Verify Start Request");

                // We're looking good here. Need to set the encryption/settings on this session.
                //
                session.IsVerified          = true;
                session.SkipFirstEncryption = true;

                TLV responseTLV = new TLV();
                responseTLV.AddType(Constants.State, 4);

                var output = TLVParser.Serialise(responseTLV);

                return(new Tuple <string, byte[]>("application/pairing+tlv8", output));
            }

            return(null);
        }
Ejemplo n.º 12
0
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            const string Algorithm               = "ECDH"; //What do you think about the other algorithms?
            const int    KeyBitSize              = 2056;
            const int    NonceBitSize            = 128;
            const int    MacBitSize              = 128;
            const int    DefaultPrimeProbability = 30;

            //BEGIN SETUP ALICE
            IAsymmetricCipherKeyPairGenerator aliceKeyGen    = GeneratorUtilities.GetKeyPairGenerator(Algorithm);
            DHParametersGenerator             aliceGenerator = new DHParametersGenerator();

            aliceGenerator.Init(KeyBitSize, DefaultPrimeProbability, new SecureRandom());
            DHParameters aliceParameters = aliceGenerator.GenerateParameters();

            KeyGenerationParameters aliceKGP = new DHKeyGenerationParameters(new SecureRandom(), aliceParameters);

            aliceKeyGen.Init(aliceKGP);

            AsymmetricCipherKeyPair aliceKeyPair  = aliceKeyGen.GenerateKeyPair();
            IBasicAgreement         aliceKeyAgree = AgreementUtilities.GetBasicAgreement(Algorithm);

            aliceKeyAgree.Init(aliceKeyPair.Private);

            Button   a1b             = FindViewById <Button>(Resource.Id.a1b);
            TextView AliceRandomText = FindViewById <TextView>(Resource.Id.a1t);

            Button   a2b = FindViewById <Button>(Resource.Id.a2b);
            TextView AlicePrivateKeyText = FindViewById <TextView>(Resource.Id.a2t);

            Button   a3b = FindViewById <Button>(Resource.Id.a3b);
            TextView AlicePublicKeyText = FindViewById <TextView>(Resource.Id.a3t);

            Button   b1b           = FindViewById <Button>(Resource.Id.b1b);
            TextView BobRandomText = FindViewById <TextView>(Resource.Id.b1t);

            Button   b2b = FindViewById <Button>(Resource.Id.b2b);
            TextView BobPrivateKeyText = FindViewById <TextView>(Resource.Id.b2t);

            Button   b3b = FindViewById <Button>(Resource.Id.b3b);
            TextView BobPublicKeyText = FindViewById <TextView>(Resource.Id.b3t);

            Button   a4b = FindViewById <Button>(Resource.Id.a4b);
            TextView AliceBobSharedKeyText = FindViewById <TextView>(Resource.Id.a4t);

            Button   b4b = FindViewById <Button>(Resource.Id.b4b);
            TextView BobAliceSharedKeyText = FindViewById <TextView>(Resource.Id.b4t);


            // what Alice does
            byte[] aliceRandomBytes = new byte[32];
            RNGCryptoServiceProvider.Create().GetBytes(aliceRandomBytes);

            byte[] alicePrivate = Curve25519.(aliceRandomBytes);
            byte[] alicePublic  = Curve25519.GetPublicKey(alicePrivate);

            // what Bob does
            byte[] bobRandomBytes = new byte[32];
            RNGCryptoServiceProvider.Create().GetBytes(bobRandomBytes);

            byte[] bobPrivate = Curve25519.ClampPrivateKey(bobRandomBytes);
            byte[] bobPublic  = Curve25519.GetPublicKey(bobPrivate);

            // what Alice does with Bob's public key
            byte[] aliceShared = Curve25519.GetSharedSecret(alicePrivate, bobPublic);

            // what Bob does with Alice' public key
            byte[] bobShared = Curve25519.GetSharedSecret(bobPrivate, alicePublic);

            // aliceShared == bobShared

            a1b.Click += delegate {
                alicePrivateBytes        = null;
                AlicePrivateKeyText.Text = "";

                alicePublicBytes        = null;
                AlicePublicKeyText.Text = "";

                aliceBobSharedBytes = null;
                bobAliceSharedBytes = null;

                AliceBobSharedKeyText.Text = "";
                BobAliceSharedKeyText.Text = "";

                aliceRandomBytes = new byte[32];
                RNGCryptoServiceProvider.Create().GetBytes(aliceRandomBytes);
                AliceRandomText.Text = BitConverter.ToString(aliceRandomBytes).Replace("-", "");
            };

            a2b.Click += delegate {
                if (aliceRandomBytes != null)
                {
                    alicePrivateBytes        = Curve25519.Create(aliceRandomBytes);
                    AlicePrivateKeyText.Text = BitConverter.ToString(alicePrivateBytes).Replace("-", "");
                }
            };

            a3b.Click += delegate {
                if (alicePrivateBytes != null)
                {
                    alicePublicBytes        = Curve25519.GetPublicKey(alicePrivateBytes);
                    AlicePublicKeyText.Text = BitConverter.ToString(alicePublicBytes).Replace("-", "");
                }
            };

            b1b.Click += delegate {
                bobPrivateBytes        = null;
                BobPrivateKeyText.Text = ""; // Reset

                bobPublicBytes        = null;
                BobPublicKeyText.Text = ""; // Reset

                aliceBobSharedBytes = null;
                bobAliceSharedBytes = null;

                AliceBobSharedKeyText.Text = "";
                BobAliceSharedKeyText.Text = "";

                bobRandomBytes = new byte[32];
                RNGCryptoServiceProvider.Create().GetBytes(bobRandomBytes);
                BobRandomText.Text = BitConverter.ToString(bobRandomBytes).Replace("-", "");
            };


            b2b.Click += delegate {
                if (bobRandomBytes != null)
                {
                    bobPrivateBytes        = Curve25519.ClampPrivateKey(bobRandomBytes);
                    BobPrivateKeyText.Text = BitConverter.ToString(bobPrivateBytes).Replace("-", "");
                }
            };

            b3b.Click += delegate {
                if (bobPrivateBytes != null)
                {
                    bobPublicBytes        = Curve25519.GetPublicKey(bobPrivateBytes);
                    BobPublicKeyText.Text = BitConverter.ToString(bobPublicBytes).Replace("-", "");
                }
            };

            a4b.Click += delegate {
                if ((alicePrivateBytes != null) && (bobPublicBytes != null))
                {
                    aliceBobSharedBytes        = Curve25519.GetSharedSecret(alicePrivateBytes, bobPublicBytes);
                    AliceBobSharedKeyText.Text = BitConverter.ToString(aliceBobSharedBytes).Replace("-", "");
                }
            };


            b4b.Click += delegate {
                if ((bobPrivateBytes != null) && (alicePublicBytes != null))
                {
                    bobAliceSharedBytes        = Curve25519.GetSharedSecret(bobPrivateBytes, alicePublicBytes);
                    BobAliceSharedKeyText.Text = BitConverter.ToString(bobAliceSharedBytes).Replace("-", "");
                }
            };
        }
Ejemplo n.º 13
0
        public PairVerifyReturn Post(Tlv parts, HapSession session)
        {
            var state = parts.GetTypeAsInt(Constants.State);

            if (state == 1)
            {
                _logger.LogDebug("* Pair Verify Step 1/4");
                _logger.LogDebug("* Verify Start Request");

                var clientPublicKey = parts.GetType(Constants.PublicKey);

                byte[] privateKey = new byte[32];

                Random random = new Random();
                random.NextBytes(privateKey);

                var publicKey    = Curve25519.GetPublicKey(privateKey);
                var sharedSecret = Curve25519.GetSharedSecret(privateKey, clientPublicKey);

                var serverUsername = Encoding.UTF8.GetBytes(HapControllerServer.HapControllerId);

                var material      = publicKey.Concat(serverUsername).Concat(clientPublicKey).ToArray();
                var accessoryLtsk = StringToByteArray(HapControllerServer.HapControllerLtsk);

                var proof = Chaos.NaCl.Ed25519.Sign(material, accessoryLtsk);

                var hdkf       = new HkdfSha512();
                var hkdfEncKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Salt"),
                                                  Encoding.UTF8.GetBytes("Pair-Verify-Encrypt-Info"), 32);

                var encoder = new Tlv();
                encoder.AddType(Constants.Identifier, serverUsername);
                encoder.AddType(Constants.Signature, proof);
                var plaintext = TlvParser.Serialize(encoder);

                var zeros = new byte[] { 0, 0, 0, 0 };
                var nonce = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg02"));

                var encryptedOutput = AeadAlgorithm.ChaCha20Poly1305.Encrypt(
                    Key.Import(AeadAlgorithm.ChaCha20Poly1305, hkdfEncKey, KeyBlobFormat.RawSymmetricKey), nonce,
                    new byte[0], plaintext);

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 2);
                responseTlv.AddType(Constants.EncryptedData, encryptedOutput);
                responseTlv.AddType(Constants.PublicKey, publicKey);

                // Store the details on the session.
                //
                session.ClientPublicKey = clientPublicKey;
                session.PrivateKey      = privateKey;
                session.PublicKey       = publicKey;
                session.SharedSecret    = sharedSecret;
                session.HkdfPairEncKey  = hkdfEncKey;


                var encSalt   = Encoding.UTF8.GetBytes("Control-Salt");
                var infoRead  = Encoding.UTF8.GetBytes("Control-Read-Encryption-Key");
                var infoWrite = Encoding.UTF8.GetBytes("Control-Write-Encryption-Key");

                session.AccessoryToControllerKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoRead, 32);
                session.ControllerToAccessoryKey = hdkf.DeriveBytes(SharedSecret.Import(sharedSecret), encSalt, infoWrite, 32);

                return(new PairVerifyReturn
                {
                    TlvData = responseTlv,
                    Ok = true,
                    HapSession = session
                });
            }

            if (state == 3)
            {
                _logger.LogDebug("* Pair Verify Step 3/4");
                _logger.LogDebug("* Verify Finish Request");

                var encryptedData = parts.GetType(Constants.EncryptedData);
                var zeros         = new byte[] { 0, 0, 0, 0 };
                var nonce         = new Nonce(zeros, Encoding.UTF8.GetBytes("PV-Msg03"));

                var decrypt = AeadAlgorithm.ChaCha20Poly1305.Decrypt(Key.Import(AeadAlgorithm.ChaCha20Poly1305, session.HkdfPairEncKey, KeyBlobFormat.RawSymmetricKey), nonce, new byte[0], encryptedData, out var output);

                if (!decrypt)
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.State, 4);
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairVerifyReturn
                    {
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var subData        = TlvParser.Parse(output);
                var clientUserName = subData.GetType(Constants.Identifier);
                var signature      = subData.GetType(Constants.Signature);

                var clientPublicKey = StringToByteArray(HapControllerServer.HapControllerLtpk);
                var material        = session.ClientPublicKey.Concat(clientUserName).Concat(session.PublicKey).ToArray();

                session.ClientUsername = Automatica.Core.Driver.Utility.Utils.ByteArrayToString(in clientUserName);

                if (!Chaos.NaCl.Ed25519.Verify(signature, material, clientPublicKey))
                {
                    var errorTlv = new Tlv();
                    errorTlv.AddType(Constants.State, 4);
                    errorTlv.AddType(Constants.Error, ErrorCodes.Authentication);
                    return(new PairVerifyReturn
                    {
                        TlvData = errorTlv,
                        Ok = false
                    });
                }

                var responseTlv = new Tlv();
                responseTlv.AddType(Constants.State, 4);

                session.IsVerified          = true;
                session.SkipFirstEncryption = true;

                return(new PairVerifyReturn
                {
                    Ok = true,
                    TlvData = responseTlv
                });
            }

            return(null);
        }
Ejemplo n.º 14
0
        public static string GenEncrypedPin(string pin, string pinToken, string sessionId, string priKey, ulong it)
        {
            ulong time = (ulong)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            var bPinToken = UrlBase64.Decode(pinToken);
            var bPriToken = UrlBase64.Decode(priKey);

            byte[] bPriToken2 = new byte[32];
            Array.Copy(bPriToken, bPriToken2, 32);

            var bPriToken3 = PrivateKeyToCurve25519(bPriToken2);

            Curve25519 pkey = Curve25519.Create(Curve25519.Curve25519Sha256);

            pkey.FromPrivateKey(bPriToken3);

            byte[] sk = pkey.GetSharedSecret(bPinToken);

            var bPin      = Encoding.ASCII.GetBytes(pin);
            var btime     = BitConverter.GetBytes(time);
            var biterator = BitConverter.GetBytes(it);


            int len = bPin.Length + btime.Length + biterator.Length;

            IBlockCipher cipherAes    = new AesEngine();
            int          bsize        = cipherAes.GetBlockSize();
            KeyParameter keyParameter = new KeyParameter(sk);


            int nPadding = bsize - len % bsize;
            var bPadding = new byte[nPadding];

            len += (len % bsize == 0 ? 0 : nPadding);


            var blocks = new byte[len];

            Array.Copy(bPin, blocks, bPin.Length);
            Array.Copy(btime, 0, blocks, bPin.Length, btime.Length);
            Array.Copy(biterator, 0, blocks, bPin.Length + btime.Length, biterator.Length);
            Array.Copy(bPadding, 0, blocks, bPin.Length + btime.Length + biterator.Length, nPadding);

            var iv = new byte[bsize];

            random.NextBytes(iv);

            CbcBlockCipher   cbcBc            = new CbcBlockCipher(cipherAes);
            ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, iv);

            BufferedBlockCipher bc = new BufferedBlockCipher(cbcBc);

            bc.Init(true, parametersWithIV);
            var bOut = bc.ProcessBytes(blocks);
            var rz   = new byte[bOut.Length + bsize];

            Array.Copy(iv, rz, iv.Length);
            Array.Copy(bOut, 0, rz, iv.Length, bOut.Length);

            return(UrlBase64.Encode(rz));
        }