Пример #1
0
        public void AesGcm1000Rounds()
        {
            IShadowsocksAeadCipher aes = new AEAD_AES_128_GCM("password");

            byte[] raw = new byte[1024];

            for (int i = 0; i < 1000; i++)
            {
                RandomNumberGenerator.Fill(raw);
                var c = aes.EncryptTcp(raw);
                var p = aes.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }

            aes = new AEAD_AES_192_GCM("password2");
            for (int i = 0; i < 1000; i++)
            {
                RandomNumberGenerator.Fill(raw);
                var c = aes.EncryptTcp(raw);
                var p = aes.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }

            aes = new AEAD_AES_256_GCM("password3");
            for (int i = 0; i < 1000; i++)
            {
                RandomNumberGenerator.Fill(raw);
                var c = aes.EncryptTcp(raw);
                var p = aes.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }
        }
Пример #2
0
        public async Task <WeChatPayPlatformCertificate> GetCertificateAsync(IWeChatPayClient client, WeChatPayOptions options)
        {
            // 如果证书序列号已缓存,则直接使用缓存的
            var platformCert = _certDictionary.Values.Where(cert => cert.EffectiveTime <DateTime.Now && cert.ExpireTime> DateTime.Now).FirstOrDefault();

            if (platformCert != null)
            {
                return(platformCert);
            }

            // 否则重新下载新的平台证书
            var request  = new WeChatPayCertificatesRequest();
            var response = await client.ExecuteAsync(request, options);

            foreach (var certificate in response.Certificates)
            {
                // 若证书序列号未被缓存,解密证书并加入缓存
                if (!_certDictionary.ContainsKey(certificate.SerialNo))
                {
                    switch (certificate.EncryptCertificate.Algorithm)
                    {
                    case nameof(AEAD_AES_256_GCM):
                    {
                        var certStr = AEAD_AES_256_GCM.Decrypt(certificate.EncryptCertificate.Nonce, certificate.EncryptCertificate.Ciphertext, certificate.EncryptCertificate.AssociatedData, options.V3Key);

                        var cert = new WeChatPayPlatformCertificate
                        {
                            SerialNo      = certificate.SerialNo,
                            EffectiveTime = DateTime.Parse(certificate.EffectiveTime),
                            ExpireTime    = DateTime.Parse(certificate.ExpireTime),
                            Certificate   = new X509Certificate2(Encoding.ASCII.GetBytes(certStr))
                        };

                        _certDictionary.TryAdd(certificate.SerialNo, cert);
                    }
                    break;

                    default:
                        throw new WeChatPayException($"Unknown algorithm: {certificate.EncryptCertificate.Algorithm}");
                    }
                }
            }

            // 重新从缓存获取
            platformCert = _certDictionary.Values.Where(cert => cert.EffectiveTime <DateTime.Now && cert.ExpireTime> DateTime.Now).FirstOrDefault();
            if (platformCert != null)
            {
                return(platformCert);
            }
            else
            {
                throw new WeChatPayException("Download certificates failed!");
            }
        }
        /// <summary>
        /// Encrypts an input byte array using AES with a 256 bits key in GCM authenticated mode.
        /// </summary>
        /// <param name="text">The input byte array of the string to encrypt.</param>
        /// <param name="key">The encryption key being used.</param>
        /// <returns>The base64 encoded output string encrypted with AES.</returns>
        public static string Encrypt(byte[] text, byte[] key)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var aes = new AEAD_AES_256_GCM();

            return(Convert.ToBase64String(aes.EncryptString(text, key)));
        }
        /// <summary>
        /// Encrypts an input string using AES with a 256 bits key in GCM authenticated mode.
        /// </summary>
        /// <param name="text">The plain string input to encrypt.</param>
        /// <param name="key">The encryption key being used.</param>
        /// <returns>The base64 encoded output string encrypted with AES.</returns>
        public static string Encrypt(string text, string key)
        {
            if (string.IsNullOrEmpty(text))
            {
                throw new ArgumentNullException(nameof(text));
            }

            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            var aes = new AEAD_AES_256_GCM();

            return(Convert.ToBase64String(aes.EncryptString(text, key)));
        }
        /// <summary>
        /// Encrypts an input byte array using AES with a 256 bits key in GCM authenticated mode.
        /// </summary>
        /// <param name="cipher">The byte array of the cipher to decrypt.</param>
        /// <param name="key">The encryption key being used.</param>
        /// <returns>The decrypted output string.</returns>
        public static string Decrypt(byte[] cipher, byte[] key)
        {
            if (cipher == null)
            {
                throw new ArgumentNullException(nameof(cipher));
            }

            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }

            var aes = new AEAD_AES_256_GCM();

            return(Encoding.UTF8.GetString(aes.DecryptString(cipher, key)));
        }
        /// <summary>
        /// Decrypts an input string using AES with a 256 bits key in GCM authenticated mode.
        /// </summary>
        /// <param name="cipher">The base64 encoded input cipher to decrypt.</param>
        /// <param name="key">The encryption key being used.</param>
        /// <returns>The decrypted output string.</returns>
        public static string Decrypt(string cipher, string key)
        {
            if (string.IsNullOrEmpty(cipher))
            {
                throw new ArgumentNullException(nameof(cipher));
            }

            if (string.IsNullOrEmpty(key))
            {
                throw new ArgumentNullException(nameof(key));
            }

            var aes = new AEAD_AES_256_GCM();

            return(Encoding.UTF8.GetString(aes.DecryptString(cipher, key)));
        }
