2009-11-29 127 views
0

這已問過幾次,但都沒有提供編碼測試用例。在這裏,我給這個問題的一個例子:Java:通過代碼生成時無效的密鑰庫格式

  1. 程序生成一個密鑰存儲的(作品)
  2. 那家商店(工程)中創建證書的
  3. 保存密鑰存儲到磁盤(作品)
  4. 上市密鑰庫與密鑰工具(作品)
  5. 程序加載密鑰庫(失敗IOException異常:InvalidKeystoreFormat)

什麼我不摹et是在保存和加載中,我使用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; 
    } 
} 

回答

2

1)創建在當前工作目錄中的私有密鑰存儲,通過寫入文件new FileOutputStream(fPrivateKeyStore);

2)以後,您從類路徑使用getClass().getClassLoader().getResourceAsStream(fPrivateKeyStore);

讀我認爲你正在閱讀錯誤的文件。而且之前的測試中已經有另外一個名字爲private.keystore。爲了驗證,你可能想打印出兩個文件的絕對文件路徑,例如new File(fPrivateKeyStore).getAbsolutePath()並將其比較getClass().getClassLoader().getResource(fPrivateKeyStore).toFileURL();

+0

OMG,我怎麼錯過了。謝謝,現在都很好。 – javahollic 2009-11-29 21:53:29

0

我可能失去了一些東西,但爲什麼不只是重新加載使用FileInputStream的私有密鑰存儲?

InputStream reloadedIs = new FileInputStream(fPrivateKeyStore); 

(我不能肯定這能解決問題,我只注意到它,而掃描代碼)