2013-10-16 31 views
6

這就是我現在生成的數字證書。現在我可以生成一個密碼爲私鑰保護的數字證書。使用BouncyCastle和Java生成X509Certificate

public static void main(String[] args) throws Exception { 
    Security.addProvider(new BouncyCastleProvider()); 
    testKeyStore(); 
} 

public static void testKeyStore() throws Exception { 
    try { 
     String storeName = "d://suresh_test.cer"; 
     java.security.KeyPairGenerator keyPairGenerator = KeyPairGenerator 
       .getInstance("RSA"); 
     keyPairGenerator.initialize(2048); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     PublicKey publicKey = keyPair.getPublic(); 
     PrivateKey privateKey = keyPair.getPrivate(); 
     X509Certificate trustCert = createCertificate("CN=CA", "CN=CA", 
       publicKey, privateKey); 
     java.security.cert.Certificate[] outChain = { 
       createCertificate("CN=Client", "CN=CA", publicKey, 
         privateKey), trustCert }; 
     KeyStore outStore = KeyStore.getInstance("PKCS12"); 
     outStore.load(null, "suresh_".toCharArray()); 
     outStore.setKeyEntry("mykey", privateKey, "suresh_".toCharArray(), 
       outChain); 
     OutputStream outputStream = new FileOutputStream(storeName); 
     outStore.store(outputStream, "suresh_".toCharArray()); 
     outputStream.flush(); 
     outputStream.close(); 

     KeyStore inStore = KeyStore.getInstance("PKCS12"); 
     inStore.load(new FileInputStream(storeName), 
       "suresh_".toCharArray()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw new AssertionError(e.getMessage()); 
    } 
} 

private static X509Certificate createCertificate(String dn, String issuer, 
     PublicKey publicKey, PrivateKey privateKey) throws Exception { 
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); 
    certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random() 
      .nextLong()))); 
    certGenerator.setIssuerDN(new X509Name(dn)); 
    certGenerator.setSubjectDN(new X509Name(dn)); 
    certGenerator.setIssuerDN(new X509Name(issuer)); // Set issuer! 
    certGenerator.setNotBefore(Calendar.getInstance().getTime()); 
    certGenerator.setNotAfter(Calendar.getInstance().getTime()); 
    certGenerator.setPublicKey(publicKey); 
    certGenerator.setSignatureAlgorithm("SHA1WithRSAEncryption"); 
    X509Certificate certificate = (X509Certificate) certGenerator.generate(
      privateKey, "BC"); 
    return certificate; 
} 

如何讓它自我簽名?

我沒有線索。

我該怎麼做?

感謝您的任何提示。

+1

你的問題並沒有解釋你已經做了什麼嘗試和解決問題;它目前的讀取方式類似於代碼請求。請分享您嘗試的實施方式,並解釋如何達不到您的要求。 –

+0

@DuncanJones嗯,我生成了證書。但不知道如何使用彈性城堡API來簽名,在他們的網站上沒有發現任何東西。謝謝您的幫助。 –

回答

4

您擁有生成自簽名證書所需的全部代碼。你只需要確保你的鏈只包含一個證書。

public static void testKeyStore() throws Exception { 
    try { 
    String storeName = "path/to/store"; 
    java.security.KeyPairGenerator keyPairGenerator = KeyPairGenerator 
     .getInstance("RSA"); 
    keyPairGenerator.initialize(2048); 
    KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
    PublicKey publicKey = keyPair.getPublic(); 
    PrivateKey privateKey = keyPair.getPrivate(); 
    X509Certificate selfCert = createCertificate("CN=Client", "CN=Client", 
     publicKey, privateKey); 

    // Note: if you just want to store this certificate then write the 
    // contents of selfCert.getEncoded() to file 

    java.security.cert.Certificate[] outChain = { selfCert }; 
    KeyStore outStore = KeyStore.getInstance("PKCS12"); 
    outStore.load(null, PASSWORD.toCharArray()); 
    outStore.setKeyEntry("mykey", privateKey, PASSWORD.toCharArray(), 
     outChain); 
    OutputStream outputStream = new FileOutputStream(storeName); 
    outStore.store(outputStream, PASSWORD.toCharArray()); 
    outputStream.flush(); 
    outputStream.close(); 

    KeyStore inStore = KeyStore.getInstance("PKCS12"); 
    inStore.load(new FileInputStream(storeName), PASSWORD.toCharArray()); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    throw new AssertionError(e.getMessage()); 
    } 
} 

