OpenSSL and ASP.NET WebAPI

25

I'm developing an internal application, but in a certain module I'll need to traffic some sensitive data.

A priori I thought about using SSL, but due to limitations ( non-technical ) I would not be able to do so, so I thought about using OpenSSL.

I even managed to make use of the implementation below, but I do not know if it is implemented correctly, so I would like someone to review it.

Model

public class SecurityModel
{
    public string Token { get; set; }
    public string PublicKey { get; set; }
}

public class EncryptedModel
{
    public string Token { get; set; }
    public string Encrypted { get; set; }
}

Controller

[HttpGet]
public async Task<SecurityModel> GeneratePublicKey()
{
    var model = new SecurityModel();
    using (var generator = new RSACryptoServiceProvider(1024))
    {
        try
        {
            var token = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
            var keys = generator.ExportParameters(true);
            var pemString = generator.GetPublicKeyAsPemString();

            MemoryCache.Default.Add(token, keys, new CacheItemPolicy
            {
                AbsoluteExpiration = ObjectCache.InfiniteAbsoluteExpiration,
                SlidingExpiration = TimeSpan.FromMinutes(30),
                Priority = CacheItemPriority.NotRemovable
            });

            model.Token = token;
            model.PublicKey = pemString;
        }
        finally
        {
            generator.PersistKeyInCsp = false;
        }
    }
    return model;
}

[HttpPost]
public async Task<bool> ReadSensitiveData(EncryptedModel model)
{
    using (var generator = new RSACryptoServiceProvider(1024))
    {
        try
        {
            var keys = (RSAParameters)MemoryCache.Default.Get(model.Token);
            generator.ImportParameters(keys);

            var binary = Convert.FromBase64String(model.Encrypted);
            var decrypted = generator.Decrypt(binary, false);
            var sensitive = Encoding.UTF8.GetString(decrypted);

            return sensitive == "Sensitive Data";
        }
        finally
        {
            generator.PersistKeyInCsp = false;
        }
    }
    return false;
}

The RSAUtils.GetPublicKeyAsPemString(this RSACryptoServiceProvider csp) extension basically returns the public key in the format expected in JavaScript. Something similar to:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN
FOb9I5XRb6khyfD1Yt3YiCgQWMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76
xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4
gwQco1KRMDSmXSMkDwIDAQAB
-----END PUBLIC KEY-----

Now follow my scripts:

Deviations

A Javascript library to perform OpenSSL RSA Encryption, Decryption, and Key Generation

Scripts

var encrypt = new JSEncrypt();
var token = "";
var generatePublicKey = function () {
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('GET', '/api/Security/', true);
    httpRequest.responseType = "json";
    httpRequest.addEventListener("readystatechange", function (event) {
        if (httpRequest.readyState == 4) {
            token = httpRequest.response.Token;
            encrypt.setPublicKey(httpRequest.response.PublicKey);
            sendSensitiveData();
        }
    });
    httpRequest.send();
}

var sendSensitiveData = function () {
    var sensitive = "Sensitive Data";
    var encrypted = encrypt.encrypt(sensitive);

    var httpRequest = new XMLHttpRequest();
    httpRequest.open('POST', '/api/Security/', true);
    httpRequest.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
    httpRequest.addEventListener("readystatechange", function (event) {
        if (httpRequest.readyState == 4) {
            console.log(httpRequest);
        }
    });
    httpRequest.send(JSON.stringify({ Token: token, Encrypted: encrypted }));
}

generatePublicKey();
    
asked by anonymous 31.05.2016 / 13:56

1 answer

2

Dude, the solution is not 100% secure, but you already have some protections, the ideal is to convince the use of SSL. (valid certificates can be obtained at very affordable prices).

But on your case, in a sniffer attack I believe it is protected, but the attack is more elaborate, do not ... Take a test, enable Fiddler to decrypt SSL, but without installing the certificate. Like, go to step three of the link below: link

When accessing any https site, modern browsers will open a page warning you that something is wrong with the certificate, I believe that this will not happen on your site (if you pass the test, what happened), data may be encrypted in the Fiddler, but if there was no alert, it means that any program could be in place of the Fiddler alternating the sending and receiving data, bridging the client and the server, and thus obtaining the data encrypted. It is true that it is a more complex attack, but it will be exposed, depending on the criticality of the data, I would not risk it.

    
21.12.2016 / 17:14