如何从 .key 文件加载私钥
Posted
技术标签:
【中文标题】如何从 .key 文件加载私钥【英文标题】:how to load Private Key from .key file 【发布时间】:2020-08-28 21:19:48 【问题描述】:我想从 .key 文件加载 PrivateKey 并使用它来生成 jwt 令牌。 我有以下方法来生成令牌
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 方法如下:
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;
在编译时我得到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)
我不明白,因为我正在打开 PKCS8 私钥。有人知道如何解决这个问题吗?
【问题讨论】:
【参考方案1】:我希望这将帮助您生成令牌。
将.key
或.der
文件保存到类路径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;
找到项目配置类:
@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;
主类:
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());
应用程序-stg.properties
keyAlgorithm=RSA
keyPath=private-stage.der
subject=
issuer=
audience=
claimKey=
claimValue=true
tokenExpiryFrequency=DAY
tokenExpiryUnit=1
clientId=
clientSecret=
jwtTokenUrl=
【讨论】:
以上是关于如何从 .key 文件加载私钥的主要内容,如果未能解决你的问题,请参考以下文章