无法将公钥、私钥从文件加载到Java对象

问题描述 投票:0回答:0

我使用Ubuntu sub-Linux系统来生成密钥

firerose@DESKTOP-84LARLB:~$ openssl genrsa -out jwtRSA256-private.pem 2048

firerose@DESKTOP-84LARLB:~$ openssl rsa -in jwtRSA256-private.pem -pubout -outform PEM -out jwtRSA256-public.pem
writing RSA key

firerose@DESKTOP-84LARLB:~$ echo -n '{"alg":"RS256","typ":"JWT"}' | base64 | sed s/\+/-/ | sed -E s/=+$//
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9

firerose@DESKTOP-84LARLB:~$ echo -n '{"sub":"RS256inOTA","name":"John Doe"}' | base64 | sed s/\+/-/ | sed -E s/=+$//
eyJzdWIiOiJSUzI1NmluT1RBIiwibmFtZSI6IkpvaG4gRG9lIn0

firerose@DESKTOP-84LARLB:~$ echo -n "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJSUzI1NmluT1RBIiwibmFtZSI6IkpvaG4gRG9lIn0" | openssl dgst -sha256 -binary -sign jwtRSA256-private.pem  | openssl enc -base64 | tr -d '\n=' | tr -- '+/' '-_'
Gim84zxX_4SjTojJq9BU_ivSBkpIAkhJeU8uhv6wUGYxhXK-8-VwLs-WmrDjNM-fIxVtQ_I1Nnz_cgHUSj0G9PtIxJ3zv818D-npzIgcAhWwmv4WWdATtU7UXHGfpKw1pkLOKMlGr8bJ_ooK9yWU49BuaKc1HHH4GizO9hn3IJwMNPeYw7P371aMgshBF3T_gyhGNYippwCE177e_VfdATMibN6S4So-8BKBaLf8uGAtgwcBPc5Qe-CkhAQsnVDy_Rm_l14kEch_ogVQKPrVnDnR4GPYOQSlCi8Q9fZ7rBCTvomw_fANBC7qfLZw3HgkTBE-NEbh0SmSBmzb7BiiYw

firerose@DESKTOP-84LARLB:~$

我的 JWT 令牌

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJSUzI1NmluT1RBIiwibmFtZSI6IkpvaG4gRG9lIn0.Gim84zxX_4SjTojJq9BU_ivSBkpIAkhJeU8uhv6wUGYxhXK-8-VwLs-WmrDjNM-fIxVtQ_I1Nnz_cgHUSj0G9PtIxJ3zv818D-npzIgcAhWwmv4WWdATtU7UXHGfpKw1pkLOKMlGr8bJ_ooK9yWU49BuaKc1HHH4GizO9hn3IJwMNPeYw7P371aMgshBF3T_gyhGNYippwCE177e_VfdATMibN6S4So-8BKBaLf8uGAtgwcBPc5Qe-CkhAQsnVDy_Rm_l14kEch_ogVQKPrVnDnR4GPYOQSlCi8Q9fZ7rBCTvomw_fANBC7qfLZw3HgkTBE-NEbh0SmSBmzb7BiiYw

我的公钥和私钥对 https://drive.google.com/drive/folders/1TMCKH77IBIMv0bZGE4gydbwkqNq-H3uC?usp=sharing

我在 Windows 11 中将文件

jwtRSA256-private.pem
jwtRSA256-public.pem
复制到
C:\

我的Java代码,文件

CryptoUtils.java
有内容

package com.example.cryptology;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA.
 */
public class CryptoUtils {

    private static String getKey(String filename) throws IOException {
        // Read key from file.
        String strKeyPEM = "";
        BufferedReader br = new BufferedReader(new FileReader(filename));
        String line;
        while ((line = br.readLine()) != null) {
            strKeyPEM += line + "\n";
        }
        br.close();
        return strKeyPEM;
    }

    public static RSAPrivateKey getPrivateKey(String filename) throws IOException, GeneralSecurityException {
        String privateKeyPEM = getKey(filename);
        return getPrivateKeyFromString(privateKeyPEM);
    }

