2009-05-29 20 views
11

के साथ प्रमाण पत्र, सार्वजनिक और निजी कुंजी जेनरेट करें, मैं तीसरे पक्ष के कार्यक्रमों (जैसे ओपनएसएल) का उपयोग किये बिना फ्लाई पर प्रमाण पत्र, सार्वजनिक और निजी कुंजी उत्पन्न करने के लिए जावा लाइब्रेरी या कोड ढूंढ रहा हूं।जावा

मुझे कुछ ऐसा लगता है जो कि keytool + openssl को कर रहा है लेकिन जावा कोड से।

एसएसएल और क्लाइंट प्रमाणीकरण के साथ सुरक्षित जावा सर्वलेट आधारित वेब एप्लिकेशन पर विचार करें। मैं चाहता हूं कि सर्वलेट कंटेनर केवल जावा कोड के साथ अनुरोध पर क्लाइंट प्रमाणपत्र (उदाहरण के लिए pkcs12 प्रारूप) उत्पन्न करे।

धन्यवाद, पीटर।

+0

वैकल्पिक रूप से आप सिर्फ सन जावा Keytool वर्ग आह्वान और जरूरत मापदंडों प्रदान कर सकता है प्रमाण पत्र उत्पन्न करने के लिए। लेकिन इन वर्गों com.sun * पैकेज में हैं और संभावित रूप से बदल जाएंगे। सिद्धांत रूप में जावा में अपने प्रमाण पत्र जेनरेट करने के लिए सबकुछ मौजूद है, लेकिन यह सार्वजनिक रूप से उपलब्ध नहीं है। –

उत्तर

4

Bouncy Castle crypto libraries काफी व्यापक हैं।

+2

अरघ, मेरे पास यह पुस्तकालय मेरे हाथों में था और मुझे याद नहीं आया धन्यवाद! – PeterMmm

9

आप एक जोड़ी या चाबियों का उपयोग कर जावा में गतिशील रूप से प्रमाणपत्र उत्पन्न कर सकते हैं। (सार्वजनिक कुंजी, निजी कुंजी)। इन कुंजी को BigInteger प्रारूप के रूप में प्राप्त करें और प्रमाणपत्र उत्पन्न करने के लिए निम्न कोड जांचें।

RSAPrivateKeySpec serPrivateSpec = new RSAPrivateKeySpec(
    new BigInteger(val of pub key), new BigInteger(val of pri key)); 
fact = KeyFactory.getInstance("RSA"); 
PrivateKey serverPrivateKey = fact.generatePrivate(serPrivateSpec); 

RSAPublicKeySpec serPublicSpec = new RSAPublicKeySpec(
    new BigInteger(agentCL.getSerPubMod()), new BigInteger(agentCL.getSerPubExp())); 
PublicKey serverPublicKey = fact.generatePublic(serPublicSpec); 

keyStore = KeyStore.getInstance(IMXAgentCL.STORE_TYPE); 
keyStore.load(null, SOMEPWD.toCharArray()); 

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 

X509Certificate[] serverChain = new X509Certificate[1]; 
X509V3CertificateGenerator serverCertGen = new X509V3CertificateGenerator(); 
X500Principal serverSubjectName = new X500Principal("CN=OrganizationName"); 
serverCertGen.setSerialNumber(new BigInteger("123456789")); 
// X509Certificate caCert=null; 
serverCertGen.setIssuerDN(somename); 
serverCertGen.setNotBefore(new Date()); 
serverCertGen.setNotAfter(new Date()); 
serverCertGen.setSubjectDN(somename); 
serverCertGen.setPublicKey(serverPublicKey); 
serverCertGen.setSignatureAlgorithm("MD5WithRSA"); 
// certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,new 
// AuthorityKeyIdentifierStructure(caCert)); 
serverCertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, 
    new SubjectKeyIdentifierStructure(serverPublicKey)); 
