用于创建密钥库并将csr和密钥对附加到其中的JAVA API

时间:2016-10-31 21:09:08

标签: java security bouncycastle keytool csr

我需要将现有的csr和keypair附加到密钥库。下面给出了一个实现,它使用GUI(java swing)来获取用户的输入,例如密钥库名称,别名,公用名,组织等。

我尝试使用keystore.setkeyentry(...)将csr链接到密钥库,但密钥库仍为空。

我在下面附上了我的代码,任何帮助都非常有用:

以下代码用于创建csr

            public String getCSR(String cn, String ou, String o, String l,String s) throws Exception {
            byte[] csr = generatePKCS10(cn, ou, o, l,s,"US");

            return new String(csr);
        }


private static byte[] generatePKCS10(String CN, String OU, String O,
                String L, String S, String C) throws Exception {
            // generate PKCS10 certificate request
            String sigAlg = "MD5WithRSA";
            PKCS10 pkcs10 = new PKCS10(publicKey);
            Signature signature = Signature.getInstance(sigAlg);
            signature.initSign(privateKey);
            // common, orgUnit, org, locality, state, country
            X500Principal principal = new X500Principal( "CN=Ole Nordmann, OU=ACME, O=Sales, C=NO");

       //     pkcs10CertificationRequest kpGen = new PKCS10CertificationRequest(sigAlg, principal, publicKey, null, privateKey);  
         //   byte[] c = kpGen.getEncoded();  
            X500Name x500name=null;
            x500name= new X500Name(principal.getEncoded());
          pkcs10.encodeAndSign(x500name, signature);
            ByteArrayOutputStream bs = new ByteArrayOutputStream();
            PrintStream ps = new PrintStream(bs);
            pkcs10.print(ps);
            byte[] c = bs.toByteArray();
            try {
                if (ps != null)
                    ps.close();
                if (bs != null)
                    bs.close();
            } catch (Throwable th) {
            }
            return c;
        }


        public static X509Certificate generateX509Certificate(String certEntry) throws IOException {

            InputStream in = null;
            X509Certificate cert = null;
            try {
                byte[] certEntryBytes = certEntry.getBytes();
                in = new ByteArrayInputStream(certEntryBytes);
                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");

                cert = (X509Certificate) certFactory.generateCertificate(in);
            } catch (CertificateException ex) {

            } finally {
                if (in != null) {
                        in.close();
                }
            }
            return cert;
        }

在main方法中,我执行以下操作来创建密钥库并将其附加到csr

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());


                        char[] pass = password.toCharArray();
                        ks.load(null, pass);

                        ks.store(fos, pass);
                        fos.close();
                         GenerateCSR gcsr = GenerateCSR.getInstance();

                    System.out.println("Public Key:\n"+gcsr.getPublicKey().toString());

                    System.out.println("Private Key:\n"+gcsr.getPrivateKey().toString());

                    String csr = gcsr.getCSR(CN,OU,O,L,S);

                    System.out.println("CSR Request Generated!!");
                    System.out.println(csr);


                    X509Certificate[] certChain = new X509Certificate[1];
                 //   certChain[0]= gcsr.generateX509Certificate(csr);
                    X509Certificate myCert = (X509Certificate) CertificateFactory
                                                 .getInstance("X509")
                                                 .generateCertificate(
                                                    // string encoded with default charset
                                                    new ByteArrayInputStream(csr.getBytes())
                                                 ); 
                    certChain[0]= myCert;
                    ks.setKeyEntry("alias", (Key)gcsr.getPrivateKey(), pass, certChain);

当我检查密钥库的内容时,它是空的。 任何建议将不胜感激

谢谢!!!

1 个答案:

答案 0 :(得分:1)

你有两个主要错误

  • 证书签名请求又名 CSR又称PKCS10不是证书CertificateFactory.generateCertificate只会读取证书而不是CSR,当您向它提供CSR时,它会抛出一个异常,您的代码会巧妙地抑制它,并且没有任何迹象表明存在严重问题。您之前修订版中的注释掉的代码更接近于生成证书所需的代码。

  • (如果您确实创建/拥有有效证书)KeyStore.set*仅在内存中的KeyStore对象中设置条目。如果您希望在程序退出后将密钥库内容保存在文件中的某个位置,则必须store在执行'设置'(s)后必须//--

