[英]Load certificate to KeyStore (JAVA)
我在將證書加載到密鑰存儲區時遇到問題。 我可以使用以下命令在控制台中創建該證書openssl pkcs12 -export -out cloudCA.p12 -inkey Cloud\\ privateLey.key -in cloudCa.pem -certfile rootCa.pem -name "cloudCA"
我想出了如何加載cloudCA.pem與privateKey.key,但我找不到方法如何在其中添加rootCA.pem。 這是我當前的代碼。 感謝幫助。
//Regular patterns for certificate.
private static final Pattern CERT_PATTERN = Pattern.compile(
"-+BEGIN\\s+.*CERTIFICATE[^-]*-+(?:\\s|\\r|\\n)+" + // Header
"([a-z0-9+/=\\r\\n]+)" + // Base64 text
"-+END\\s+.*CERTIFICATE[^-]*-+", // Footer
CASE_INSENSITIVE);
private static final Pattern KEY_PATTERN = Pattern.compile(
"-+BEGIN\\s+.*PRIVATE\\s+KEY[^-]*-+(?:\\s|\\r|\\n)+" + // Header
"([a-z0-9+/=\\r\\n]+)" + // Base64 text
"-+END\\s+.*PRIVATE\\s+KEY[^-]*-+", // Footer
CASE_INSENSITIVE);
public static KeyStore loadKeyStore(String certificate, String privateKey, Optional<String> keyPassword)
throws IOException, GeneralSecurityException {
List<X509Certificate> certificateChain = readCertificateChain(certificate);
if (certificateChain.isEmpty()) {
throw new CertificateException("Certificate file string does not contain any certificates: ");
}
//Load and customize key string to byte array.
byte[] data = Base64.getDecoder().decode(privateKey.replace("\n","")
.replace("-----BEGIN RSA PRIVATE KEY-----", "")
.replace("-----END RSA PRIVATE KEY-----", "")
.replace(" ", ""));
/* Add PKCS#8 formatting */
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(0));
ASN1EncodableVector v2 = new ASN1EncodableVector();
v2.add(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.rsaEncryption.getId()));
v2.add(DERNull.INSTANCE);
v.add(new DERSequence(v2));
v.add(new DEROctetString(data));
ASN1Sequence seq = new DERSequence(v);
byte[] privKey = seq.getEncoded("DER");
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privKey);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey key = fact.generatePrivate(spec);
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
keyStore.setKeyEntry("CloudCA", key, keyPassword.orElse("").toCharArray(), certificateChain.stream().toArray(Certificate[]::new));
return keyStore;
}
private static List<X509Certificate> readCertificateChain(String contents) throws GeneralSecurityException {
Matcher matcher = CERT_PATTERN.matcher(contents);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
List<X509Certificate> certificates = new ArrayList<>();
int start = 0;
while (matcher.find(start)) {
byte[] buffer = Base64.getMimeDecoder().decode(matcher.group(1).getBytes(US_ASCII));
certificates.add((X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(buffer)));
start = matcher.end();
}
return certificates;
}
首先,使用openssl pkcs12 -export
創建的PKCS12文件已經是Java密鑰庫; 盡管低於9的Java版本的密鑰庫默認為JKS格式,但它們也支持PKCS12,而現在的j9 up默認為PKCS12。 因此,您只需要使用PKCS12密鑰庫就可以了。 但是SO是關於編程的,因此根本不需要做任何事情的解決方案可能就沒必要了:)
如果您想要(或以某種方式需要)自己構建密鑰庫,並且在一個文件中擁有實體證書(如果顧名思義,實際上是一個從屬CA,並且直接在根目錄下),而在另一個文件中擁有根證書,則可以閱讀它們中的每一個都構成了鏈,例如:
// read privatekey, reformat to PKCS8 and process-in as you do now
CertificateFactory fact = CertificateFactory.getInstance("X.509");
InputStream file1 = new FileInputStream("mycert.pem"), file2 = new FileInputStream("rootcert.pem");
Certificate[] chain = { fact.generateCertificate(file1), fact.generateCertificate(file2) };
file1.close(); file2.close(); // or use try-with-resources
// if already in memory use ByteArrayInputStream's instead,
// and maybe don't bother closing
// basically unchanged
KeyStore keyStore = KeyStore.getInstance("JKS"); // or maybe "PKCS12" ?
keyStore.load(null, null);
keyStore.setKeyEntry("name", key, (keypass), chain);
// either use this keystore as is, or store it (to a file,
// or maybe somewhere else like a database) for later use
請注意,您不需要刪除PEM標頭/尾部並將自己轉換為base64即可, CertificateFactory
自上世紀以來一直能夠讀取PEM。 盡管如果你的PEM文件包含PEM塊,其中由文件創建的OpenSSL之前額外“注釋”信息經常這樣做,你需要一個相當新的Java版本(IIRC J6或J7可能)來處理 。
或者,如果您將證書串聯在一起(在文件或內存中),則可以使用CertificateFactory.generateCertificates
(請注意s)將它們都讀取到Collection
,然后將其轉換為數組。 同樣,這已經處理了PEM,因此您不必解析和轉換它。 請注意,您可以將Collection
或List
(如上面的代碼中一樣)直接轉換為數組,而無需先通過Stream
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.