我會建議你不要扔AssertionError。這應該只被Java本身用來表示assert陳述是錯誤的。

+1

謝謝瓊斯,一個小小的懷疑。 'outStore.load(null,PASSWORD.toCharArray());'和 'outStore.setKeyEntry(「mykey」,privateKey,PASSWORD.toCharArray(), outChain);'爲什麼我們使用的兩個密碼?密鑰庫文件是否需要?兩個密碼可以不同嗎? –

+0

@sᴜʀᴇsʜᴀᴛᴛᴀ首先,這些行在我的代碼示例中,因爲它們在您的原始代碼中。檢查'KeyStore'的文檔以瞭解它們的含義。 –

+0

是的,我也這樣做。 :) 謝謝您的幫助。如果你有時間,請看看這個。 http://stackoverflow.com/questions/19421571/providing-key-usage-to-x509certificate-generated-with-with-java-bouncycastle –

2

花了週末的時間將我們的BC版本從143改爲154後,我發佈了一些學習過的東西,希望能夠爲將來某個人節省一些時間。

1)來自BC的PKI eXtention API已被移至自己的jar中。我在bcprov-jdk15on-154.jar中突然找到PemParser。 PemParser的實現在bcpkix-jdk15on-154.jar中。不用說pkix jar取決於核心bc jar。

2)PEMReader類在最新的154版本中不可用。這已被PemParser取代。

3)從文件在磁盤上讀一本公證書:

Security.addProvider(new BouncyCastleProvider()); 
File file = new File("c:/mycert.crt"); 
X509Certificate cert = null; 
PEMParser pemParser = new PEMParser(new FileReader(file)); 
Object object = pemParser.readObject(); 
if (object instanceof X509CertificateHolder) { 
    X509CertificateHolder holder = (X509CertificateHolder)object; 
    cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder); 
} 
if (cert == null) { 
    throw new Exception("mycert.crt" + " doesn't contain X509Certificate!"); 
} 
return cert; 
//If you need publicKey use cert.getPublicKey() method. 

4)讀取密碼保護的私有密鑰從盤:

Security.addProvider(new BouncyCastleProvider()); 
KeyPair keyPair = null; 
File file = new File("c:/myprivate.key"); 
PEMParser pemParser = new PEMParser(new FileReader(file)); 
Object object = pemParser.readObject(); 
if (object instanceof PEMEncryptedKeyPair) { 
    JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); 
    PEMEncryptedKeyPair ckp = (PEMEncryptedKeyPair) object; 
    PEMDecryptorProvider decProv = 
      new JcePEMDecryptorProviderBuilder().build("strongpasswordfor_myprivate.key".toCharArray()); 
    keyPair = converter.getKeyPair(ckp.decryptKeyPair(decProv)); 
} 
return keyPair; 
//Once we have the keypair, we can get keyPair.getPrivate() [PrivateKey.class] 
//or keyPair.getPublic() [PublicKey.class] 

5)讀取基於字符串的證書,這是通常是我們想要進行SSL相互認證的情況,並讓Web服務器將客戶端證書轉發到Http Request Header中的應用服務器:

Security.addProvider(new BouncyCastleProvider()); 
X509Certificate cert = null; 
    String myClientCert = "-----BEGIN CERTIFICATE----- CERTCONTENTS -----END CERTIFICATE-----" 
    String cert1 = myClientCert.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", "").replaceAll(" ", System.lineSeparator()); 
    int ind = cert1.lastIndexOf(System.lineSeparator()); 
    cert1 = new StringBuilder(cert1).replace(ind, ind + System.lineSeparator().length(), "").toString(); 
    cert1 = BEGIN_CERT + cert1 + END_CERT; 
    PEMParser pemParser = new PEMParser(new StringReader(cert1)); 
    Object object = pemParser.readObject(); 
    if (object instanceof X509CertificateHolder) { 
     X509CertificateHolder holder = (X509CertificateHolder)object; 
     cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder); 
    } 
    return cert; 

6)不用說,添加錯誤處理,異常管理&清理你的口味。

相關問題