Пример #7
0
        /// <summary>
        /// Loads JSON configuration key/values from a stream into a provider.
        /// </summary>
        /// <param name="stream">The stream to read.</param>
        public override void Load(Stream stream)
        {
            var source = (EncryptedJsonConfigurationSource)Source;

            try
            {
                var encryptedSettings = stream.ToBytes();
                var aes      = new AEAD_AES_256_GCM();
                var settings = aes.DecryptString(encryptedSettings, source.Key);

                Data = EncryptedJsonConfigurationFileParser.Parse(new MemoryStream(settings));
            }
            catch (JsonException e)
            {
                throw new FormatException("Could not parse the encrypted JSON file", e);
            }
        }
Пример #8
0
        /// <summary>
        /// Loads JSON configuration key/values from a stream into a provider.
        /// </summary>
        public override void Load()
        {
            var source = (EncryptedJsonConfigurationSource)Source;

            try
            {
                var text     = Convert.FromBase64String(File.ReadAllText(source.Path));
                var aes      = new AEAD_AES_256_GCM();
                var settings = aes.DecryptString(text, source.Key);

                Data = EncryptedJsonConfigurationFileParser.Parse(new MemoryStream(settings));
            }
            catch (JsonException e)
            {
                throw new FormatException("Could not parse the encrypted JSON file", e);
            }
        }
Пример #9
0
        /// <summary>
        /// 将加密报文解密并反序列化
        /// https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_2.shtml
        /// </summary>
        public T Parse(string body, string v3key)
        {
            T   result            = null;
            var notifyCiphertext  = default(NotifyCiphertext);
            var resourcePlaintext = string.Empty;

            try
            {
                if (body.StartsWith("{") && body.EndsWith("}"))
                {
                    notifyCiphertext = JsonSerializer.Deserialize <NotifyCiphertext>(body, jsonSerializerOptions);
                }
            }
            catch { }

            switch (notifyCiphertext.Resource.Algorithm)
            {
            case nameof(AEAD_AES_256_GCM):
            {
                resourcePlaintext = AEAD_AES_256_GCM.Decrypt(notifyCiphertext.Resource.Nonce, notifyCiphertext.Resource.Ciphertext, notifyCiphertext.Resource.AssociatedData, v3key);
            }
            break;

            default:
                throw new WeChatPayException("Unknown algorithm!");
            }

            try
            {
                result = JsonSerializer.Deserialize <T>(resourcePlaintext, jsonSerializerOptions);
            }
            catch { }

            if (result == null)
            {
                result = Activator.CreateInstance <T>();
            }

            result.Body              = body;
            result.NotifyCiphertext  = notifyCiphertext;
            result.ResourcePlaintext = resourcePlaintext;

            return(result);
        }
