1

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.

Mcfer
  • 194
  • 1
  • 4
  • 15
  • Your question is very unclear. Are you encrypting values in the json or maybe the whole json object? Is each value encrypted or only some? Are you sending json over a URL (usually json is sent as the http message body especialy due to limits of the URL like length)? What algorithm are you encrypting with? Do you have a private key to decrypt/encrypt with? – Igor Aug 15 '16 at 19:59
  • @Igor i am not encripting nothing yet !! I need to encripty ... thats the question... i have to encripty all the Json because all the values are sensitive. I am using HTTP to send. What i told that i already encripted is the content of the querystring when i send the values on the querystring. Now, i need encript the Json – Mcfer Aug 15 '16 at 20:07
  • It sounds like currently you know 0 about encryption (no offense intended). I recommend you first figure out how encryption works, and then pick the best algorithm that suits your needs (a symmetric or asymmetric) and then implement that in your project. Make sure its supported at both client and server (if client is javascript this could be an issue) and that you also think about a strategy for key sharing. Alternatively if this is all browser based then maybe transmission over httpS is sufficient and you are over thinking it. – Igor Aug 15 '16 at 20:18
  • @Igor Yes, i don´t know too much ! Let me explain... i did a web api with just a Get. So, i used the Nugget PCLCrypto to encrypt just the values on the querystring. 100% working...but, when the Security department of here saw the code, they told me that i need to encrypt the Json result as well. I am also transmiting by httpS , but they still need the Json result encrypted. So, how the Json is a string, i don´t know if i can simple use the PCLCrypto ! And how to do this. Encripting the result on the WebApi and decripting on the Client-side ?Thats my question...i am not seeing nothing like this – Mcfer Aug 15 '16 at 20:27
  • If your question is, "how can I integrate encryption of specific properties into Json.NET", see [here](https://stackoverflow.com/questions/29196809). But if your question is, "how can I secure an ASP.NET Web API" see, possibly, [here](https://stackoverflow.com/questions/11775594). I think you need to specify your requirements more precisely. – dbc Aug 15 '16 at 20:28
  • @dbc i had saw this post about specific properties ! In my case, the difference is that i need to encrypt all the properties – Mcfer Aug 15 '16 at 20:36
  • @MarceloCFernandes - then just remove the `&& pi.GetCustomAttribute(typeof(JsonEncryptAttribute), true) != null` to encrypt all string-valued properties. But then have your security department review the code to make sure you've implemented the `EncryptedStringValueProvider` correctly. – dbc Aug 15 '16 at 20:41

2 Answers2

4

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

xer21
  • 304
  • 1
  • 11
  • I will try as soon as possible, but seems to be what i need !! I am using Xamarin and using the PCLCrypto to encrypt all the datas... but i am having difficult to change from syncronous to assyncronous mode! I will give a try for RSACryptoServiceProvider.... THANKS AGAIN ! – Mcfer Sep 13 '16 at 17:08
  • If you "await" the response like in my example shouldn't be a problem with async... if your breaking your code up into different methods/classes then whatever code is going to handle the response make sure you pass along the "privateXmlKeys" value – xer21 Sep 13 '16 at 18:53
  • My friend... the RSACryptoServiceProvider is always a Asym crypto ? Other question...when you sugest the extra-validation, you told "if these values do not match there was an attack", but if the public key is different, the decryption will not be succesfull and the attacker will not see nothing. Or I am wrong ? Because of this, I am not understanding this extra validation... can you explain better ? Sorry for this and many thanks !! – Mcfer Sep 15 '16 at 15:09
  • @MarceloCFernandes Yes RSACryptoServiceProvider extends the AsymmetricAlgorithm class. I understand the extra validation can be confusing... if a man in the middle attack occurs that means they would have provided the server-side a different public key than what you sent then decrypted what your server-side sent and re-encrypted with your original public key so your client side can decrypt the request. They could manually update the json as well in the attack but its even more work for them. – xer21 Sep 15 '16 at 19:51
  • I'll also add that if someone is attempting to do a man-in-the-middle attack which is probably unlikely their first few attempts I'm sure they will mess up with not passing the public key, or not including the public key in the json... so if you were to monitor when those cases happen then its a great indicator someone is starting to interfere and you can alert someone to take action – xer21 Sep 15 '16 at 19:58
  • Thanks for the explanation!! Very helpfull... The System.Security.Cryptography to use RSACryptoServiceProvider doesn´t work in Xamarin PCL (forms). I think i have to use the PCL Crypto - Portable Crypto .. but i am not finding a example with a asymetrical crypto. – Mcfer Sep 16 '16 at 14:02
  • PCL has asymmetric crypto... take a look at the asymmetric support here... https://github.com/AArnott/PCLCrypto/wiki/Algorithms-X-platforms-support you will probably not be able to use ToXmlString or FromXmlString and you would have to figure out how to set the key/iv yourself, I've never used PCLCrytpo but it looks like you can use it how you need to – xer21 Sep 17 '16 at 00:39
  • the problem is that i am a newbie in crypto and i am not finding a example code of asymetric using PCLCrypto. Just symetric... – Mcfer Sep 20 '16 at 13:14
  • What are the platforms you are targeting? – xer21 Sep 20 '16 at 17:05
  • Xamarin Forms with just .droid and .ios ! – Mcfer Sep 20 '16 at 18:07
  • My friend....thanks for your help. So, i got it using BoucyCastle . Two doubts ...its a problem fix the private key ? May i really send the publickey via querystring. I mean, its not unsafe? – Mcfer Sep 20 '16 at 19:52
  • I was going to recommend bouncycastle but I haven't used it and I didn't see documentation... I'm sure PCLCrypto will work also but their api seems poorly designed, seems they want you to call different objects for every platform your using instead of standardizing it to one object and throw NotSupportedException on platforms that don't have support for a specific algo. Yes you can send the publickey via querystring, or POST it either one... I assume your not calling it via a browser so a GET is fine, but if you were using in a browser I would suggest POST. Just don't send the private key!! – xer21 Sep 20 '16 at 20:41
  • No ... its via app but not using browser !! Certainly if the user wants to do something bad, he will catch the querystring, but i am not using browser. Thanks my friend! Very helpfull – Mcfer Sep 20 '16 at 21:01
  • Your forgot the other question... its unsafe fix the public and private keys ? to avoid send on querystring. Remeber that i am using a cipher object for OAEP encoding. – Mcfer Sep 21 '16 at 16:20
  • what was the question I didn't answer? I didn't quite follow... but I did say Yes you can send the publickey in the querystring, but do not send the private key at all across the internet – xer21 Sep 28 '16 at 19:57
1

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.

Ramin Esfahani
  • 190
  • 1
  • 6
  • Yes...a lot of people are telling me this!! But is not a option... if the app was mine, i would do this with just https, but its for a company and they have a security department that need it. But thanks my friend – Mcfer Sep 13 '16 at 16:57