Hello.
(1)I made PKCS10 Certification request by using chap 6. PKCS10CertRequestExample.(it was modified to generate the file pkcs10.req)
(2)and then, I create Certificate by using chap 6. PKCS10CERTCreateExample
(it was also modified to generate the file pkcs10.pem, the certificate)
(3)At last, I would like to sign a message through the pkcs10.pem, thus I modified the chap 9. SignedMailExample class BUT, it shows exceptions as follows.
-----------------------
Exception in thread "main" java.security.cert.CertPathBuilderException: Unable to find certificate chain.
at org.bouncycastle.jce.provider.PKIXCertPathBuilderS pi.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
at chapter9.Utils.buildPath(Utils.java:63)
at chapter9.SignedDataProcessor.isValid(SignedDataPro cessor.java:64)
at chapter9.SignedMailExample.main(SignedMailExample. java:102)
-----------------------
it seems to be lack of CertPath, but I don't know how to add the CertPath in the certificate.
code (1)
Code:
//import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.OutputStreamWriter;
//import java.io.PrintWriter;
//import java.io.StringWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.openssl.PEMWriter;
//import org.bouncycastle.util.encoders.Base64;
import chapter6.PKCS10ExtensionExample;
public class PKCS10CRexample
{
public static PKCS10CertificationRequest generateRequest(
KeyPair pair)
throws Exception
{
return new PKCS10CertificationRequest(
"SHA256withRSA",
new X500Principal("CN=Requested Test Certificate"),
pair.getPublic(),
null,
pair.getPrivate());
}
public static void pemEncodeToFile(String filename, Object obj, char[] password) throws Exception{
PEMWriter pw = new PEMWriter(new FileWriter(filename));
if (password != null && password.length > 0) {
pw.writeObject(obj, "DESEDE", password, new SecureRandom());
} else {
pw.writeObject(obj);
}
pw.flush();
pw.close();
}
public static void main(String[] args) throws Exception
{
//create the keys
/*
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");
//KeyPairGenerator kpGen = KeyPairGenerator.getInstance()
kpGen.initialize(512, chapter4.Utils.createFixedRandom());
KeyPair pair=kpGen.generateKeyPair();
*/
//PKCS10CertificationRequest request = generateRequest(pair);
KeyPair pair = chapter8.Utils.generateRSAKeyPair();
//PKCS10CertificationRequest request = PKCS10ExtensionExample.generateRequest(pair);
PKCS10CertificationRequest request = PKCS10ExtensionExample.generateRequest(pair);
//System.out.println(request);
//KeyPair pair = chapter6.Utils.generateRSAKeyPair();
//PKCS10CertificationRequest request = generateRequest(pair);
pemEncodeToFile("pkcs10.req", request, null);
PEMWriter pemWrt = new PEMWriter( new OutputStreamWriter(System.out));
pemWrt.writeObject(request);
pemWrt.close();
/////
/////
////
//FileOutputStream fOut = new FileOutputStream("pkcs10.req");
//fOut.write((request.getEncoded()));
//fOut.write(sw.toString());
//fOut.close();
//pemWrt.close();
}
}
code (2)
Code:
import java.io.FileInputStream;
//import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.pkcs.Attribute;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Extension;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.openssl.PEMReader;
import org.bouncycastle.openssl.PEMWriter;
//import org.bouncycastle.util.encoders.Base64Encoder;
//import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
//import chapter6.PKCS10ExtensionExample;
import chapter6.X509V1CreateExample;
//example of a basic CA
public class PKCS10CertCreateExample
{
public static X509Certificate[] buildChain() throws Exception
{
//create the certification request
//KeyPair pair = chapter7.Utils.generateRSAKeyPair();
//PKCS10CertificationRequest request = PKCS10ExtensionExample.generateRequest(pair);
//System.out.println(request);
//Read the certificate request(parse the request)
//System.out.println(System.getProperty("user.dir"));
PEMReader pRd = new PEMReader(
new InputStreamReader(
new FileInputStream("pkcs10.req")));
PKCS10CertificationRequest request = (PKCS10CertificationRequest)pRd.readObject();
//create a root certificate
KeyPair rootPair=chapter6.Utils.generateRSAKeyPair();
X509Certificate rootCert = X509V1CreateExample.generateV1Certificate(rootPair);
//validate the certification request
if(!request.verify("BC"))
{
System.out.println("request failed to verify!");
System.exit(1);
}
//create the certificate using the information in the request
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
certGen.setIssuerDN(rootCert.getSubjectX500Principal());
certGen.setNotBefore(new Date(System.currentTimeMillis()));
certGen.setNotAfter(new Date(System.currentTimeMillis()+50000));
certGen.setSubjectDN(request.getCertificationRequestInfo().getSubject());
certGen.setPublicKey(request.getPublicKey("BC"));
certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");
certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(rootCert));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(request.getPublicKey("BC")));
certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));
//certGen.addExtension(X509Extensions.KeyUsage, true, new BasicConstraints(false));
certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));
//extract the extension request attribute
ASN1Set attributes = request.getCertificationRequestInfo().getAttributes();
for(int i=0;i!=attributes.size();i++)
{
Attribute attr = Attribute.getInstance(attributes.getObjectAt(i));
//process extension request
if(attr.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest))
{
X509Extensions extensions = X509Extensions.getInstance(attr.getAttrValues().getObjectAt(0));
Enumeration<?> e = extensions.oids();
while(e.hasMoreElements())
{
DERObjectIdentifier oid = (DERObjectIdentifier)e.nextElement();
X509Extension ext = extensions.getExtension(oid);
certGen.addExtension(oid, ext.isCritical(), ext.getValue().getOctets());
}
}
}
X509Certificate issuedCert = certGen.generateX509Certificate(rootPair.getPrivate());
return new X509Certificate[]{issuedCert, rootCert};
}
public static void pemEncodeToFile(String filename, Object obj, char[] password) throws Exception{
PEMWriter pw = new PEMWriter(new FileWriter(filename));
if (password != null && password.length > 0) {
pw.writeObject(obj, "DESEDE", password, new SecureRandom());
} else {
pw.writeObject(obj);
}
pw.flush();
pw.close();
}
public static void main(String[] args) throws Exception
{
X509Certificate[] chain = buildChain();
PEMWriter pemWrt = new PEMWriter(new OutputStreamWriter(System.out));
pemWrt.writeObject(chain[0]);
pemEncodeToFile("pkcs10.pem", chain[0], null);
pemWrt.close();
}
}
code (3)
Code:
package chapter9;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.*;
import java.util.Arrays;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.cms.AttributeTable;
import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;
import org.bouncycastle.asn1.smime.SMIMECapability;
import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
import org.bouncycastle.asn1.smime.SMIMEEncryptionKeyPreferenceAttribute;
import org.bouncycastle.jce.PKCS10CertificationRequest;
import org.bouncycastle.mail.smime.SMIMESigned;
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
import org.bouncycastle.mail.smime.SMIMEUtil;
import org.bouncycastle.openssl.PEMReader;
/**
* a simple example that creates and processes a signed mail message.
*/
public class SignedMailExample
extends SignedDataProcessor
{
public static MimeMultipart createMultipartWithSignature(
PrivateKey key,
X509Certificate cert,
CertStore certsAndCRLs,
MimeBodyPart dataPart)
throws Exception
{
// create some smime capabilities in case someone wants to respond
ASN1EncodableVector signedAttrs = new ASN1EncodableVector();
SMIMECapabilityVector caps = new SMIMECapabilityVector();
caps.addCapability(SMIMECapability.aES256_CBC);
caps.addCapability(SMIMECapability.dES_EDE3_CBC);
caps.addCapability(SMIMECapability.rC2_CBC, 128);
signedAttrs.add(new SMIMECapabilitiesAttribute(caps));
signedAttrs.add(new SMIMEEncryptionKeyPreferenceAttribute(SMIMEUtil.createIssuerAndSerialNumberFor(cert)));
// set up the generator
SMIMESignedGenerator gen = new SMIMESignedGenerator();
gen.addSigner(key, cert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null);
gen.addCertificatesAndCRLs(certsAndCRLs);
// create the signed message
return gen.generate(dataPart, "BC");
}
public static void main(
String args[])
throws Exception
{
KeyStore credentials = Utils.createCredentials();
PrivateKey key = (PrivateKey)credentials.getKey(Utils.END_ENTITY_ALIAS, Utils.KEY_PASSWD);
Certificate[] chain = credentials.getCertificateChain(Utils.END_ENTITY_ALIAS);
CertStore certsAndCRLs = CertStore.getInstance("Collection",
new CollectionCertStoreParameters(Arrays.asList(chain)), "BC");
X509Certificate cert = (X509Certificate)chain[0];
// create the message we want signed
MimeBodyPart dataPart = new MimeBodyPart();
dataPart.setText("Hello world!");
// create the signed message
MimeMultipart multiPart = createMultipartWithSignature(key, cert, certsAndCRLs, dataPart);
// create the mail message
MimeMessage mail = Utils.createMimeMessage("example signed message", multiPart, multiPart.getContentType());
// extract the message from the mail message
if (mail.isMimeType("multipart/signed"))
{
SMIMESigned signed = new SMIMESigned(
(MimeMultipart)mail.getContent());
// verification step
X509Certificate rootCert = (X509Certificate)credentials.getCertificate(Utils.ROOT_ALIAS);
//////
PEMReader pRd = new PEMReader(
new InputStreamReader(
new FileInputStream("pkcs10.pem")));
X509Certificate kkk = (X509Certificate)pRd.readObject();
//////
if (isValid(signed, kkk))
{
System.out.println("verification succeeded");
}
else
{
System.out.println("verification failed");
}
//
/*
Signature verifier = Signature.getInstance("SHA256WithRSAEncryption");
PEMReader pRd = new PEMReader(
new InputStreamReader(
new FileInputStream("pkcs10.pem")));
X509Certificate kkk = (X509Certificate)pRd.readObject();
verifier.initVerify(kkk.getPublicKey());
*/
/*
PEMReader pRd = new PEMReader(
new InputStreamReader(
new FileInputStream("pkcs10.req")));
PKCS10CertificationRequest request = (PKCS10CertificationRequest)pRd.readObject();
*/
//
// content display step
MimeBodyPart content = signed.getContent();
System.out.print("Content: ");
System.out.println(content.getContent());
}
else
{
System.out.println("wrong content found");
}
}
}