Java : 코드를 통해 생성 될 때 유효하지 않은 Keystore 형식
-
08-07-2019 - |
문제
이것은 몇 번 요청되었지만 코딩 된 테스트 사례를 제공하는 것은 없습니다. 여기서는 문제의 예를 제시합니다.
- Keystore (Works)의 프로그래밍 방식 생성
- 해당 상점 내 인증서 작성 (Works)
- 키 스토어 저장 디스크 (작업)
- KeyTool (Works)과 Keystore 목록
- KeyStore를 프로그래밍 방식으로로드 (IOException으로 실패 : InvalidKeyStoreFormat)
내가 얻지 못하는 것은 저장과로드 모두에서 사용한다는 것입니다. keystore.getInstance ( "jks"), 그러나 실패합니다. 모든 제안을 환영합니다!
런타임 출력 :
Creating private keystore at 'private.keystore'. Created keystore, now created signer cert Created signer cert, saving cert Reloading keystore: Failed to load the keystore after creation: Invalid keystore format
테스트 케이스 출처 :
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.security.InvalidKeyException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import sun.security.x509.X500Name; public class KeystoreCreator { private String fPrivateKeyStore; private String fPrivateKeyStorePassword; private String fPrivateKeyStoreKeyPassword; private String fPublicKeyCipherPassword; private String fPrivateKeyAlias; /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { KeystoreCreator creator = new KeystoreCreator(); creator.setPrivateKeyStore("private.keystore"); creator.setPrivateKeyStorePassword("beer123"); creator.setPrivateKeyAlias("myalias"); creator.setPrivateKeyStoreKeyPassword("beer123"); creator.setPublicKeyCipherPassword("beer123"); creator.initKeyStores(); } public KeystoreCreator() { } public void setPrivateKeyStore(String name) { fPrivateKeyStore=name; } public void setPrivateKeyStorePassword(String pass) { fPrivateKeyStorePassword=pass; } public void setPrivateKeyStoreKeyPassword(String pass) { fPrivateKeyStoreKeyPassword=pass; } public void setPublicKeyCipherPassword(String pass) { fPublicKeyCipherPassword=pass; } public void setPrivateKeyAlias(String alias) { fPrivateKeyAlias=alias; } public void initKeyStores() throws Exception { OutputStream out = null; File f=new File(fPrivateKeyStore); if (f.exists()) { f.delete(); if (f.exists()) { throw new IOException("Want to remove the keystore but can't, still reported as present after removal"); } } try { System.out.println("Creating private keystore at '" + fPrivateKeyStore + "'."); out = new FileOutputStream(fPrivateKeyStore); KeyStore privateKeyStore = KeyStore.getInstance("JKS"); privateKeyStore.load(null, fPrivateKeyStorePassword.toCharArray()); System.out.println("Created keystore, now created signer cert"); X500Name x500name=getCA(); Certificate cert = createCertificate(fPrivateKeyAlias, fPrivateKeyStoreKeyPassword, x500name, privateKeyStore); System.out.println("Created signer cert, saving cert"); privateKeyStore.store(out, fPublicKeyCipherPassword.toCharArray()); out.flush(); out.close(); //try to load it. KeyStore reloadedKeyStore = KeyStore.getInstance("JKS"); try { InputStream reloadedIs=getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore); if (reloadedIs!=null) { System.out.println("Reloading keystore:"); reloadedKeyStore.load(reloadedIs, fPrivateKeyStorePassword.toCharArray()); } } catch (Exception e) { System.err.println("Failed to load the keystore after creation: "+e.getLocalizedMessage()); } } catch (Exception e) { System.err.println("Failed to save the keystore: "+e.getLocalizedMessage()); } } private X500Name getCA() throws IOException { return new sun.security.x509.X500Name("a","b", "c","d","e", "GB"); } public Certificate createCertificate( String alias, String keyPassword, sun.security.x509.X500Name x500Name, KeyStore keyStore ) throws NoSuchAlgorithmException, InvalidKeyException, CertificateException, SignatureException, NoSuchProviderException, KeyStoreException { sun.security.x509.CertAndKeyGen keypair = new sun.security.x509.CertAndKeyGen( "RSA", "MD5WithRSA" ); keypair.generate( 1024 ); PrivateKey privKey = keypair.getPrivateKey(); X509Certificate[] chain = new X509Certificate[1]; chain[0] = keypair.getSelfCertificate( x500Name, 7000 * 24 * 60 * 60 ); keyStore.setKeyEntry( alias, privKey, keyPassword.toCharArray(), chain ); Certificate cert = keyStore.getCertificate( alias ); return cert; } }
해결책
1) 현재 작업 디렉토리에서 개인 키 스토어를 만듭니다. 파일에 쓰기: new FileOutputStream(fPrivateKeyStore);
2) 나중에, 당신 수업 경로에서 읽으십시오 사용하여 getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);
잘못된 파일을 읽고 있다고 생각합니다. 그리고 이미 이름이있는 또 다른 것이 있습니다 private.keystore
이전 테스트에서. 확인하려면 두 파일의 절대 파일 경로를 인쇄 할 수 있습니다. new File(fPrivateKeyStore).getAbsolutePath()
그리고 그것을 비교하십시오 getClass().getClassLoader().getResource(fPrivateKeyStore).toFileURL();
다른 팁
나는 무언가를 놓치고 있을지 모르지만 왜 개인 키 스토어를 다시로드하지 마십시오. FileInputStream
?
InputStream reloadedIs = new FileInputStream(fPrivateKeyStore);
(이것이 문제를 해결하는 것이 확실하지 않습니다. 코드를 스캔하는 동안 방금 발견했습니다)
제휴하지 않습니다 StackOverflow