问题
I would like to load PrivateKey from a .key file and use it to generate jwt token. I have following method to generate token
public String gen(String privateFile, String crtFile) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
long expMillis = nowMillis + 50000;
Date exp = new Date(expMillis);
// load private key
PrivateKey privKey= loadPrivateKey(privateFile);
// load public key
PublicKey pubKey= loadPublicKey(crtFile);
String jws = Jwts.builder()
.setSubject(jwtSubject)
.setAudience(jwtAudience)
.setExpiration(exp)
.setIssuedAt(now)
.setIssuer(jwtIssuer)
.setNotBefore(now)
.signWith(privKey, SignatureAlgorithm.RS512)
.compact();
return jws;
}
loadPrivateKey method looks as follows:
public static PrivateKey loadPrivateKey(String filename)
throws Exception {
String privateKeyContent = new String(Files.readAllBytes(Paths.get(ClassLoader.getSystemResource(filename).toURI())));
privateKeyContent = privateKeyContent.replaceAll("\\n", "").replace("-----BEGIN PRIVATE KEY-----", "").replace("-----END PRIVATE KEY-----", "");
KeyFactory kf = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
PrivateKey privKey = kf.generatePrivate(keySpecPKCS8);
return privKey;
}
On the compilation I get java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:663)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
Which I do not understand because I am opening PKCS8 private key. Would someone have an idea how to solve this?
回答1:
I hope this will help you to generate the token.
keep the .key
or .der
file into classpath src/main/resources
.
public class JWTClientService {
public String generateJWTToken(ProjectConfig jwtConfig) {
return Jwts.builder()
.setSubject(jwtConfig.getSubject())
.setIssuer(jwtConfig.getIssuer())
.setExpiration(getExpiryDate(jwtConfig.getTokenExpiryUnit(), jwtConfig.getTokenExpiryFrequency()))
.setAudience(jwtConfig.getAudience())
.claim(jwtConfig.getClaimKey(), Boolean.valueOf(jwtConfig.getClaimValue()))
.signWith(SignatureAlgorithm.RS512, privateKey(jwtConfig))
.compact();
}
private Date getExpiryDate(String tokenExp, String tokenExpFreq) {
Calendar calendar = Calendar.getInstance();
int expiry = Integer.parseInt(tokenExp);
switch (tokenExpFreq.toLowerCase()) {
case "second": {
calendar.add(Calendar.SECOND, expiry);
break;
}
case "minute": {
calendar.add(Calendar.MINUTE, expiry);
break;
}
case "hour": {
calendar.add(Calendar.HOUR, expiry);
break;
}
case "day": {
calendar.add(Calendar.DATE, expiry);
break;
}
case "month": {
calendar.add(Calendar.MONTH, expiry);
break;
}
default: {
calendar.add(Calendar.HOUR, expiry);
break;
}
}
return calendar.getTime();
}
private PrivateKey privateKey(ProjectConfig jwtConfig) {
PrivateKey privateKey = null;
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(jwtConfig.getKeyPath());
ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
assert inputStream != null;
IOUtils.copy(inputStream, byteOutputStream);
byte[] privKeyByteArray = byteOutputStream.toByteArray();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privKeyByteArray);
KeyFactory keyFactory = KeyFactory.getInstance(jwtConfig.getKeyAlgorithm());
privateKey = keyFactory.generatePrivate(keySpec);
} catch (Exception ex) {
throw new RuntimeException("Unable to generate private key..." + ex.getMessage());
}
return privateKey;
}
}
Find the Project config class:
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProjectConfig {
private String clientId;
private String clientSecret;
private String jwtTokenUrl;
private String keyAlgorithm;
private String keyPath;
private String subject;
private String issuer;
private String audience;
private String claimKey;
private String claimValue;
private String tokenExpiryFrequency;
private String tokenExpiryUnit;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getJwtTokenUrl() {
return jwtTokenUrl;
}
public void setJwtTokenUrl(String jwtTokenUrl) {
this.jwtTokenUrl = jwtTokenUrl;
}
public String getKeyAlgorithm() {
return keyAlgorithm;
}
public void setKeyAlgorithm(String keyAlgorithm) {
this.keyAlgorithm = keyAlgorithm;
}
public String getKeyPath() {
return keyPath;
}
public void setKeyPath(String keyPath) {
this.keyPath = keyPath;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getIssuer() {
return issuer;
}
public void setIssuer(String issuer) {
this.issuer = issuer;
}
public String getAudience() {
return audience;
}
public void setAudience(String audience) {
this.audience = audience;
}
public String getClaimKey() {
return claimKey;
}
public void setClaimKey(String claimKey) {
this.claimKey = claimKey;
}
public String getClaimValue() {
return claimValue;
}
public void setClaimValue(String claimValue) {
this.claimValue = claimValue;
}
public String getTokenExpiryFrequency() {
return tokenExpiryFrequency;
}
public void setTokenExpiryFrequency(String tokenExpiryFrequency) {
this.tokenExpiryFrequency = tokenExpiryFrequency;
}
public String getTokenExpiryUnit() {
return tokenExpiryUnit;
}
public void setTokenExpiryUnit(String tokenExpiryUnit) {
this.tokenExpiryUnit = tokenExpiryUnit;
}
}
Main Class :
public class TokenApplication {
static ObjectMapper objectMapper = new ObjectMapper()
.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true);
public static void main(String[] args) {
ProjectConfig projectConfig = loadConfiguration("application-stg.properties");
if (args.length > 0 && args[0].equals("PROD")) {
projectConfig = loadConfiguration("application-prod.properties");
}
try {
JWTTokenService jwtTokenService = new JWTTokenService();
System.out.println(jwtTokenService.getJwtToken(projectConfig).getAccessToken());
System.exit(JobStatus.SUCCESS.getCode());
} catch (Exception ex) {
System.exit(JobStatus.PROCESS_FAILED.getCode());
}
}
private static ProjectConfig loadConfiguration(String filePath) {
try (InputStream input = TokenApplication.class.getClassLoader().getResourceAsStream(filePath)) {
Properties props = new Properties();
props.load(input);
return objectMapper.convertValue(new HashMap(props), ProjectConfig.class);
} catch (Exception ex) {
throw new RuntimeException("Not able to load configuration" + ex.getMessage());
}
}
}
application-stg.properties
keyAlgorithm=RSA
keyPath=private-stage.der
subject=
issuer=
audience=
claimKey=
claimValue=true
tokenExpiryFrequency=DAY
tokenExpiryUnit=1
clientId=
clientSecret=
jwtTokenUrl=
来源:https://stackoverflow.com/questions/61761800/how-to-load-private-key-from-key-file