從 KeyStore 中獲取 PublicKey 和 PrivateKey


KeyStore(譯:密鑰存儲庫) 代表用於加密密鑰和證書的存儲設施。

KeyStore 管理不同類型的 entry(譯:條目)。每種類型的 entry 都實現了 KeyStore.Entry 接口。提供了三個基本的 KeyStore.Entry 實現:

  • KeyStore.PrivateKeyEntry

  • 這種類型的 Entry 持有一個加密PrivateKey,可以選擇以受保護的格式存儲,以防止未經授權的訪問。它還伴隨着對應的公鑰的證書鏈。私鑰和證書鏈由給定實體用於自我身份驗證。這種身份驗證的應用程序包括軟件分發組織,它們將JAR文件作為發布和/或許可軟件的一部分進行簽名。

  • KeyStore.SecretKeyEntry

  • 這種類型的 Entry 持有一個加密的SecretKey,它可以選擇以受保護的格式存儲,以防止未經授權的訪問。

  • KeyStore.TrustedCertificateEntry

  • 這種類型的Entry包含一個屬於另一方的公鑰證書。它被稱為受信任的證書,因為密鑰存儲庫所有者信任證書中的公鑰確實屬於證書的主體(所有者)標識的身份。這種類型的Entry可用於對其他方進行身份驗證。

KeyStore 中的每個 Entry 都由一個“alias”字符串標識。對於私鑰及其關聯的證書鏈,這些字符串區分實體對自身進行身份驗證的不同方式。例如,實體可以使用不同的證書頒發機構或使用不同的公鑰算法對自己進行身份驗證。

這里沒有指定密鑰存儲庫是否持久,以及密鑰存儲庫使用的機制(如果它是持久的)。

請求KeyStore對象的典型方法包括依賴默認類型和提供特定的KeyStore類型:

  • 依賴默認類型:

  • KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
  • 提供特定的密鑰存儲庫類型:

  • KeyStore ks = KeyStore.getInstance("JKS");

在訪問密鑰存儲庫之前,必須先加載它。

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

// get user password and file input stream
char[] password = getPassword();

try (FileInputStream fis = new FileInputStream("keyStoreName")) {
  ks.load(fis, password);
}

為了用上面的方法創建一個空的 KeyStore(密鑰存儲庫),可以傳遞null作為InputStream參數。

一旦加載了密鑰存儲庫,就可以從密鑰存儲庫中讀取現有條目,或者將新條目寫入密鑰存儲庫:

KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(password);

// get my private key
KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("privateKeyAlias", protParam);
PrivateKey myPrivateKey = pkEntry.getPrivateKey();

// save my secret key
javax.crypto.SecretKey mySecretKey;
KeyStore.SecretKeyEntry skEntry = new KeyStore.SecretKeyEntry(mySecretKey);
ks.setEntry("secretKeyAlias", skEntry, protParam);

// store away the keystore
try (FileOutputStream fos = new FileOutputStream("newKeyStoreName")) {
   ks.store(fos, password);
}

注意,盡管可以使用相同的密碼加載keystore、保護private key entry、保護secret key entry和存儲keystore(如上面的示例代碼所示),但也可以使用不同的密碼或其他保護參數。

更多請參見 java.security.KeyStore

下面,演示一下

首先,生成一個密鑰文件

keytool -genkeypair -alias soas -keypass 123456 -keyalg RSA -storepass 123456 -keysize 1024 -validity 3650 -keystore F:/soas.jks

加載keystore

//  創建KeyStore
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
KeyStore ks2 = KeyStore.getInstance("JKS");

//  加載KeyStore
InputStream is = new ClassPathResource("keyStoreName").getInputStream();
ks.load(is, "storepass".toCharArray());

FileInputStream fis = new FileInputStream("keyStoreName");
ks.load(is, "storepass".toCharArray());

//  獲取PrivateKey/PublicKey(方式一)
KeyStore.ProtectionParameter protectionParameter = new KeyStore.PasswordProtection("keypass".toCharArray());
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("alias", protectionParameter);

PrivateKey myPrivateKey = privateKeyEntry.getPrivateKey();
PublicKey myPublicKey = privateKeyEntry.getCertificate().getPublicKey();

System.out.println(myPrivateKey);
System.out.println(myPublicKey);

//  獲取PrivateKey/PublicKey(方式二)
PrivateKey myPrivateKey2 = (PrivateKey) ks.getKey("alias", "keypass".toCharArray());
PublicKey myPublicKey2 = ks.getCertificate("alias").getPublicKey();

System.out.println(myPrivateKey2);
System.out.println(myPublicKey2);

補充:生成token

package com.soa.supervision.portal.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.List;

/**
 * @Author ChengJianSheng
 * @Date 2022/5/14
 */
@Slf4j
public class RSAUtils {

    private static final Logger logger = LoggerFactory.getLogger(RSAUtils.class);
    private static final String CLAIM = "user";

    public static RSAPublicKey rsaPublicKey;
    private static RSAPrivateKey rsaPrivateKey;

    static {
        try {
//            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
//            keyPairGenerator.initialize(2048);
//            KeyPair keyPair = keyPairGenerator.generateKeyPair();
//            publicKey = (RSAPublicKey) keyPair.getPublic();
//            privateKey = (RSAPrivateKey) keyPair.getPrivate();


            KeyStore keyStore = KeyStore.getInstance("JKS");
            InputStream is = new ClassPathResource("soas.jks").getInputStream();
            keyStore.load(is, "123456".toCharArray());
            is.close();
            PrivateKey privateKey = (PrivateKey) keyStore.getKey("soas", "123456".toCharArray());
            PublicKey publicKey = keyStore.getCertificate("soas").getPublicKey();

            rsaPrivateKey = (RSAPrivateKey) privateKey;
            rsaPublicKey = (RSAPublicKey)publicKey;

        } catch (NoSuchAlgorithmException | KeyStoreException | IOException | CertificateException | UnrecoverableKeyException e) {
            logger.error("生成密鑰對失敗!原因: {}", e.getMessage(), e);
        }
    }

    public static String createToken(String name, Integer userId, List
  
  
  
          
            authorities) { Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, rsaPrivateKey); String token = JWT.create() .withClaim(CLAIM, name) .withClaim("userId", userId) .withClaim("authorities", authorities) .sign(algorithm); return token; } public static Claim parseToken(String token) { Algorithm algorithm = Algorithm.RSA256(rsaPublicKey, rsaPrivateKey); JWTVerifier verifier = JWT.require(algorithm).build(); DecodedJWT jwt = verifier.verify(token); return jwt.getClaim(CLAIM); } } 
          


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM