Soporte al cliente de CMP
Esta página proporciona ejemplos de código y otra información necesaria para crear un cliente CMP. Estos ejemplos de código no se mantienen y podrían no ser compatibles con futuras versiones de BouncyCastle.
Mensaje (inicial) de solicitud de certificado protegido por HMAC (modo RA)
Mensaje de solicitud de revocación protegido por HMAC (modo RA)
Mensaje (inicial) de solicitud de certificado protegido por HMAC (modo RA)
// Just preparationsfinal BigInteger certReqId = BigInteger.valueOf( 1 );final byte [] senderNonce = "12345" .getBytes();final byte [] transactionId = "23456" .getBytes();KeyPairGenerator kpi = KeyPairGenerator.getInstance( "RSA" );kpi.initialize( 1024 );KeyPair keyPair = kpi.generateKeyPair();// Now on to the CMPCertificateRequestMessageBuilder msgbuilder = new CertificateRequestMessageBuilder(certReqId);X500Name issuerDN = new X500Name( "CN=ManagementCA" );X500Name subjectDN = new X500Name( "CN=user" );msgbuilder.setIssuer(issuerDN);msgbuilder.setSubject(subjectDN);final byte [] bytes = keyPair.getPublic().getEncoded();final ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);final ASN1InputStream dIn = new ASN1InputStream(bIn);final SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject());dIn.close();msgbuilder.setPublicKey(keyInfo);GeneralName sender = new GeneralName(subjectDN);msgbuilder.setAuthInfoSender(sender);// RAVerified POPmsgbuilder.setProofOfPossessionRaVerified();CertificateRequestMessage msg = msgbuilder.build();org.bouncycastle.asn1.crmf.CertReqMessages msgs = new org.bouncycastle.asn1.crmf.CertReqMessages(msg.toASN1Structure());org.bouncycastle.asn1.cmp.PKIBody pkibody = new org.bouncycastle.asn1.cmp.PKIBody(org.bouncycastle.asn1.cmp.PKIBody.TYPE_INIT_REQ, msgs);// Message protection and final messageGeneralName recipient = new GeneralName(issuerDN);ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);pbuilder.setMessageTime( new Date());// senderNoncepbuilder.setSenderNonce(senderNonce);// TransactionIdpbuilder.setTransactionID(transactionId);// Key Id used (required) by the recipient to do a lot of stuffpbuilder.setSenderKID( "KeyID" .getBytes());pbuilder.setBody(pkibody);JcePKMACValuesCalculator jcePkmacCalc = new JcePKMACValuesCalculator(); Identificador de algoritmo
final AlgorithmIdentifier digAlg = new AlgorithmIdentifier( new ASN1ObjectIdentifier( "1.3.14.3.2.26" )); // SHA1 Identificador de algoritmo
final AlgorithmIdentifier macAlg = new AlgorithmIdentifier( new ASN1ObjectIdentifier( "1.2.840.113549.2.7" )); // HMAC/SHA1jcePkmacCalc.setup(digAlg, macAlg);PKMACBuilder macbuilder = new PKMACBuilder(jcePkmacCalc);MacCalculator macCalculator = macbuilder.build( "password" .toCharArray());ProtectedPKIMessage message = pbuilder.build(macCalculator); Mensaje de solicitud de revocación protegido por HMAC (modo RA)
// Just preparationsfinal byte [] senderNonce = "12345" .getBytes();final byte [] transactionId = "23456" .getBytes();BigInteger serNo = new BigInteger( "aabbccdd" );X500Name issuerDN = new X500Name( "CN=ManagementCA" );X500Name userDN = new X500Name( "CN=user" );// Cert template too tell which cert we want to revokeCertTemplateBuilder myCertTemplate = new CertTemplateBuilder();myCertTemplate.setIssuer(issuerDN);myCertTemplate.setSubject(userDN);myCertTemplate.setSerialNumber( new ASN1Integer(serNo));// Extension telling revocation reasonExtensionsGenerator extgen = new ExtensionsGenerator();CRLReason crlReason = CRLReason.lookup(CRLReason.cessationOfOperation);extgen.addExtension(Extension.reasonCode, false , crlReason);Extensions exts = extgen.generate();ASN1EncodableVector v = new ASN1EncodableVector();v.add(myCertTemplate.build());v.add(exts);ASN1Sequence seq = new DERSequence(v);RevDetails myRevDetails = RevDetails.getInstance(seq);RevReqContent myRevReqContent = new RevReqContent(myRevDetails);PKIBody myPKIBody = new PKIBody(PKIBody.TYPE_REVOCATION_REQ, myRevReqContent); // revocation request// Message protection and final messageGeneralName sender = new GeneralName(userDN);GeneralName recipient = new GeneralName(issuerDN);ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);pbuilder.setMessageTime( new Date());// senderNoncepbuilder.setSenderNonce(senderNonce);// TransactionIdpbuilder.setTransactionID(transactionId);// Key Id used (required) by the recipient to do a lot of stuffpbuilder.setSenderKID( "KeyId" .getBytes());pbuilder.setBody(myPKIBody);JcePKMACValuesCalculator jcePkmacCalc = new JcePKMACValuesCalculator(); Identificador de algoritmo
final AlgorithmIdentifier digAlg = new AlgorithmIdentifier( new ASN1ObjectIdentifier( "1.3.14.3.2.26" )); // SHA1 Identificador de algoritmo
final AlgorithmIdentifier macAlg = new AlgorithmIdentifier( new ASN1ObjectIdentifier( "1.2.840.113549.2.7" )); // HMAC/SHA1jcePkmacCalc.setup(digAlg, macAlg);PKMACBuilder macbuilder = new PKMACBuilder(jcePkmacCalc);MacCalculator macCalculator = macbuilder.build( "password" .toCharArray());ProtectedPKIMessage message = pbuilder.build(macCalculator); Mensaje protegido por firma (modo cliente)
CertificateRequestMessageBuilder msgbuilder = new CertificateRequestMessageBuilder(BigInteger.valueOf(certReqId));X509NameEntryConverter dnconverter = new X509DefaultEntryConverter();X500Name issuerDN = X500Name.getInstance( new X509Name( "CN=ManagementCA" ).toASN1Object());X500Name subjectDN = X500Name.getInstance( new X509Name( "CN=user" , dnconverter).toASN1Object());msgbuilder.setIssuer(issuerDN);msgbuilder.setSubject(subjectDN);final byte [] bytes = keyPair.getPublic().getEncoded();final ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);final ASN1InputStream dIn = new ASN1InputStream(bIn);final SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject());msgbuilder.setPublicKey(keyInfo);GeneralName sender = new GeneralName(subjectDN);msgbuilder.setAuthInfoSender(sender);Control control = new RegTokenControl( "foo123" );msgbuilder.addControl(control);Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);ContentSigner popsigner = new JcaContentSignerBuilder( "SHA256withRSA" ).setProvider(prov).build(keyPair.getPrivate());msgbuilder.setProofOfPossessionSigningKeySigner(popsigner);CertificateRequestMessage msg = msgbuilder.build();GeneralName recipient = new GeneralName(issuerDN);ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);pbuilder.setMessageTime( new Date());// senderNoncepbuilder.setSenderNonce(senderNonce);// TransactionIdpbuilder.setTransactionID(transactionId);org.bouncycastle.asn1.crmf.CertReqMessages msgs = new org.bouncycastle.asn1.crmf.CertReqMessages(msg.toASN1Structure());org.bouncycastle.asn1.cmp.PKIBody pkibody = new org.bouncycastle.asn1.cmp.PKIBody(org.bouncycastle.asn1.cmp.PKIBody.TYPE_INIT_REQ, msgs);pbuilder.setBody(pkibody);ContentSigner msgsigner = new JcaContentSignerBuilder( "SHA1withRSA" ).setProvider(prov).build(keyPair.getPrivate());ProtectedPKIMessage message = pbuilder.build(msgsigner); Mensaje con múltiples firmas
Código de muestra para un mensaje NestedMessageContent protegido por firma:
String subjectDN = "CN=bogusSubjectNested" ;final byte [] nonce = "sendernonce" .getBytes();final byte [] transid = "trandis" .getBytes();PKIMessage crmfMsg = createCrmfReq();//Signing crmfMsgKeyPair eeKeys = getAdminKeys();Certificate adminCert = getAdminCertificate();ByteArrayInputStream bIn = new ByteArrayInputStream(adminCert.getEncoded());ASN1InputStream dIn = new ASN1InputStream(bIn);ASN1Sequence extraAdminCertSeq = (ASN1Sequence)dIn.readObject();X509CertificateStructure extraCert = new X509CertificateStructure(ASN1Sequence.getInstance(extraAdminCertSeq));crmfMsg.addExtraCert(extraCert); Firma
final Signature sig = Signature.getInstance(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(eekeys.getPrivate());sig.update(crmfMsg.getProtectedBytes());byte [] eeSignature = sig.sign();crmfMsg.setProtection( new DERBitString(eeSignature));PKIHeader myPKIHeader = new PKIHeader( new DERInteger( 2 ), new GeneralName( new X509Name(subjectDN)), new GeneralName( new X509Name(((X509Certificate)cacert).getSubjectDN().getName())));myPKIHeader.setMessageTime( new DERGeneralizedTime( new Date()));// senderNoncemyPKIHeader.setSenderNonce( new DEROctetString(nonce));// TransactionIdmyPKIHeader.setTransactionID( new DEROctetString(transid));PKIBody myPKIBody = new PKIBody(crmfMsg, 20 ); // NestedMessageContentPKIMessage myPKIMessage = new PKIMessage(myPKIHeader, myPKIBody);//Signing myPKIMessageKeyPair raKeys = getRAKeys(); Firma
final Signature sig = Signature.getInstance(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(rakeys.getPrivate());sig.update(myPKIMessage.getProtectedBytes());byte [] eeSignature = sig.sign();myPKIMessage.setProtection( new DERBitString(eeSignature));final ByteArrayOutputStream bao = new ByteArrayOutputStream();final DEROutputStream out = new DEROutputStream(bao);out.writeObject(myPKIMessage);final byte [] ba = bao.toByteArray();// Send request and receive responsefinal byte [] resp = sendCmpHttp(ba, 200 );