Пример #10
0
        private async Task <X509Certificate2> LoadPlatformCertificateAsync(string serial, WeChatPayOptions options)
        {
            // 如果证书序列号已缓存,则直接使用缓存的
            if (_platformCertificateManager.TryGetValue(serial, out var certificate2))
            {
                return(certificate2);
            }

            // 否则重新下载新的平台证书
            var request  = new WeChatPayCertificatesRequest();
            var response = await ExecuteAsync(request, options);

            foreach (var certificate in response.Certificates)
            {
                // 若证书序列号未被缓存,解密证书并加入缓存
                if (!_platformCertificateManager.ContainsKey(certificate.SerialNo))
                {
                    switch (certificate.EncryptCertificate.Algorithm)
                    {
                    case nameof(AEAD_AES_256_GCM):
                    {
                        var certStr = AEAD_AES_256_GCM.Decrypt(certificate.EncryptCertificate.Nonce, certificate.EncryptCertificate.Ciphertext, certificate.EncryptCertificate.AssociatedData, options.V3Key);
                        var cert    = new X509Certificate2(Encoding.UTF8.GetBytes(certStr));
                        _platformCertificateManager.TryAdd(certificate.SerialNo, cert);
                    }
                    break;

                    default:
                        throw new WeChatPayException($"Unknown algorithm: {certificate.EncryptCertificate.Algorithm}");
                    }
                }
            }

            // 重新从缓存获取
            if (_platformCertificateManager.TryGetValue(serial, out certificate2))
            {
                return(certificate2);
            }
            else
            {
                throw new WeChatPayException("Download certificates failed!");
            }
        }
Пример #11
0
        public void AesGcmBasics()
        {
            byte[] raw = new byte[1024];
            RandomNumberGenerator.Fill(raw);
            IShadowsocksAeadCipher aead = new AEAD_AES_128_GCM("password");

            {
                var c = aead.EncryptUdp(raw);
                var p = aead.DecryptUdp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }
            {
                RandomNumberGenerator.Fill(raw);
                var c = aead.EncryptTcp(raw);
                var p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));

                RandomNumberGenerator.Fill(raw);
                c = aead.EncryptTcp(raw);
                p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));

                RandomNumberGenerator.Fill(raw);
                c = aead.EncryptTcp(raw);
                p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }


            aead = new AEAD_AES_192_GCM("password");
            {
                RandomNumberGenerator.Fill(raw);
                var c = aead.EncryptUdp(raw);
                var p = aead.DecryptUdp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }
            {
                RandomNumberGenerator.Fill(raw);
                var c = aead.EncryptTcp(raw);
                var p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));

                RandomNumberGenerator.Fill(raw);
                c = aead.EncryptTcp(raw);
                p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));

                RandomNumberGenerator.Fill(raw);
                c = aead.EncryptTcp(raw);
                p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }

            aead = new AEAD_AES_256_GCM("password");
            {
                RandomNumberGenerator.Fill(raw);
                var c = aead.EncryptUdp(raw);
                var p = aead.DecryptUdp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }
            {
                RandomNumberGenerator.Fill(raw);
                var c = aead.EncryptTcp(raw);
                var p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));

                RandomNumberGenerator.Fill(raw);
                c = aead.EncryptTcp(raw);
                p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));

                RandomNumberGenerator.Fill(raw);
                c = aead.EncryptTcp(raw);
                p = aead.DecryptTcp(c.SignificantMemory);
                Assert.IsTrue(p.SignificantMemory.Span.SequenceEqual(raw.AsSpan()));
            }
        }
