Cache X509Certificate2 in memory securely

I am using .Net Core 3.1 and am in the process of migrating to .Net 5.

I need to access X509Certificate2 from multiple locations, such as Windows Certificate Store.
However, once I retrieve them, I would like to cache them in memory securely so that I don’t have to retrieve them multiple times.

Once I retrieve them, I perform GetRSAPublicKey() and GetRSAPrivateKey() on the certificate.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

As far as I know, if you want to read the certificate into memory cache ,you could create a service which contains the GetRSAPublicKey() and GetRSAPrivateKey() method.

In each method, it will try to get the certificate from the memory cache, if memory cache exists, it will read from memory.

In my opinion, store the information into the server memory is security enough.

More details, you could refer to below codes:

IGetCertificate interface:

public interface IGetCertificate
{
    public string GetRSAPublicKey();

    public string GetRSAPrivateKey();


}

GetCertificate :

public class GetCertificate : IGetCertificate
{

    private IMemoryCache _cache;


    public GetCertificate(IMemoryCache memoryCache) {
        _cache = memoryCache;
    }
    public string GetRSAPrivateKey()
    {
        string result;
        if (!_cache.TryGetValue("TestKey", out result))
        {
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection cers = store.Certificates.Find(X509FindType.FindBySubjectName, "localhost", false);
            if (cers.Count > 0)
            {
                var cer = cers[0];
                string re = cer.PrivateKey.ToXmlString(false);
                _cache.Set("TestKey", re);
                return re;
            }
            else {
                return "Couldn't find the certificate";
            };
        }
        else {
            return result;
        }



    }

    public string GetRSAPublicKey()
    {
        string result;
        if (!_cache.TryGetValue("TestPubkcKeyOID", out result))
        {
            X509Store store = new X509Store(StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            X509Certificate2Collection cers = store.Certificates.Find(X509FindType.FindBySubjectName, "localhost", false);
            if (cers.Count > 0)
            {
                var cer = cers[0];
                string re = cer.PublicKey.Oid.Value;
                _cache.Set("TestPubkcKeyOID", re);
                return re;
            }
            else
            {
                return "Couldn't find the certificate";
            };
        }
        else
        {
            return result;
        }

    }
}

Register the service:

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddControllers();
        services.AddMemoryCache();
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "Dotnet5WebAPIApplication", Version = "v1" });
        });

        services.AddScoped(typeof(IGetCertificate),typeof(GetCertificate));
    }

Usage:

    public WeatherForecastController(ILogger<WeatherForecastController> logger, IGetCertificate getCertificate)
    {
        _logger = logger;
        _getCertificate = getCertificate;
    }

     [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
       var re =  _getCertificate.GetRSAPrivateKey();
        var re2 = _getCertificate.GetRSAPublicKey();
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x