    public static RSAPrivateKey getPrivateKeyFromString(String key) throws IOException, GeneralSecurityException {
        String privateKeyPEM = key;
        privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----\n", "");
        privateKeyPEM = privateKeyPEM.replace("-----END PRIVATE KEY-----", "");
        byte[] encoded = Base64.decodeBase64(privateKeyPEM);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
        RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(keySpec);
        return privKey;
    }

    public static RSAPublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException {
        String publicKeyPEM = getKey(filename);
        return getPublicKeyFromString(publicKeyPEM);
    }

    public static RSAPublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException {
        String publicKeyPEM = key;
        publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
        publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
        byte[] encoded = Base64.decodeBase64(publicKeyPEM);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
        return pubKey;
    }

    public static String sign(PrivateKey privateKey, String message) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
        Signature sign = Signature.getInstance("SHA1withRSA");
        sign.initSign(privateKey);
        sign.update(message.getBytes("UTF-8"));
        return new String(Base64.encodeBase64(sign.sign()), "UTF-8");
    }

    public static boolean verify(PublicKey publicKey, String message, String signature) throws SignatureException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        Signature sign = Signature.getInstance("SHA1withRSA");
        sign.initVerify(publicKey);
        sign.update(message.getBytes("UTF-8"));
        return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
    }

    public static String encrypt(String rawText, PublicKey publicKey) throws IOException, GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return Base64.encodeBase64String(cipher.doFinal(rawText.getBytes("UTF-8")));
    }

    public static String decrypt(String cipherText, PrivateKey privateKey) throws IOException, GeneralSecurityException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(Base64.decodeBase64(cipherText)), "UTF-8");
    }

    /**
     * Get public key from file.
     *
     * @param file
     * @return
     * @throws Exception
     */
    public static RSAPublicKey readPublicKey(File file) throws Exception {
        String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
        String publicKeyPEM = key.replace("-----BEGIN PUBLIC KEY-----", "").replaceAll(System.lineSeparator(), "").replace("-----END PUBLIC KEY-----", "");
        byte[] encoded = Base64.decodeBase64(publicKeyPEM);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
        return (RSAPublicKey) keyFactory.generatePublic(keySpec);
    }

    /**
     * Get private key from file.
     *
     * @param file
     * @return
     * @throws Exception
     */
    public static RSAPrivateKey readPrivateKey(File file) throws Exception {
        String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
        String privateKeyPEM = key.replace("-----BEGIN PRIVATE KEY-----", "").replaceAll(System.lineSeparator(), "").replace("-----END PRIVATE KEY-----", "");
        byte[] encoded = Base64.decodeBase64(privateKeyPEM);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
        return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
    }

    public static RSAPublicKey readPublicKeySecondApproach(File file) throws IOException {
        try (FileReader keyReader = new FileReader(file)) {
            PEMParser pemParser = new PEMParser(keyReader);
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pemParser.readObject());
            return (RSAPublicKey) converter.getPublicKey(publicKeyInfo);
        }
    }

    public static RSAPrivateKey readPrivateKeySecondWay(File file) throws Exception {
        KeyFactory factory = KeyFactory.getInstance("RSA");
        try (FileReader keyReader = new FileReader(file);
            PemReader pemReader = new PemReader(keyReader)) {
            PemObject pemObject = pemReader.readPemObject();
            byte[] content = pemObject.getContent();
            PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
            return (RSAPrivateKey) factory.generatePrivate(privKeySpec);
        }
    }

}

文件

SampleController.java

package com.example.controller;

//import org.springframework.security.core.Authentication;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;

@RestController
@RequestMapping("/sample")
public class SampleController {

    @Autowired
    public AuthPartnerRepository authPartnerRepository;