Пример #12
0
        private static ExitCode RunCryptOptionsAndReturnExitCode(CryptOptions cryptOptions)
        {
            AesEncryptionResult aesEncryptionResult = null;

            switch (cryptOptions.InputType.ToLower())
            {
            case "string":
            {
                switch (cryptOptions.Algorithm.ToLower())
                {
                case "aes128cbc":
                    aesEncryptionResult = new AE_AES_128_CBC_HMAC_SHA_256().EncryptString(cryptOptions.InputToBeEncrypted, cryptOptions.Password);
                    break;

                case "aes192cbc":
                    aesEncryptionResult = new AE_AES_192_CBC_HMAC_SHA_384().EncryptString(cryptOptions.InputToBeEncrypted, cryptOptions.Password);
                    break;

                case "aes256cbc":
                    aesEncryptionResult = new AE_AES_256_CBC_HMAC_SHA_512().EncryptString(cryptOptions.InputToBeEncrypted, cryptOptions.Password);
                    break;

                case "aes128gcm":
                    aesEncryptionResult = new AEAD_AES_128_GCM().EncryptString(cryptOptions.InputToBeEncrypted, cryptOptions.Password, cryptOptions.AssociatedData);
                    break;

                case "aes192gcm":
                    aesEncryptionResult = new AEAD_AES_192_GCM().EncryptString(cryptOptions.InputToBeEncrypted, cryptOptions.Password, cryptOptions.AssociatedData);
                    break;

                case "aes256gcm":
                    aesEncryptionResult = new AEAD_AES_256_GCM().EncryptString(cryptOptions.InputToBeEncrypted, cryptOptions.Password, cryptOptions.AssociatedData);
                    break;

                default:
                    aesEncryptionResult = new AesEncryptionResult()
                    {
                        Success = false, Message = $"Unknown algorithm \"{cryptOptions.Algorithm}\"."
                    };
                    break;
                }
            }
            break;

            case "file":
            {
                switch (cryptOptions.Algorithm.ToLower())
                {
                case "aes128cbc":
                {
                    using (var progressBar = new ProgressBar())
                    {
                        var aes128 = new AE_AES_128_CBC_HMAC_SHA_256();
                        aes128.OnEncryptionProgress += (percentageDone, message) => { progressBar.Report((double)percentageDone / 100); };
                        aes128.OnEncryptionMessage  += (msg) => { /*Console.WriteLine(msg);*/ progressBar.WriteLine(msg); };

                        aesEncryptionResult = aes128.EncryptFile(cryptOptions.InputToBeEncrypted, cryptOptions.OutputFilePath, cryptOptions.Password, cryptOptions.DeleteSourceFile);
                    }
                }
                break;

                case "aes192cbc":
                {
                    using (var progressBar = new ProgressBar())
                    {
                        var aes192 = new AE_AES_192_CBC_HMAC_SHA_384();
                        aes192.OnEncryptionProgress += (percentageDone, message) => { progressBar.Report((double)percentageDone / 100); };
                        aes192.OnEncryptionMessage  += (msg) => { /*Console.WriteLine(msg);*/ progressBar.WriteLine(msg); };

                        aesEncryptionResult = aes192.EncryptFile(cryptOptions.InputToBeEncrypted, cryptOptions.OutputFilePath, cryptOptions.Password, cryptOptions.DeleteSourceFile);
                    }
                }
                break;

                case "aes256cbc":
                {
                    using (var progressBar = new ProgressBar())
                    {
                        var aes256 = new AE_AES_256_CBC_HMAC_SHA_512();
                        aes256.OnEncryptionProgress += (percentageDone, message) => { progressBar.Report((double)percentageDone / 100); };
                        aes256.OnEncryptionMessage  += (msg) => { /*Console.WriteLine(msg);*/ progressBar.WriteLine(msg); };

                        aesEncryptionResult = aes256.EncryptFile(cryptOptions.InputToBeEncrypted, cryptOptions.OutputFilePath, cryptOptions.Password, cryptOptions.DeleteSourceFile);
                    }
                }
                break;

                case "aes128gcm":
                case "aes192gcm":
                case "aes256gcm":
                    aesEncryptionResult = new AesEncryptionResult()
                    {
                        Success = false, Message = $"Algorithm \"{cryptOptions.Algorithm}\" currently not available for file encryption."
                    };
                    break;

                default:
                    aesEncryptionResult = new AesEncryptionResult()
                    {
                        Success = false, Message = $"Unknown algorithm \"{cryptOptions.Algorithm}\"."
                    };
                    break;
                }
            }
            break;

            default:
                aesEncryptionResult = new AesEncryptionResult()
                {
                    Success = false, Message = $"Unknown input type \"{cryptOptions.InputType}\"."
                };
                break;
            }

            if (aesEncryptionResult.Success)
            {
                Console.WriteLine((cryptOptions.InputType.ToLower().Equals("string") ? aesEncryptionResult.EncryptedDataBase64String : aesEncryptionResult.Message));

                return(ExitCode.Sucess);
            }
            else
            {
                Console.WriteLine(aesEncryptionResult.Message);

                return(ExitCode.Error);
            }
        }