introduce
Recently, I want to develop a coder management platform. For the technical selection of login module, I chose JWT
Jwt can ensure that the login information placed on the client is not tampered with.
In order to be more secure, I use RSA asymmetric encryption. That is, the private key is used to generate Jwt, and the public key is used to verify Jwt.
problem
At first, I wanted to use spring's security framework, because it contains JWT, Bcrypt and other contents, and using JwtHelper class, I can easily generate JWT with private key and decrypt public key.
But after searching the whole network, I couldn't find the method of JwtHelper to set the expiration time of Jwt.
One blogger said that iat and exp data can be added manually in the load. But after testing, it still can't.
Finally, I decided to use Jwts for encryption and decryption
Encryption and decryption of JWT
The code provides encryption and decryption of Jwts and JwtHelper
Step 1: generate key
Generated through keyTool (certificate management tool provided by java)
This tool is available as long as JDK is installed. You can enter keytool in cmd interface to check whether there is such a tool.
If:
'keytool' is not an internal or external command, nor is it a runnable program or batch file.
You can enter the jdk installation directory. Under the bin folder, there is keytool Exe file.
At this time, enter cmd in the address bar and press enter to open the cmd window here.
Execute the following command:
// The following instructions are one line. Setting multiple lines is convenient for reading keytool -genkeypair -alias key alias -keyalg Algorithm used -keypass Key access password -keystore Generated keystore file name, extension is jks -storepass The access password of the keystore, which is used to open jks file
After entering the information, you can generate jks files in the current directory.
Step 2: export public key
For microservices, the private key is placed on the authentication service, and other services only need to store the public key. Because other services only perform verification and do not encrypt JWT
You can export the key through openssl, that is, the public key or private key in string format
openssl needs to be installed, Click here Jump Download
After installation, add environment variables:
Execute the following command:
keytool -list -rfc --keystore jks file(Include extension.jks) | openssl x509 -inform pem -pubkey
Copy the contents of ----- BEGIN PUBLIC KEY ----- and ----- END PUBLIC KEY -----, create a new file and store it.
Generally, create public key
Put it into the resource directory of the project
Step 3: encrypt JWT
/** * Generate JWT token based on private key * * @author Eugenema * @date 2022/2/19 17:49 * * @param userInfo User information * * @return Encrypted JWT **/ public String createJWT(UserInfo userInfo){ //load Map<String,Object> payload = new HashMap<>(2); payload.put("id", userInfo.getId()); payload.put("userName",userInfo.getName()); /** Private key: under the resource directory */ ClassPathResource keyFileResource = new ClassPathResource("emPerson.jks"); //Create a secret key factory. The parameters are: secret key file, secret key library password //import org.springframework.security.rsa.crypto.KeyStoreKeyFactory; //pom file: /** <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-rsa</artifactId> <version>1.0.11.RELEASE</version> </dependency> */ KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(keyFileResource, "Keystore password password".toCharArray()); //Obtain the secret key. The parameters are: alias, secret key and password KeyPair keyContent = keyStoreKeyFactory.getKeyPair("alias alias", "Password of secret key".toCharArray()); /** Private key */ PrivateKey privateKey = keyContent.getPrivate(); //Generate JWT through JwtHelper //Deprecated because the expiration time cannot be set // Jwt jwtContent = JwtHelper.encode(JSON.toJSONString(payload), new RsaSigner(privateKey)); // String jwtEncoded = jwtContent.getEncoded(); // System.out.println(jwtEncoded); //Generate JWT through Jwts //pom file: /** <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version> </dependency> */ JwtBuilder eugeneMa = Jwts.builder() //Set load .addClaims(payload) //Setting ID is said to prevent replay attacks .setId(String.valueOf(System.currentTimeMillis())) //set up themes .setSubject("eugeneMa") //Set issuing time .setIssuedAt(new Date()) //Set expiration time .setExpiration(new Date(System.currentTimeMillis() + 30000)) //Set encryption algorithm and private key .signWith(SignatureAlgorithm.RS256, privateKey); //Return to JWT return eugeneMa.compact(); }
Step 4: decrypt JWT
/** * Parsing JWT * * @author Eugenema * @date 2022/2/19 18:47 * * @param jwt JWT to decrypt * * @return jwt after parsing **/ public String parseJwt(String jwt){ //Parsing through JwtHelper //Jwt token = JwtHelper.decodeAndVerify(jwt, new RsaVerifier(getPubKey)); //return token.getClaims(); //Parsing through Jwts Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getPubKey()).parseClaimsJws(jwt); return claimJws.getBody(); } /** * Get public key * * @author Eugenema * @date 2022/2/19 19:01 * * @return Public key. If the acquisition fails, null will be returned **/ private static PublicKey getPubKey() { //Point to the public key file in the resource directory Resource publicKey = new ClassPathResource("public.key"); try { InputStreamReader publicKeyIs = new InputStreamReader(publicKey.getInputStream()); BufferedReader publicKeyBr = new BufferedReader(publicKeyIs); StringBuilder publicKeySb = new StringBuilder(); String line; //Change multiple lines in the file to one line while ((line = publicKeyBr.readLine()) != null) { publicKeySb.append(line); } //Convert String to java PublicKey object byte[] byteKey = Base64.getDecoder().decode(publicKeySb.toString()); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(x509EncodedKeySpec); } catch (Exception e) { logger.error("Get public key exception!", e); return null; } }