    /**
     * GET http://localhost:8084/sample/login
     * JWT token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aW1lc3RhbXAiOiIyMDIzLTA3LTI0VDA5OjQyOjE4Ljc4NloiLCJpYXQiOjE2OTAxOTE3Mzh9.g3iTwX1n-y8G9k0yzJj36x2nOuWItuWI1qXTEG95CyHf6krpdpbrgVZ7QFsWqXYkYfR_S44s9_vTt49FZ1Bqxw6K7h-T-fpfG77uZHVDU80Y2cZuIDUYLoyGHUqHNHrLcfGjWyAf0knIpJVzD8eWAIewk7fGvbdBjoTaj9dE0wKpa1itMSbnS3G7S2SKlnRH0x2583FgMSQ76yIFl9B4J510_06MljjNKmUJiu2XlyZGEpj0WzYgyDuJfsnuJgz6y847FNtcfxt7IoakMzHRtHrtAYM_pgJaW7uAFWvEta1mEOZEbTy6RB7hnz5i0gYjEuuK3yF4JmSUGtcGGatCvg"
     *
     *
     * @return
     */
    @GetMapping("/login")
    public String foo(@RequestHeader("Authorization") String authorization) throws Exception {
        //AuthPartner authPartner = authPartnerRepository.getOne(1L);
        //String foo = authPartner.getPublicKey();
        //System.out.println(foo);

        String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJSUzI1NmluT1RBIiwibmFtZSI6IkpvaG4gRG9lIn0.Gim84zxX_4SjTojJq9BU_ivSBkpIAkhJeU8uhv6wUGYxhXK-8-VwLs-WmrDjNM-fIxVtQ_I1Nnz_cgHUSj0G9PtIxJ3zv818D-npzIgcAhWwmv4WWdATtU7UXHGfpKw1pkLOKMlGr8bJ_ooK9yWU49BuaKc1HHH4GizO9hn3IJwMNPeYw7P371aMgshBF3T_gyhGNYippwCE177e_VfdATMibN6S4So-8BKBaLf8uGAtgwcBPc5Qe-CkhAQsnVDy_Rm_l14kEch_ogVQKPrVnDnR4GPYOQSlCi8Q9fZ7rBCTvomw_fANBC7qfLZw3HgkTBE-NEbh0SmSBmzb7BiiYw";
        DecodedJWT decodedJWT;
        File publicFile = new File("C:\\jwtRSA256-public.pem");
        // RSAPublicKey rsaPublic = CryptoUtils.readPublicKey(publicFile);
        RSAPublicKey rsaPublic = CryptoUtils.readPublicKeySecondApproach(publicFile);

        File privateFile = new File("C:\\jwtRSA256-private.pem");
        // RSAPrivateKey rsaPrivate = CryptoUtils.readPrivateKey(privateFile);
        RSAPrivateKey rsaPrivate = CryptoUtils.readPrivateKeySecondWay(privateFile);

        try {
            Algorithm algorithm = Algorithm.RSA256(rsaPublic, rsaPrivate);
            JWTVerifier verifier = JWT.require(algorithm).withIssuer("auth0").build();
            decodedJWT = verifier.verify(token);
        } catch (JWTVerificationException exception){
            // Invalid signature/claims.
        }

        Signature signature1 = Signature.getInstance("SHA256WithRSA");
        //signature1.initVerify(publicKey);

        // String message = "z2c6l34OiHCRbdwHOhowjycqKhrM6HOBWcHOZXeNxHg5ACELiFfZDx8wNXKJVKQv";
        //byte[] messageBytes = authorization.getBytes("UTF8");
        //boolean result = signature1.verify(messageBytes);

        //if(result == true){
        //    return "Xac thuc ok";
        //}else {
        //    return "Xac thuc that bai";
        //}

        return "Xac thuc ok";
    }

}

我的错误

java.security.InvalidKeyException: IOException : algid parse error, not a sequence
    at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:350) ~[na:na]
    at java.base/sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:355) ~[na:na]
    at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:130) ~[na:na]
    at java.base/sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:80) ~[na:na]
    at java.base/sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:356) ~[na:na]
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:247) ~[na:na]
    at java.base/java.security.KeyFactory.generatePrivate(KeyFactory.java:390) ~[na:na]
    at ati.com.example.cryptology.CryptoUtils.readPrivateKeySecondWay(CryptoUtils.java:149) ~[classes/:na]

我使用的是Java 11。我尝试了4种方法,都是错误

readPublicKey()
readPrivateKey()
readPublicKeySecondApproach()
readPrivateKeySecondWay()

如何加载私钥/公钥(

jwtRSA256-private.pem
jwtRSA256-public.pem
)到Java对象(
RSAPrivateKey
RSAPublicKey
)成功?

java openssl rsa
© www.soinside.com 2019 - 2024. All rights reserved.