这是你的代码修改得足够好,因为我相信你想要的。除了琐碎的格式和脚手架之外,我更改的点标记为//**标记为删除,sun.security标记为添加。即便如此,我也不推荐它,因为:

  • 我继续使用不受支持的X509V3CertificateGenerator类,即使您使用BC并且它支持PKCS10及相关位的类,只有在您想要申请证书时才需要CSR来自CA;

  • ,直接生成证书就可以直接生成证书 最近版本的BC pkix中的
  • (不太严重)已被拆分为一个单独的jar并且X509v3CertificateBuilder现已弃用,以支持//nopackage import java.io.*; import java.math.BigInteger; import java.security.*; import java.security.cert.*; import java.util.*; import javax.security.auth.x500.*; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.x509.X509V3CertificateGenerator; //--import sun.security.pkcs.PKCS10; -- Java7 import sun.security.pkcs10.PKCS10; //** Java8 import sun.security.x509.X500Name; public class SO40350607GenerateCertIntoKeystoreFile8 { public static void main (String[] args) throws Exception { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); //**dummy value for test KeyPairGenerator kpgen = KeyPairGenerator.getInstance("RSA"); kpgen.initialize(1024); keyPair = kpgen.generateKeyPair(); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); char[] pass = "password".toCharArray(); ks.load(null, pass); //--ks.store(fos, pass); useless here //--fos.close(); String csr = new String(generatePKCS10("CommonName","OrgUnit","Org","Locality","State", "US")); System.out.println("CSR Request Generated!!"); System.out.println(csr); //--X509Certificate myCert = (X509Certificate) CertificateFactory.getInstance("X509") //-- .generateCertificate(new ByteArrayInputStream(csr.getBytes()) ); // string encoded with default charset*/ X509Certificate myCert = generateCertificate2 (csr); //** X509Certificate[] certChain = new X509Certificate[]{myCert}; ks.setKeyEntry("alias", keyPair.getPrivate(), pass, certChain); FileOutputStream fos = new FileOutputStream ("newksfile"); ks.store(fos,pass); fos.close(); //** NOW store to file } private static KeyPair keyPair; private static byte[] generatePKCS10(String CN, String OU, String O, String L, String S, String C) throws Exception { // generate PKCS10 certificate request String sigAlg = "SHA1WithRSA"; //** don't use "MD5WithRSA" even for CSR PKCS10 pkcs10 = new PKCS10(keyPair.getPublic()); Signature signature = Signature.getInstance(sigAlg); signature.initSign(keyPair.getPrivate()); // common, orgUnit, org, locality, state, country //--X500Principal principal = new X500Principal( "CN=Ole Nordmann, OU=ACME, O=Sales, C=NO"); //--X500Name x500name= new X500Name(principal.getEncoded()); //** can do this directly (and better) X500Name x500name = new X500Name ("CN="+CN+",OU="+OU+",O="+O+",L="+L+",S="+S+",C="+C); pkcs10.encodeAndSign(x500name, signature); ByteArrayOutputStream bs = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(bs); pkcs10.print(ps); byte[] c = bs.toByteArray(); ps.close(); //** bs,ps are never null, ps.close automatically closes underlying bs, //** and anyway BAOS doesn't need to be closed (although most streams do) return c; } //** (whole) routine to generate an actual (though selfsigned) certificate public static X509Certificate generateCertificate2 (String csrpem) throws Exception { String csrtrim = csrpem.replaceAll("-----[^\\n]*\\n","").replaceAll("\\r?\\n",""); //--PKCS10 pkcs10 = new PKCS10 (Base64.decode (csrtrim.toCharArray())); --Java7 PKCS10 pkcs10 = new PKCS10 (Base64.getDecoder().decode (csrtrim.getBytes())); //Java8 // or use the one we had before encoding it -- or the input data directly?? // X509V3CertificateGenerator is deprecated but stay with it for now X509V3CertificateGenerator cert = new X509V3CertificateGenerator(); cert.setSerialNumber(BigInteger.valueOf(1)); //or generate a random number cert.setSubjectDN(pkcs10.getSubjectName().asX500Principal()); cert.setIssuerDN(pkcs10.getSubjectName().asX500Principal()); //same since it is self-signed cert.setPublicKey(pkcs10.getSubjectPublicKeyInfo()); Date now = new Date(); cert.setNotBefore(now); now.setYear(now.getYear()+1); cert.setNotAfter(now); cert.setSignatureAlgorithm("SHA1WithRSA"); PrivateKey signingKey = keyPair.getPrivate(); return cert.generate(signingKey, "BC"); } }

IF OBJECT_ID ( 'dbo.sp_PreviousAcitivites', 'P' ) IS NOT NULL   
DROP PROCEDURE dbo.sp_PreviousAcitivites;  
GO  
CREATE PROCEDURE dbo.sp_PreviousAcitivites   
@StartPoint nvarchar(50)
AS   

SET NOCOUNT ON;  

DECLARE @lastResult TABLE (document_id VARCHAR(30), document_name VARCHAR(100), direction VARCHAR(1), process_step_id VARCHAR(30), process_step VARCHAR(100))
DECLARE @collectedResult TABLE (document_id VARCHAR(30), document_name VARCHAR(100), direction VARCHAR(1), process_step_id VARCHAR(30), process_step VARCHAR(100))
DECLARE @nextDirection VARCHAR(1)
DECLARE @nextSelectionID VARCHAR(30)
DECLARE @maxResultCount INT
DECLARE @resultCount INT

SET @maxResultCount=50
SET @resultCount=0
SET @nextDirection='I'
SET @nextSelectionID=@StartPoint

INSERT INTO @lastResult
SELECT TOP 1 document_id, document_name, direction, process_step_id, process_step  
FROM [document_to_process] 
WHERE process_step_id=@nextSelectionID
AND direction=@nextDirection 

WHILE EXISTS(SELECT 1 FROM @lastResult) AND @resultCount < @maxResultCount
BEGIN

    IF @nextDirection='I' 
    BEGIN
        SELECT @nextSelectionID=process_step_id FROM @lastResult

        DELETE FROM @lastResult

        INSERT INTO @lastResult
        SELECT TOP 1 document_id, document_name, direction, process_step_id, process_step  
        FROM [document_to_process] 
        WHERE process_step_id=@nextSelectionID
        AND direction=@nextDirection 

        SET @nextDirection='O' 
    END 
    ELSE 
    BEGIN
        SELECT @nextSelectionID=document_id FROM @lastResult

        DELETE FROM @lastResult

        INSERT INTO @lastResult
        SELECT TOP 1 document_id, document_name, direction, process_step_id, process_step  
        FROM [document_to_process] 
        WHERE document_id=@nextSelectionID
        AND direction=@nextDirection 

        SET @nextDirection='I' 
    END

    SET @resultCount=@resultCount+1

    INSERT INTO @collectedResult(document_id, document_name, direction, process_step_id, process_step) 
    SELECT document_id, document_name, direction, process_step_id, process_step FROM @lastResult
END

SELECT * FROM @collectedResult
GO

dbo.sp_PreviousAcitivites 'SE-SOP-53'