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