In the network world, security is a very important problem, the past HTTP requests can not bear this security task, a packet capture tool, all your network requests are exposed. Sure, you might use an encryption algorithm to encrypt data, but that’s still not enough.
During the communication between the mobile terminal and the server, there are two authentication modes: Token and Session.
Session: After each user is authenticated by our application, our application makes a record on the server to facilitate the identification of the user’s next request. Generally speaking, sessions are stored in the database and memory. However, as the number of authenticated users increases, the overhead on the server will increase significantly.
Scalability: After the user is authenticated, the server makes authentication records. If the authentication records are stored in memory, it means that the user’s next request must be made on this server to obtain authorized resources, which limits the capacity of the load balancer in distributed applications. This also means limiting the application’s ability to scale.
__CSRF: __ Because user identification is based on cookies, if cookies are intercepted, users will be vulnerable to cross-site request forgery attacks. ~~CSRF attacks are web-based implicit authentication mechanisms! The WEB’s authentication mechanism can guarantee that a request is from a user’s browser, but it can’t guarantee that the request is user-approved!
Token-based authentication Similar to HTTP, token-based authentication is stateless and does not need to retain user authentication information or session information on the server. This means that token-based applications do not need to consider which server users log in to, which facilitates application expansion.
The process looks like this:
- The user requests the server using a username and password
- The server authenticates the user’s information
- The server sends the user a token through authentication
- The client stores the token and supplies it with each request
- The server validates the token value and returns data
Access-control-allow-origin: * This token must be passed to the server on every request. It should be stored in the header of the request. In addition, the server must support the CORS policy.
So let’s go back to JWT.
JWT is what?
Json Web Token (JWT) is an open jSON-based standard (RFC 7519) implemented for the transfer of declarations between network application environments. The token is designed to be compact and secure, especially suitable for single sign-on (SSO) scenarios in distributed sites. The JWT declaration is generally used to pass authenticated user identity information between the identity provider and the service provider to obtain resources from the resource server, and to add some additional declaration information necessary for other business logic. The token can also be used directly for authentication or can be encrypted.
What does JWT look like?
JWT is made up of three pieces of information. Use these three pieces of information text. The links together make up the Jwt string. Something like this:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHQiOjE0ODg1NTM3OTk5NzIsImlwIjoiMTkyLjE2OC4xMDIuMTk1IiwidGVsIjoiMTMxMjM0NTY3ODk iLCJ0eXBlIjoiMiIsImRldmljZSI6ImVjMGEwOWZhOWRiOTNjNDQ1Mzk1YzcyNmI2OTUyM2YzIiwiaWF0IjoxNDg4NTI0OTk5OTcyfQ.9rl2XwKIMnVCVVKv 9GvhTify7P2xhxIITfaSX4tm_78Copy the code
The composition of JWT
The first part we call the header, the second part we call the payload, and the third part is the signature.
Header
The header of the JWT carries two pieces of information:
Declare type, in this case JWT, declare encryption algorithms usually directly using HMAC SHA256 complete headers like the following JSON:
{
'typ': 'JWT'.'alg': 'HS256'
}
Copy the code
Base64 encryption of the header, which can be decrypted symmetrically, then forms the first part.
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.
Copy the code
Playload
The second part of the Token is the payload, which contains claims. Claims are the state and additional metadata of some entity (usually a user). There are three types of claims: reserved, public, and private.
-
Reserved Claims: These claims are predefined by JWT. They are not mandatory in JWT, but recommended. The commonly used claims are ISS (issuer), EXP (expiration timestamp), SUB (user facing), AUD (recipient), and IAT (issue time).
-
Public Claims: Define your own fields as required, taking care to avoid conflicts
-
Private Claims: These are custom fields that can be used to exchange information between two parties
Examples of load usage:
{
"sub": "1234567890"."name": "John Doe"."admin": true
}
Copy the code
The payload above needs to be Base64Url encoded as the second part of the JWT structure.
Signature
To create a signature, you need to use the encoded header, payload and a secret key. The signature algorithm specified in the header is used. For example, if you want to use the HMAC SHA256 algorithm, the signature should be created in the following way:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
Copy the code
The signature is used to verify the sender of the message and that the message has not been tampered with.
The complete JWT
The output of the JWT format is encoded in three Base64 segments separated by. JWT is easier to deliver in HTTP and HTML environments than xmL-based standards such as SAML.
The following JWT shows a complete JWT format that concatenates the previous Header, Payload, and secret key signature:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9. eyJleHQiOjE0ODg1NTM3OTk5NzIsImlwIjoiMTkyLjE2OC4xMDIuMTk1IiwidGVsIjoiMTMxMjM0NTY3ODkiLCJ0eXBlIjoiMiIsImRldmljZSI6ImVjMGEw OWZhOWRiOTNjNDQ1Mzk1YzcyNmI2OTUyM2YzIiwiaWF0IjoxNDg4NTI0OTk5OTcyfQ. 9rl2XwKIMnVCVVKv9GvhTify7P2xhxIITfaSX4tm_78Copy the code
How to apply
[AFHTTPSessionManager manager].requestSerializer setValue:JWTToken forHTTPHeaderField:@"token"];
Copy the code
In this demo I use AFN3.0, Xcoede8.
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; // The server returns the string NSMutableDictionary *para = [[NSMutableDictionary alloc] init]; [parasetValue:userPhoneNumber forKey:@"ac_id"]; // User mobile number [parasetValue:dToken forKey:@"token"]; //UUID NSURLSessionDataTask *task = [self httpRequestWithMethod:@"POST"pathUrl:USER_GET_NEW_SESSION_ID_URL parameters:para success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { NSString *resonseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; / / the server to our flow is a binary string, transforming it into a first nsstrings nsstrings * decodeStr = [RSACode decryptString: resonseString publicKey: publicKey]; / / server to my data through the RSA encryption, decryption here with the public key NSDictionary * dicObject = [RSACode dictionaryWithJsonString: decodeStr]; NSMutableArray *resultJson = [dicObject objectForKey:@"result"];
[[NSUserDefaults standardUserDefaults] setValue:[[resultJson firstObject]objectForKey:@"jwtToken"] forKey:RME_DEVICE_JWT]; // Store tokens permanently in NSUserDefaults [self.requestSerializer]setValue:[[resultJson firstObject]objectForKey:@"jwtToken"] forHTTPHeaderField:@"token"]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {}];Copy the code
Having covered JWT, RSA encryption is next.
The __RSA algorithm __ is the most popular public key cryptography algorithm, which uses a key of variable length. RSA was the first algorithm that could be used for both data encryption and digital signatures. The principle of RSA algorithm is as follows: 1. Two large prime numbers p and Q are randomly selected. P is not equal to q, and N=pq is calculated. 2. Select a natural number e greater than 1 and less than N, e must be copprime with (p-1)×(q-1). 3. D: d×e = 1 (mod (p-1)×(q-1)) 4. Destroy p and Q’s. The resulting N and E are the “public keys” and D is the “private key”. The sender uses N to encrypt the data and the receiver uses D to unlock the data. The security of RSA depends on large number decomposition. N less than 1024 bits has been proved to be insecure. In addition, because RSA performs large number calculation, the fastest CASE of RSA is several times slower than that of DES, which is the biggest disadvantage of RSA. It should be noted that the security of RSA algorithm is only a kind of computational security, not unconditional security, which is determined by its theoretical basis. Therefore, in the implementation of RSA algorithm, every step should be considered from the security aspect.
The public and private keys are first generated through the Mac terminal.
The red line is the command that needs to be input, and the generated file is in the current directory.
openssl
genrsa -out rsa_private_key.pem 1024
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
Copy the code
After generating the public key and private key, we only need to hold the public key on the APP side, and the private key is stored on the server side. In this way, when communicating with the server, the sensitive information server can use the private key to encrypt it, even if others have access to the data. The data we send to the server can also be encrypted through the public key, because the data encrypted by the public key can only be unlocked by the corresponding private key, and the private key can only be held by the server, so that only the server can unlock the encryption. This will make our communication with the server more secure and reliable.
Session | Token | |
---|---|---|
State storage location | The server stores all Session status information | Each client stores its own token status |
scalability | Even in a distributed layout, you need to fetch data from the server that stores the current Session | Any server can resolve the Token |
share | Cannot be shared and licensed to other applications | It can be easily shared and licensed to other applications, and it is secure and cannot be forged |
dependency | This is usually done with cookies | Encryption is secure without dependencies |