javascript – OpenSSL e ASP.NET WebAPI

Question:

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

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

I even managed to make it work using the implementation below, but I don't 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-----

Agora segue os meus scripts:

Depedências

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();

Answer:

Man, the solution is not 100% secure, but it already has some protections, the ideal is to convince the use of SSL. (It is possible to get valid certificates for very affordable prices).

But about your case, in a sniffer attack I think it's protected, but the attack is more elaborate, no… Make a test, activate Fiddler to decrypt SSL, but without installing the certificate. Like, go to step three of the link below: http://docs.telerik.com/fiddler/Configure-Fiddler/Tasks/FirefoxHTTPS

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

Scroll to Top