serverChain[0] = serverCertGen.generateX509Certificate(serverPrivateKey, "BC"); // note: private key of CA 

keyStore.setEntry("xyz", 
    new KeyStore.PrivateKeyEntry(serverPrivateKey, serverChain), 
    new KeyStore.PasswordProtection("".toCharArray())); 

आशा है कि यह आपकी मदद करेगा।

+1

केवल बाउंसी कैसल जेएसएसई प्रदाता जोड़कर, जो आप आपके उत्तर में उल्लेख नहीं किया है। – EJP

3

विरासत चेतावनी शुरू:

  • इस कोड को केवल CommonName/सीएन/विषय सेट।
  • सही स्थान अब विषय AltName है।

Chrome Deprecates Subject CN Matching से:

क्रोम 58 की आवश्यकता होगी कि प्रमाण पत्र होस्ट नाम (रों) जो वे SubjectAltName क्षेत्र में लागू करने के लिए निर्दिष्ट; विषय फ़ील्ड में मानों पर ध्यान नहीं दिया जाएगा। "

विरासत चेतावनी समाप्ति

import java.io.FileOutputStream; 
import java.security.KeyStore; 
import java.security.PrivateKey; 
import java.security.cert.X509Certificate; 
import java.util.Date; 

import sun.security.x509.CertAndKeyGen; 
import sun.security.x509.X500Name; 

public class UseKeyTool { 

    private static final int keysize = 1024; 
    private static final String commonName = "www.test.de"; 
    private static final String organizationalUnit = "IT"; 
    private static final String organization = "test"; 
    private static final String city = "test"; 
    private static final String state = "test"; 
    private static final String country = "DE"; 
    private static final long validity = 1096; // 3 years 
    private static final String alias = "tomcat"; 
    private static final char[] keyPass = "changeit".toCharArray(); 

    // copied most ideas from sun.security.tools.KeyTool.java 

    @SuppressWarnings("restriction") 
    public static void main(String[] args) throws Exception { 

     KeyStore keyStore = KeyStore.getInstance("JKS"); 
     keyStore.load(null, null); 

     CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null); 

     X500Name x500Name = new X500Name(commonName, organizationalUnit, organization, city, state, country); 

     keypair.generate(keysize); 
     PrivateKey privKey = keypair.getPrivateKey(); 

     X509Certificate[] chain = new X509Certificate[1]; 

     chain[0] = keypair.getSelfCertificate(x500Name, new Date(), (long) validity * 24 * 60 * 60); 

     keyStore.setKeyEntry(alias, privKey, keyPass, chain); 

     keyStore.store(new FileOutputStream(".keystore"), keyPass); 



    } 
} 
+1

DNS नाम 'सामान्य नाम' में नहीं होने चाहिए * (मान लीजिए कि यह उपर्युक्त कोड में जोड़ा जाना चाहिए)। अभ्यास आईईटीएफ और सीए/ब्राउज़र मंच दोनों द्वारा बहिष्कृत किया गया है। DNS नामों को 'subjectAltNames' में जाना होगा, लेकिन कोड में इसकी कमी है। – jww

+1

DigiCert असहमत प्रतीत होता है: "https://www.example.com को सुरक्षित करने के लिए, आपका सामान्य नाम www.example.com या * .example.com को वाइल्डकार्ड प्रमाण पत्र के लिए होना चाहिए।" https://www.digicert.com/easy-csr/keytool.htm –

+0

देखें [आरएफसी 6125] (http://tools.ietf.org/html/rfc6125), खंड 6.4.4 या सीए/ब्राउज़र [ बेसलाइन सुरक्षा आवश्यकताएं] (https://cabforum.org/wp-content/uploads/Baseline_Requirements_V1_1_9.pdf), खंड 9.2.2। DidgiCert को बेहतर पता होना चाहिए क्योंकि वे [सीए/बी] के सदस्य हैं (https://cabforum.org/members/)। – jww