public async Task SavePrivateKeyAsync(string orderUrl, AsymmetricCipherKeyPair privateKey, long expires)
        {
            FileSystemKeysCollectionFormat keysFormat = await GetFileSystemKeyCollectionFormat();

            if (keysFormat.Keys.Count > 64)
            {
                _logger.LogInformation("Too many saved private keys, culling old records");
                IEnumerable <KeyValuePair <string, FileSystemPrivateKeyFormat> > oldRecords =
                    keysFormat.Keys.ToArray().OrderBy(i => i.Value.Expires).Take(32);
                foreach (KeyValuePair <string, FileSystemPrivateKeyFormat> oldRecord in oldRecords)
                {
                    _logger.LogInformation($"Remove private key {oldRecord.Key}");
                    keysFormat.Keys.Remove(oldRecord.Key);
                }
            }

            byte[] serialized = _privateKeyCodec.Encode(new CertPrivateKey
            {
                KeyPair = privateKey
            });
            string serializedStr = Convert.ToBase64String(serialized);

            keysFormat.Keys[orderUrl] = new FileSystemPrivateKeyFormat()
            {
                Expires = expires,
                Val     = serializedStr
            };
            await SaveFileSystemKeyCollectionFormat(keysFormat);
        }
        public async Task <X509Certificate2> GetActiveCertificateAsync(long fromTimeStamp, long toTimeStamp)
        {
            if (toTimeStamp < fromTimeStamp)
            {
                throw new ArgumentOutOfRangeException(
                          $"Invalid time range. FromTimeStamp {fromTimeStamp}, ToTimeStamp {toTimeStamp}");
            }

            FileSystemPrivateKeyFormat     keyFormat       = null;
            FileSystemCertFormat           certFormat      = null;
            FileSystemCertCollectionFormat certsCollection = await GetFileSystemCertCollectionFormat();

            FileSystemKeysCollectionFormat keysCollection = await GetFileSystemKeyCollectionFormat();

            foreach (KeyValuePair <string, FileSystemCertFormat> keyValuePair in certsCollection.Certs)
            {
                string orderUrl = keyValuePair.Key;
                if (keysCollection.Keys.TryGetValue(orderUrl, out FileSystemPrivateKeyFormat currentPrivateKey))
                {
                    FileSystemCertFormat currentCert = keyValuePair.Value;
                    if (currentCert.NotAfter > fromTimeStamp && currentCert.NotBefore <= toTimeStamp)
                    {
                        if (certFormat == null || certFormat.NotAfter < currentCert.NotAfter)
                        {
                            certFormat = currentCert;
                            keyFormat  = currentPrivateKey;
                        }
                    }
                }
            }

            if (certFormat == null)
            {
                return(null);
            }

            byte[]          certBytes   = Convert.FromBase64String(certFormat.Val);
            X509Certificate certificate = _certCodec.Decode(certBytes);

            byte[]         privateKeyBytes = Convert.FromBase64String(keyFormat.Val);
            CertPrivateKey privateKey      = _privateKeyCodec.Decode(privateKeyBytes);

            return(CertHelper.ToX509Certificate2(privateKey, certificate));
        }
        private Task SaveFileSystemKeyCollectionFormat(FileSystemKeysCollectionFormat fileSystemCertCollectionFormat)
        {
            string json = JsonSerializer.Serialize(fileSystemCertCollectionFormat);

            return(_fileSystem.WriteStringAsync("keys.json", json));
        }