KeyStore(譯:密鑰存儲庫) 代表用於加密密鑰和證書的存儲設施。 KeyStore 管理不同類型的 entry(譯:條目)。每種類型的 entry 都實現了 KeyStore.Entry 介面。提供了三個基本的 KeyStore.Entry 實現: KeyStore.PrivateKeyEnt ...
KeyStore(譯:密鑰存儲庫) 代表用於加密密鑰和證書的存儲設施。
KeyStore 管理不同類型的 entry(譯:條目)。每種類型的 entry 都實現了 KeyStore.Entry 介面。提供了三個基本的 KeyStore.Entry 實現:
KeyStore.PrivateKeyEntry
KeyStore.SecretKeyEntry
KeyStore.TrustedCertificateEntry
這種類型的 Entry 持有一個加密PrivateKey,可以選擇以受保護的格式存儲,以防止未經授權的訪問。它還伴隨著對應的公鑰的證書鏈。私鑰和證書鏈由給定實體用於自我身份驗證。這種身份驗證的應用程式包括軟體分發組織,它們將JAR文件作為發佈和/或許可軟體的一部分進行簽名。
這種類型的 Entry 持有一個加密的SecretKey,它可以選擇以受保護的格式存儲,以防止未經授權的訪問。
這種類型的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);
}
}