how to load Private Key from .key file

六月ゝ 毕业季﹏ 提交于 2020-08-10 18:54:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!