Beispiel #1
0
        public void CanECDH()
        {
            var tests = new[]
            {
                new
                {
                    Pubkey         = "04a5cf05bfe42daffaff4f1732f5868ed7c7919cba279fa7d940e6b02a8b059bde56be218077bcab1ad6b5f5dcb04c42534477fb8d21b6312b0063e08a8ae52b3e",
                    Private        = "7bd0db101160c888e9643f10594185a36a8db91b5308aaa7aad4c03245c6bdc1",
                    ExpectedSecret = "a461392f592ff4292bfce732d808a07f1bc3f49c9a66a40d50761ffb8b2325f6"
                },
                new
                {
                    Pubkey         = "043f12235bcf2776c8489ed138d4c9b85a1e29f3f4ad2787b9c8588e960867afc9de1e5702caa787665f5d0a4b04015c8bd5f1541e3d170efc3668f6ac587d43bc",
                    Private        = "1249b289c5959c71ae60e0a2a7d57dffbd5cb862aaf10442db205f6787791732",
                    ExpectedSecret = "1d664ba11d3925cfcd938b2ef131213ba4ca986822944d0a7616b34027738e7c"
                },
                new
                {
                    Pubkey         = "04769c29328998917d9f2f7c6ce46f2f12a6064e937dff722b4811e9c88b4e1d45387fea132321541e8dbdc92384aef1944d650aa889bfa836db078897e5299262",
                    Private        = "41d0cbeeb3365b8c9e190f9898689997002f94006ad3bf1dcfbac28b6e4fb84d",
                    ExpectedSecret = "7fcfa754a40ceaabee5cd3df1a99ee2e5d2c027fdcbd8e437d9be757ea58708f"
                }
            };

            foreach (var test in tests)
            {
                var pubKey = new PubKey(test.Pubkey);
                var key    = new Key(Encoders.Hex.DecodeData(test.Private));
                var secret = pubKey.GetSharedPubkey(key);
                Assert.Equal(test.ExpectedSecret, Encoders.Hex.EncodeData(Hashes.SHA256(secret.ToBytes())));
            }
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static byte[] EncryptBytesWithPublicKey(byte[] message, PubKey key)
        {
            if (message is null)
            {
                throw new ArgumentNullException(nameof(message));
            }
            var ephemeral     = new Key();
            var sharedKey     = NBitcoin.Crypto.Hashes.SHA512(key.GetSharedPubkey(ephemeral).ToBytes());
            var iv            = sharedKey.SafeSubarray(0, 16);
            var encryptionKey = sharedKey.SafeSubarray(16, 16);
            var hashingKey    = sharedKey.SafeSubarray(32);

            //var aes = new AesBuilder().SetKey(encryptionKey).SetIv(iv).IsUsedForEncryption(true).Build();
            //var cipherText = aes.Process(message, 0, message.Length);
            var cipherText           = SymetricProvider.EncryptBytes(encryptionKey, message, iv);
            var ephemeralPubkeyBytes = ephemeral.PubKey.ToBytes();
            var encrypted            = Encoders.ASCII.DecodeData("BIE1").Concat(ephemeralPubkeyBytes, cipherText);
            var hashMAC = HMACSHA256(hashingKey, encrypted);

            return(encrypted.Concat(hashMAC));
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="encrypted"></param>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentException"></exception>
        public static byte[] DecryptBytesWithPrivateKey(byte[] encrypted, Key privateKey)
        {
            if (encrypted is null)
            {
                throw new ArgumentNullException(nameof(encrypted));
            }
            if (encrypted.Length < 85)
            {
                throw new ArgumentException("Encrypted text is invalid, it should be length >= 85.");
            }

            var magic = encrypted.SafeSubarray(0, 4);
            var ephemeralPubkeyBytes = encrypted.SafeSubarray(4, 33);
            var cipherText           = encrypted.SafeSubarray(37, encrypted.Length - 32 - 37);
            var mac = encrypted.SafeSubarray(encrypted.Length - 32);

            if (!Utils.ArrayEqual(magic, Encoders.ASCII.DecodeData("BIE1")))
            {
                throw new ArgumentException("Encrypted text is invalid, Invalid magic number.");
            }

            var ephemeralPubkey = new PubKey(ephemeralPubkeyBytes);

            var sharedKey     = NBitcoin.Crypto.Hashes.SHA512(ephemeralPubkey.GetSharedPubkey(privateKey).ToBytes());
            var iv            = sharedKey.SafeSubarray(0, 16);
            var encryptionKey = sharedKey.SafeSubarray(16, 16);
            var hashingKey    = sharedKey.SafeSubarray(32);

            var hashMAC = HMACSHA256(hashingKey, encrypted.SafeSubarray(0, encrypted.Length - 32));

            if (!Utils.ArrayEqual(mac, hashMAC))
            {
                throw new ArgumentException("Encrypted text is invalid, Invalid mac.");
            }

            var message = SymetricProvider.DecryptBytes(encryptionKey, cipherText, iv);

            return(message);
        }