提示:jwt的相关概念,基本原理,常用命令及java实现。
文章目录
- jwt 简介(java)
- 一、openssl生成密钥对
- 二、java读取并使用密钥进行加解密
- 三、jjwt
一、openssl生成密钥对
生成私钥
openssl genrsa -out privatekey.pem 2048
生成公钥
openssl genrsa -out privatekey.pem 2048
privatekey.pem
-----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEAwLH3uWZ9Y5kn5+hSV2hcUrArmUDWjHhFuAWOhBZQgsg2yabf ...... ytTGE0j3mjQDA8NzRinHqkgGpOrM6dbo4MnfddAOkYGFwx959xIYv9o= -----END RSA PRIVATE KEY-----
publickey.pem
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwLH3uWZ9Y5kn5+hSV2hc ...... AddsYG2Xt+IB3KWzqfRYMZTWKoQ0cMPyc3KZWL3u0JZKjly/IX9vzKJkZyh9zGgF 0wIDAQAB -----END PUBLIC KEY-----
pem的三种格式
PKCS#1 PEM (-----BEGIN RSA PRIVATE KEY-----)
PKCS#8 PEM (-----BEGIN PRIVATE KEY-----)
PKCS#8 DER (binary)
openssl pkcs8 -in key.pem -topk8 -nocrypt -out pk8key.pem二、java读取并使用密钥进行加解密
package com.example.demo;
import javax.crypto.Cipher;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.base64;
public class RSADemo {
private static final String PKCS_1_PEM_HEADER = "-----BEGIN RSA PRIVATE KEY-----";
private static final String PKCS_1_PEM_FOOTER = "-----END RSA PRIVATE KEY-----";
private static final String PKCS_8_PEM_HEADER = "-----BEGIN PRIVATE KEY-----";
private static final String PKCS_8_PEM_FOOTER = "-----END PRIVATE KEY-----";
private static final String PUBLIC_HEADER = "-----BEGIN PUBLIC KEY-----";
private static final String PUBLIC_FOOTER = "-----END PUBLIC KEY-----";
private static final String privateKeyPath = "src/main/resources/static/privatekey.txt";
private static final String publicKeyPath = "src/main/resources/static/publickey.txt";
public static String readFile(String path) throws IOException {
BufferedReader fis = new BufferedReader(
new InputStreamReader(
new FileInputStream(path), StandardCharsets.UTF_8));
String line;
StringBuilder sb = new StringBuilder();
while ((line = fis.readLine()) != null) {
sb.append(line);
}
fis.close();
System.out.println(sb);
return new String(sb);
}
public static PublicKey loadPublicKey(String keyFilePath) throws GeneralSecurityException, IOException {
String keyDataString = readFile(keyFilePath);
if (keyDataString.contains(PUBLIC_HEADER)) {
keyDataString = keyDataString.replace(PUBLIC_HEADER, "");
keyDataString = keyDataString.replace(PUBLIC_FOOTER, "");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(base64.getDecoder().decode(keyDataString));
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(keySpec);
return publicKey;
}
return null;
}
public static PrivateKey loadPrivateKey(String keyFilePath) throws GeneralSecurityException, IOException {
String keyDataString = readFile(keyFilePath);
if (keyDataString.contains(PKCS_1_PEM_HEADER)) {
keyDataString = keyDataString.replace(PKCS_1_PEM_HEADER, "");
keyDataString = keyDataString.replace(PKCS_1_PEM_FOOTER, "");
return readPkcs1PrivateKey(base64.getDecoder().decode(keyDataString));
}
if (keyDataString.contains(PKCS_8_PEM_HEADER)) {
keyDataString = keyDataString.replace(PKCS_8_PEM_HEADER, "");
keyDataString = keyDataString.replace(PKCS_8_PEM_FOOTER, "");
return readPkcs8PrivateKey(base64.getDecoder().decode(keyDataString));
}
return null;
}
private static PrivateKey readPkcs8PrivateKey(byte[] pkcs8Bytes) throws GeneralSecurityException {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8Bytes);
try {
return keyFactory.generatePrivate(keySpec);
} catch (InvalidKeySpecException e) {
throw new IllegalArgumentException("Unexpected key format!", e);
}
}
private static PrivateKey readPkcs1PrivateKey(byte[] pkcs1Bytes) throws GeneralSecurityException {
int pkcs1Length = pkcs1Bytes.length;
int totalLength = pkcs1Length + 22;
byte[] pkcs8Header = new byte[]{
0x30, (byte) 0x82, (byte) ((totalLength >> 8) & 0xff), (byte) (totalLength & 0xff), // Sequence + total length
0x2, 0x1, 0x0,
0x30, 0xD, 0x6, 0x9, 0x2A, (byte) 0x86, 0x48, (byte) 0x86, (byte) 0xF7, 0xD, 0x1, 0x1, 0x1, 0x5, 0x0, // Sequence: 1.2.840.113549.1.1.1, NULL
0x4, (byte) 0x82, (byte) ((pkcs1Length >> 8) & 0xff), (byte) (pkcs1Length & 0xff) // Octet string + length
};
byte[] pkcs8bytes = join(pkcs8Header, pkcs1Bytes);
return readPkcs8PrivateKey(pkcs8bytes);
}
private static byte[] join(byte[] byteArray1, byte[] byteArray2) {
byte[] bytes = new byte[byteArray1.length + byteArray2.length];
System.arraycopy(byteArray1, 0, bytes, 0, byteArray1.length);
System.arraycopy(byteArray2, 0, bytes, byteArray1.length, byteArray2.length);
return bytes;
}
public static void main(String[] args) throws GeneralSecurityException, IOException {
String secretMessage="123abc987gfe";
PublicKey publicKey = loadPublicKey(publicKeyPath);
PrivateKey privateKey = loadPrivateKey(privateKeyPath);
Cipher encryptCipher = Cipher.getInstance("RSA");
encryptCipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] secretMessageBytes = secretMessage.getBytes(StandardCharsets.UTF_8);
byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
Cipher decryptCipher = Cipher.getInstance("RSA");
decryptCipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] decryptedMessageBytes = decryptCipher.doFinal(encryptedMessageBytes);
String decryptedMessage = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
System.out.println(decryptedMessage);
}
}
三、jjwt
PrivateKey privateKey = loadPrivateKey(privateKeyPath);
Instant now = Instant.now();
String jwt = Jwts.builder()
.claim("name", "Jane Doe")
.claim("email", "jane@example.com")
.setSubject("jane")
.setId(UUID.randomUUID().toString())
.setIssuedAt(Date.from(now))
.setExpiration(Date.from(now.plus(5l, ChronoUnit.MINUTES)))
.signWith(SignatureAlgorithm.RS256, privateKey)
.compact();
PublicKey publicKey = loadPublicKey(publicKeyPath);
Jws jws = Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(jwt);
System.out.println(jws);
```



