我需要将现有的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);
当我检查密钥库的内容时,它是空的。 任何建议将不胜感激
谢谢!!!
答案 0 :(得分:1)
你有两个主要错误:
证书签名请求又名 CSR又称PKCS10不是证书。 CertificateFactory.generateCertificate
只会读取证书而不是CSR,当您向它提供CSR时,它会抛出一个异常,您的代码会巧妙地抑制它,并且没有任何迹象表明存在严重问题。您之前修订版中的注释掉的代码更接近于生成证书所需的代码。
(如果您确实创建/拥有有效证书)KeyStore.set*
仅在内存中的KeyStore对象中设置条目。如果您希望在程序退出后将密钥库内容保存在文件中的某个位置,则必须store
在执行'设置'(s)后必须//--
。
这是你的代码修改得足够好,因为我相信你想要的。除了琐碎的格式和脚手架之外,我更改的点标记为//**
标记为删除,sun.security
标记为添加。即便如此,我也不推荐它,因为:
我继续使用不受支持的X509V3CertificateGenerator
类,即使您使用BC并且它支持PKCS10及相关位的类,只有在您想要申请证书时才需要CSR来自CA;
(不太严重)已被拆分为一个单独的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'