Interface for MVC OR API

Source: Internet
Author: User
Tags md5 encryption

Interface security for MVC OR Webapi

When we develop an app, the app needs to communicate with the backend service to get or submit the data. If we do not have a perfect security mechanism, it is easy to tamper with the data by the hard-hearted person who forged the request.
So we need to use some kind of security mechanism to guarantee the legality of the request. Now the most common way is to add a signature to each HTTP request, the service side to verify the legitimacy of the signature, if the signature is legitimate to perform the action of the response, if the signature is illegal, the request is rejected directly.

Signature Algorithm

The signature algorithm generally uses hash hashing algorithm, commonly used Md5,sha series algorithm. These algorithms can calculate different results according to different input, and the probability of collisions is very low.
The signature algorithm is not the same as the cryptographic algorithm. Many students will say that using MD5 encryption, in fact, this is wrong. The signature algorithm cannot restore the original data because it does not contain information about the original data.
However, the encryption method can be used to re-calculate the original data according to the encryption result.
The HMAC sha, as a more secure signature algorithm, uses a key to affect the results of the signature. So the same input with different keys can draw a different signature, more secure.

 PublicStaticstring hmacsha256 (string secretkey,string Plain) {var keyBytes = Encoding.UTF8.GetBytes (Secretkey); var plainbytes = Encoding.UTF8.GetBytes (plain); using (var hmacsha256 = new HMACSHA256 (keybytes)) {var sb = new StringBuilder (); var hashValue = Hmacsha256.computehash (plainbytes); foreach (byte x in hashValue) {sb. Append (String.Format ( "{0:x2}", x));} return sb. ToString (); } } 
Parameters of the signature

With the signature algorithm, where does the content of our signature come from?
In general, we use the HTTP request's QueryString and then add a timestamp and a random number as the signature parameter.

 PublicStaticstring makesignplain (sorteddictionary<string,string> queryString,string time,  String random) { var sb = new StringBuilder (); foreach (var keyValue in queryString) {sb. AppendFormat ("{0}={1}&", Keyvalue.key, Keyvalue.value);} if (sb.) Length>1) {sb. Remove (sb.) Length- 1, 1);} sb. Append (time); Sb. Append (random); return SB. ToString (). ToUpper (); }
Verifying signatures

Verifying the signature is simply a comparison between the service-side production signature and the client-produced signature.
One thing to note is that it is best to verify the next timestamp, which cannot be compared to 5 minutes before and after the server time. This is also a simple means of anti-replay attack.

 PublicStaticboolValid (String Requestsign,String Signplain,String time,String Secretkey) {if (String. IsNullOrEmpty (time) | |String. IsNullOrEmpty (requestsign) | |String. IsNullOrEmpty (Signplain)) {ReturnFalse }is in rangevar now = DateTime.Now;Long RequestTime =0;if (Long. TryParse (Time,Out RequestTime)) {var max = now. AddMinutes (5). ToString ("Yyyymmddhhmmss"); var min = now. AddMinutes (-5). ToString ("Yyyymmddhhmmss"); if (! ( long. Parse (max) >= requesttime && long. Parse (min) <= requesttime) { return false;}} else { return false;} //hashmac var sign = encryption.hmacsha256 (Secretkey, Signplain); return Requestsign.equals (sign, stringcomparison.currentcultureignorecase);}      
Apicontroller base class

With the above cushion we can complete the signature verification in the base class. The client needs to put the timestamp mentioned above, the random number, the signature and the ID of the client into the headers of the HTTP request.
We take these data together in the onactionexecuting of the base class into signed parameters, then get the signed key based on the client ID, and then use the same signature algorithm to calculate the signature. and compare whether the signature of the client is consistent with the signature of the server.
This is not a demonstration.

Prevention of Replay Attack

There are two main points to prevent replay attacks:

    • Check the range of timestamps
      The time stamp is considered legal in a reasonable range from the server time.
    • Cache signature
      Each request is judged to see if the signature has occurred. It is considered an illegal request if it has occurred.
      Since there is a time stamp following the existence of the machine number, it is theoretically impossible to duplicate the signature of each request.
Client Calls

This shows the code for C # signing and invoking the HTTP interface

[TestMethod ()]PublicvoidGetusertest () {String url ="Http://localhost:8090/api/test/GetUser";String userId ="A39891D4-6CEF-4538-A562-3A422CA9C17A";String appId ="100001";String Secretkey ="M/vkpowxgba7gnrd73t7j+jskfbztb+f";String Rumdon = Guid.NewGuid (). ToString ();String time = DateTime.Now.ToString ("Yyyymmddhhmmss");Make Signture Plain Textvar sortdict =New sorteddictionary<StringString> () {{"UserID", UserID};var signplain =New StringBuilder ();foreach (var keyValueIn sortdict) {Signplain.appendformat ("{0}={1}&", Keyvalue.key, Keyvalue.value); }if (Signplain.length >1) {Remove Last & Signplain.remove (Signplain.length-1,1); } signplain.append (time); Signplain.append (random); Console.WriteLine ("Sign plain:{0}", Signplain.tostring (). ToUpper ());Make signvar sign = encryption.hmacsha256 (Secretkey, signplain.tostring (). ToUpper ()); Console.WriteLine ("Sign:{0}", sign);String Requesturl =String. Format ("{0}?" {1}={2} ", URL,"UserID", UserID); HttpWebRequest request = (HttpWebRequest) webrequest.create (Requesturl); Request. Method ="GET";Add headers request. Headers.add ("Time", time); Request. Headers.add ("AppId", appId); Request. Headers.add ("Random", random); Request. Headers.add ("Sign" and sign);//Start requesttry {using (HttpWebResponse response = (HttpWebResponse) request. GetResponse ()) {var responsestream = response. GetResponseStream ();if (responsestream! = null) { using (StreamReader reader = new StreamReader (Responsestream)) { var con Tent = reader. ReadToEnd (); Console.WriteLine (content); }}}} catch (WebException ex) { using (httpwebresponse response = (HttpWebResponse) ex. Response) { var responsestream = Response. GetResponseStream (); if (responsestream! = null) { using (StreamReader reader = new StreamReader (Responsestream)) { var Content = Reader. ReadToEnd (); Console.WriteLine (content); } } } } }

Interface for MVC OR API

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.