Reputation: 304
I finished my web api with data encriptions, but now, i have to encripty the Json result. When i put the querystring on the browser, now i have the answer (example) :
[{"SUSPID":"111","IVNOME":"teste","IVMAE":"teste","IVPAI":"teste","IVDATANASC":"02/07/1970","IVRG":"0000 (IFP)","ICPF":"Não Cadastrado"}]
I cannot show this...i have to show like (ENCRYPTED): [{"SUSPID":"AUAUAUA","IVNOME":"UAUAU","IVMAE":"UAUAU", ......]
I am seeing some examples, but i am not finding one that is what i need
Part of the code on my service (Cliente-side):
var response = await client.GetAsync(urllink);
var JsonResult = response.Content.ReadAsStringAsync().Result;
if (typeof(T) == typeof(string))
return null;
var rootobject = JsonConvert.DeserializeObject<T>(JsonResult);
return rootobject;
And at my controller (web api BackEnd), i return this dataset:
return lretorno.Tables[0].AsEnumerable().Select(row => new Envolvido
{
SUSPID = Convert.ToString(row["SUSPID"]),
IVNOME = Convert.ToString(row["SUSPNOME"]),
IVMAE = Convert.ToString(row["SUSPMAE"]),
IVPAI = Convert.ToString(row["SUSPPAI"]),
IVDATANASC = Convert.ToString(row["SUSPDATANASC"]).Replace(" 00:00:00", ""),
IVRG = Convert.ToString(row["RG"]),
ICPF = Convert.ToString(row["CPF"]),
MANDADO = Convert.ToInt16(row["TEMMANDADO"]),
OCORRENCIA = Convert.ToInt16(row["TEMOCORRENCIA"]),
});
I cannot understand where i have to encripty and where i have to decrypt on the code.
Upvotes: 1
Views: 14577
Reputation: 314
If you really must do some additional encryption on top of https, for instance if you want to help stop automated man-in-the-middle you can do something like the following... this would require the people in between (Government, ISP, Telco, Endpoint network admin's) to do a second man in the middle attack by figuring out specifically how you are passing your extra public key. In addition to this you could also include the "pk" parameter inside your JSON before its encrypted... and then when you decrypt the json you can compare it against the public-key that you sent, if they don't match then for sure there was a man-in-the-middle. I used the built in RSACryptoServiceProvider.
CLIENT-SIDE
// Generate private and public keys (use any asymmetric crypto/key size you want)
RSACryptoServiceProvider rsaKeys = new RSACryptoServiceProvider();
var privateXmlKeys = rsaKeys.ToXmlString(true);
var publicXmlKeys = rsaKeys.ToXmlString(false);
// Make the request for the json data from the server, and also pass along the public xml keys encoded as base64
var response = await http.GetAsync(new Uri(String.Format("https://example.com/data?id=777&pk=\"{0}\"", Convert.ToBase64String(Encoding.ASCII.GetBytes(publicXmlKeys)))));
var encryptedJsonBytes = await response.Content.ReadAsByteArrayAsync();
// Decrypt the bytes using the private key generated earlier
RSACryptoServiceProvider rsaDecrypt = new RSACryptoServiceProvider();
rsaDecrypt.FromXmlString(privateXmlKeys);
byte[] decryptedBytes = rsaDecrypt.Decrypt(encryptedJsonBytes, false);
// Now change from bytes to string
string jsonString = Encoding.ASCII.GetString(decryptedBytes);
// TODO: For extra validation, parse json, get the public key out that the server
// had used to encrypt, and compare with the "pk" you sent "publicXmlKeys",
// if these values do not match there was an attack.
SERVER-SIDE
// Assuming you have your JSON string already
string json = "{\"key\":\"secret_value\"}";
// Get the "pk" request parameter from the http request however you need to
string base64PublicKey = request.getParameter("pk");
string publicXmlKey = Encoding.ASCII.GetString(Convert.FromBase64String(base64PublicKey));
// TODO: If you want the extra validation, insert "publicXmlKey" into the json value before
// converting it to bytes
// var jo = parse(json); jo.pk = publicXmlKey; json = jo.ToString();
// Convert the string to bytes
byte[] jsonBytes = Encoding.ASCII.GetBytes(json);
// Encrypt the json using the public key provided by the client
RSACryptoServiceProvider rsaEncrypt = new RSACryptoServiceProvider();
rsaEncrypt.FromXmlString(publicXmlKey);
byte[] encryptedJsonBytes = rsaEncrypt.Encrypt(jsonBytes, false);
// Send the encrypted json back to the client
return encryptedJsonBytes;
If you need to protect against man in the middle attacks then I suggest you turn off the computer or pre-share the key via a different method not over the internet, phone, or mail and then do not embed it into your application :P Take a look into Off-the-record, End-to-end-encryption and Diffie–Hellman key exchange
Upvotes: 4
Reputation: 220
Basically I have some generic ideas about this sort of cases for you. If you knows about the Man in the middle attack, only in E2E
connection you can rely on your encryption
algorithm, That's because only these End-points have the private and public key and the attacker can not spoof, But in these cases(like your case) the attacker can simply have your public key and even your encrypted block which you're trying to send to your webservice, That's because all you have in client-side is in the javascript resources that everyones can read.
So the only solution I can give you is that take your webservices on the HTTPS
protocols which normally handle these kind of issues and you don't need to any encryption.
Regards.
Upvotes: 2