public static PKCS10CertificationRequest genPKCS10(KeyPair kp) throws Exception {
    String sigName = "SHA1withRSA";

    X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);
    x500NameBld.addRDN(BCStyle.C, "AU");
    x500NameBld.addRDN(BCStyle.ST, "Victoria");
    x500NameBld.addRDN(BCStyle.L, "Melbourne");
    x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
    X500Name subject = x500NameBld.build();

    PKCS10CertificationRequestBuilder requestBuilder =
        new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic());

    ExtensionsGenerator extGen = new ExtensionsGenerator();
    extGen.addExtension(
        Extension.subjectAlternativeName,
        false,
        new GeneralNames(
            new GeneralName(GeneralName.rfc822Name, "*****@*****.**")));

    requestBuilder.addAttribute(
        PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extGen.generate());

    PKCS10CertificationRequest p10 =
        requestBuilder.build(
            new JcaContentSignerBuilder(sigName).setProvider("BC").build(kp.getPrivate()));

    if (!p10.isSignatureValid(
        new JcaContentVerifierProviderBuilder().setProvider("BC").build(kp.getPublic()))) {
      System.out.println(sigName + ": Failed verify check.");
    } else {
      System.out.println(sigName + ": PKCS#10 request verified.");
    }
    return p10;
  }
  private static String csr() {
    try {
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
      keyGen.initialize(2048);
      KeyPair keyPair = keyGen.generateKeyPair();
      X500Principal subject =
          new X500Principal(
              "CN = edea87b4-034d-48dc-94dd-e7cdcfdde370/10562468, OU = fgdfgretertgdfg, O = VW, L = US");
      ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").build(keyPair.getPrivate());
      PKCS10CertificationRequestBuilder builder =
          new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
      PKCS10CertificationRequest csr = builder.build(signer);

      String type = "CERTIFICATE REQUEST";
      PemObject pem = new PemObject(type, csr.getEncoded());
      StringWriter str = new StringWriter();
      PEMWriter pemWriter = new PEMWriter(str);
      pemWriter.writeObject(pem);
      pemWriter.close();
      str.close();
      Log.d("Test", "" + str);
      return Base64Util.getStringAsBase64(str.toString());
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (OperatorCreationException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return "";
  }
  @Test
  public void shouldBuildParseEncodedRpkiCaCertRequest() throws Exception {

    PKCS10CertificationRequest pkcs10Request = createRpkiCaCertificateRequest();

    assertNotNull(pkcs10Request);

    PKCS10CertificationRequest decodedPkcs10Request =
        new PKCS10CertificationRequest(pkcs10Request.getEncoded());

    RpkiCaCertificateRequestParser requestParser =
        new RpkiCaCertificateRequestParser(decodedPkcs10Request);

    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_CA_REPO_URI,
        requestParser.getCaRepositoryUri());
    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_CA_MFT_URI, requestParser.getManifestUri());
    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_CA_NOTIFICATION_URI,
        requestParser.getNotificationUri());
    Assert.assertEquals(
        ProvisioningObjectMother.RPKI_CA_CERT_REQUEST_KEYPAIR.getPublic(),
        requestParser.getPublicKey());
  }
Example #4
0
  /**
   * Generate a certificate signing request (PKCS#10).
   *
   * @param info A PKCS10CertReqInfo
   * @param privateKey Private key for signing the request
   * @param signatureProvider Name of provider to sign with
   * @param publicKey Public key to include in the request
   * @param explicitEccParameters True if the EC domain parameters should be included (ie. not a
   *     named curve)
   * @return the certificate request data
   */
  public static ICertReqData genCertificateRequest(
      ISignerCertReqInfo info,
      final PrivateKey privateKey,
      final String signatureProvider,
      PublicKey publicKey,
      final boolean explicitEccParameters)
      throws IllegalArgumentException {
    LOG.debug(">genCertificateRequest");
    final Base64SignerCertReqData retval;
    if (info instanceof PKCS10CertReqInfo) {
      PKCS10CertReqInfo reqInfo = (PKCS10CertReqInfo) info;
      PKCS10CertificationRequest pkcs10;

      if (LOG.isDebugEnabled()) {
        LOG.debug("signatureAlgorithm: " + reqInfo.getSignatureAlgorithm());
        LOG.debug("subjectDN: " + reqInfo.getSubjectDN());
        LOG.debug("explicitEccParameters: " + explicitEccParameters);
      }

      try {
        // Handle ECDSA key with explicit parameters
        if (explicitEccParameters && publicKey.getAlgorithm().contains("EC")) {
          publicKey = ECKeyUtil.publicToExplicitParameters(publicKey, "BC");
        }

        if (LOG.isDebugEnabled()) {
          LOG.debug("Public key SHA1: " + createKeyHash(publicKey));
          LOG.debug("Public key SHA256: " + KeyUsageCounterHash.create(publicKey));
        }

        // Generate request
        final JcaPKCS10CertificationRequestBuilder builder =
            new JcaPKCS10CertificationRequestBuilder(
                new X500Name(CertTools.stringToBCDNString(reqInfo.getSubjectDN())), publicKey);
        final ContentSigner contentSigner =
            new JcaContentSignerBuilder(reqInfo.getSignatureAlgorithm())
                .setProvider(signatureProvider)
                .build(privateKey);
        pkcs10 = builder.build(contentSigner);
        retval = new Base64SignerCertReqData(Base64.encode(pkcs10.getEncoded()));
      } catch (IOException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      } catch (OperatorCreationException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      } catch (NoSuchAlgorithmException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      } catch (NoSuchProviderException e) {
        throw new IllegalArgumentException("Certificate request error: " + e.getMessage(), e);
      }
      LOG.debug("<genCertificateRequest");
      return retval;
    } else {
      throw new IllegalArgumentException(
          "Unsupported certificate request info type: " + info.getClass().getName());
    }
  }
 /**
  * Extracts the <tt>Challenge password</tt> from the provided CSR.
  *
  * <p>
  *
  * @param csr the CSR to extract from.
  * @return the extracted <tt>Challenge password</tt>
  */
 public static String getChallengePassword(final PKCS10CertificationRequest csr) {
   Attribute[] attrs = csr.getAttributes();
   for (Attribute attr : attrs) {
     if (attr.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_challengePassword)) {
       DERPrintableString challangePassword =
           (DERPrintableString) attr.getAttrValues().getObjectAt(0);
       return challangePassword.getString();
     }
   }
   return null;
 }
  /**
   * Extracts the <tt>PublicKey</tt> from the provided CSR.
   *
   * <p>This method will throw a {@link RuntimeException} if the JRE is missing the RSA algorithm,
   * which is a required algorithm as defined by the JCA.
   *
   * @param csr the CSR to extract from.
   * @return the extracted <tt>PublicKey</tt>
   * @throws InvalidKeySpecException if the CSR is not using an RSA key.
   * @throws IOException if there is an error extracting the <tt>PublicKey</tt> parameters.
   */
  public static PublicKey getPublicKey(final PKCS10CertificationRequest csr)
      throws InvalidKeySpecException, IOException {
    SubjectPublicKeyInfo pubKeyInfo = csr.getSubjectPublicKeyInfo();
    RSAKeyParameters keyParams = (RSAKeyParameters) PublicKeyFactory.createKey(pubKeyInfo);
    KeySpec keySpec = new RSAPublicKeySpec(keyParams.getModulus(), keyParams.getExponent());

    KeyFactory kf;
    try {
      kf = KeyFactory.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
      throw new RuntimeException(e);
    }
    return kf.generatePublic(keySpec);
  }
  /** Do action. */
  @Override
  protected void doAction() {
    FileOutputStream fos = null;
    File caReplyFile = null;

    try {
      KeyStoreHistory history = kseFrame.getActiveKeyStoreHistory();
      KeyStoreState currentState = history.getCurrentState();

      String alias = kseFrame.getSelectedEntryAlias();

      Password password = getEntryPassword(alias, currentState);

      if (password == null) {
        return;
      }

      KeyStore keyStore = currentState.getKeyStore();

      PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, password.toCharArray());
      Certificate[] certs = keyStore.getCertificateChain(alias);

      KeyPairType keyPairType = KeyPairUtil.getKeyPairType(privateKey);

      File csrFile = chooseCsrFile();
      if (csrFile == null) {
        return;
      }

      PKCS10CertificationRequest pkcs10Csr = null;
      Spkac spkacCsr = null;

      try {
        CryptoFileType fileType = CryptoFileUtil.detectFileType(new FileInputStream(csrFile));
        if (fileType == CryptoFileType.PKCS10_CSR) {
          pkcs10Csr = Pkcs10Util.loadCsr(new FileInputStream(csrFile));

          if (!Pkcs10Util.verifyCsr(pkcs10Csr)) {
            JOptionPane.showMessageDialog(
                frame,
                res.getString("SignCsrAction.NoVerifyPkcs10Csr.message"),
                res.getString("SignCsrAction.SignCsr.Title"),
                JOptionPane.WARNING_MESSAGE);
            return;
          }
        } else if (fileType == CryptoFileType.SPKAC_CSR) {
          spkacCsr = new Spkac(new FileInputStream(csrFile));

          if (!spkacCsr.verify()) {
            JOptionPane.showMessageDialog(
                frame,
                res.getString("SignCsrAction.NoVerifySpkacCsr.message"),
                res.getString("SignCsrAction.SignCsr.Title"),
                JOptionPane.WARNING_MESSAGE);
            return;
          }
        } else {
          JOptionPane.showMessageDialog(
              frame,
              MessageFormat.format(
                  res.getString("SignCsrAction.FileNotRecognisedType.message"), csrFile),
              res.getString("SignCsrAction.SignCsr.Title"),
              JOptionPane.WARNING_MESSAGE);
          return;
        }
      } catch (FileNotFoundException ex) {
        JOptionPane.showMessageDialog(
            frame,
            MessageFormat.format(res.getString("SignCsrAction.NotFile.message"), csrFile),
            res.getString("SignCsrAction.SignCsr.Title"),
            JOptionPane.WARNING_MESSAGE);
        return;
      } catch (Exception ex) {
        String problemStr =
            MessageFormat.format(
                res.getString("SignCsrAction.NoOpenCsr.Problem"), csrFile.getName());

        String[] causes =
            new String[] {
              res.getString("SignCsrAction.NotCsr.Cause"),
              res.getString("SignCsrAction.CorruptedCsr.Cause")
            };

        Problem problem = new Problem(problemStr, causes, ex);

        DProblem dProblem =
            new DProblem(frame, res.getString("SignCsrAction.ProblemOpeningCsr.Title"), problem);
        dProblem.setLocationRelativeTo(frame);
        dProblem.setVisible(true);

        return;
      }

      X509Certificate[] signingChain =
          X509CertUtil.orderX509CertChain(X509CertUtil.convertCertificates(certs));
      X509Certificate signingCert = signingChain[0];

      PublicKey publicKey = null;
      X500Name subject = null;
      DSignCsr dSignCsr = null;
      Provider provider = history.getExplicitProvider();

      if (pkcs10Csr != null) {
        publicKey = new JcaPKCS10CertificationRequest(pkcs10Csr).getPublicKey();
        subject = pkcs10Csr.getSubject();

        dSignCsr =
            new DSignCsr(frame, pkcs10Csr, csrFile, privateKey, keyPairType, signingCert, provider);
      } else {
        publicKey = spkacCsr.getPublicKey();
        subject = spkacCsr.getSubject().getName();

        dSignCsr =
            new DSignCsr(frame, spkacCsr, csrFile, privateKey, keyPairType, signingCert, provider);
      }

      dSignCsr.setLocationRelativeTo(frame);
      dSignCsr.setVisible(true);

      X509CertificateVersion version = dSignCsr.getVersion();
      SignatureType signatureType = dSignCsr.getSignatureType();
      long validityPeriod = dSignCsr.getValidityPeriod();
      BigInteger serialNumber = dSignCsr.getSerialNumber();
      caReplyFile = dSignCsr.getCaReplyFile();
      X509ExtensionSet extensions = dSignCsr.getExtensions();

      if (version == null) {
        return;
      }

      X500Name issuer =
          X500NameUtils.x500PrincipalToX500Name(signingCert.getSubjectX500Principal());

      // CA Reply is a cert with subject from CSR and issuer from signing cert's subject
      X509CertificateGenerator generator = new X509CertificateGenerator(version);
      X509Certificate caReplyCert =
          generator.generate(
              subject,
              issuer,
              validityPeriod,
              publicKey,
              privateKey,
              signatureType,
              serialNumber,
              extensions,
              provider);

      X509Certificate[] caReplyChain = new X509Certificate[signingChain.length + 1];

      caReplyChain[0] = caReplyCert;

      // Add all of the signing chain to the reply
      System.arraycopy(signingChain, 0, caReplyChain, 1, signingChain.length);

      byte[] caCertEncoded = X509CertUtil.getCertsEncodedPkcs7(caReplyChain);

      fos = new FileOutputStream(caReplyFile);
      fos.write(caCertEncoded);
    } catch (FileNotFoundException ex) {
      JOptionPane.showMessageDialog(
          frame,
          MessageFormat.format(res.getString("SignJarAction.NoWriteFile.message"), caReplyFile),
          res.getString("SignCsrAction.SignCsr.Title"),
          JOptionPane.WARNING_MESSAGE);
      return;
    } catch (Exception ex) {
      DError.displayError(frame, ex);
      return;
    } finally {
      IOUtils.closeQuietly(fos);
    }

    JOptionPane.showMessageDialog(
        frame,
        res.getString("SignCsrAction.SignCsrSuccessful.message"),
        res.getString("SignCsrAction.SignCsr.Title"),
        JOptionPane.INFORMATION_MESSAGE);
  }
Example #8
0
  @Override
  protected Object _doExecute() throws Exception {
    P10RequestGenerator p10Gen = new P10RequestGenerator();

    hashAlgo = hashAlgo.trim().toUpperCase();
    if (hashAlgo.indexOf('-') != -1) {
      hashAlgo = hashAlgo.replaceAll("-", "");
    }

    if (needExtensionTypes == null) {
      needExtensionTypes = new LinkedList<>();
    }

    // SubjectAltNames
    List<Extension> extensions = new LinkedList<>();
    if (isNotEmpty(subjectAltNames)) {
      extensions.add(P10RequestGenerator.createExtensionSubjectAltName(subjectAltNames, false));
      needExtensionTypes.add(Extension.subjectAlternativeName.getId());
    }

    // SubjectInfoAccess
    if (isNotEmpty(subjectInfoAccesses)) {
      extensions.add(
          P10RequestGenerator.createExtensionSubjectInfoAccess(subjectInfoAccesses, false));
      needExtensionTypes.add(Extension.subjectInfoAccess.getId());
    }

    // Keyusage
    if (isNotEmpty(keyusages)) {
      Set<KeyUsage> usages = new HashSet<>();
      for (String usage : keyusages) {
        usages.add(KeyUsage.getKeyUsage(usage));
      }
      org.bouncycastle.asn1.x509.KeyUsage extValue = X509Util.createKeyUsage(usages);
      ASN1ObjectIdentifier extType = Extension.keyUsage;
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // ExtendedKeyusage
    if (isNotEmpty(extkeyusages)) {
      Set<ASN1ObjectIdentifier> oids =
          new HashSet<>(SecurityUtil.textToASN1ObjectIdentifers(extkeyusages));
      ExtendedKeyUsage extValue = X509Util.createExtendedUsage(oids);
      ASN1ObjectIdentifier extType = Extension.extendedKeyUsage;
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // QcEuLimitValue
    if (isNotEmpty(qcEuLimits)) {
      ASN1EncodableVector v = new ASN1EncodableVector();
      for (String m : qcEuLimits) {
        StringTokenizer st = new StringTokenizer(m, ":");
        try {
          String currencyS = st.nextToken();
          String amountS = st.nextToken();
          String exponentS = st.nextToken();

          Iso4217CurrencyCode currency;
          try {
            int intValue = Integer.parseInt(currencyS);
            currency = new Iso4217CurrencyCode(intValue);
          } catch (NumberFormatException e) {
            currency = new Iso4217CurrencyCode(currencyS);
          }

          int amount = Integer.parseInt(amountS);
          int exponent = Integer.parseInt(exponentS);

          MonetaryValue monterayValue = new MonetaryValue(currency, amount, exponent);
          QCStatement statment =
              new QCStatement(ObjectIdentifiers.id_etsi_qcs_QcLimitValue, monterayValue);
          v.add(statment);
        } catch (Exception e) {
          throw new Exception("invalid qc-eu-limit '" + m + "'");
        }
      }

      ASN1ObjectIdentifier extType = Extension.qCStatements;
      ASN1Sequence extValue = new DERSequence(v);
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    }

    // biometricInfo
    if (biometricType != null && biometricHashAlgo != null && biometricFile != null) {
      TypeOfBiometricData _biometricType;
      if (StringUtil.isNumber(biometricType)) {
        _biometricType = new TypeOfBiometricData(Integer.parseInt(biometricType));
      } else {
        _biometricType = new TypeOfBiometricData(new ASN1ObjectIdentifier(biometricType));
      }

      ASN1ObjectIdentifier _biometricHashAlgo = AlgorithmUtil.getHashAlg(biometricHashAlgo);
      byte[] biometricBytes = IoUtil.read(biometricFile);
      MessageDigest md = MessageDigest.getInstance(_biometricHashAlgo.getId());
      md.reset();
      byte[] _biometricDataHash = md.digest(biometricBytes);

      DERIA5String _sourceDataUri = null;
      if (biometricUri != null) {
        _sourceDataUri = new DERIA5String(biometricUri);
      }
      BiometricData biometricData =
          new BiometricData(
              _biometricType,
              new AlgorithmIdentifier(_biometricHashAlgo),
              new DEROctetString(_biometricDataHash),
              _sourceDataUri);

      ASN1EncodableVector v = new ASN1EncodableVector();
      v.add(biometricData);

      ASN1ObjectIdentifier extType = Extension.biometricInfo;
      ASN1Sequence extValue = new DERSequence(v);
      extensions.add(new Extension(extType, false, extValue.getEncoded()));
      needExtensionTypes.add(extType.getId());
    } else if (biometricType == null && biometricHashAlgo == null && biometricFile == null) {
      // Do nothing
    } else {
      throw new Exception(
          "either all of biometric triples (type, hash algo, file)"
              + " must be set or none of them should be set");
    }

    if (isNotEmpty(needExtensionTypes) || isNotEmpty(wantExtensionTypes)) {
      ExtensionExistence ee =
          new ExtensionExistence(
              SecurityUtil.textToASN1ObjectIdentifers(needExtensionTypes),
              SecurityUtil.textToASN1ObjectIdentifers(wantExtensionTypes));
      extensions.add(
          new Extension(
              ObjectIdentifiers.id_xipki_ext_cmpRequestExtensions,
              false,
              ee.toASN1Primitive().getEncoded()));
    }

    ConcurrentContentSigner identifiedSigner =
        getSigner(hashAlgo, new SignatureAlgoControl(rsaMgf1, dsaPlain));
    Certificate cert = Certificate.getInstance(identifiedSigner.getCertificate().getEncoded());

    X500Name subjectDN;
    if (subject != null) {
      subjectDN = getSubject(subject);
    } else {
      subjectDN = cert.getSubject();
    }

    SubjectPublicKeyInfo subjectPublicKeyInfo = cert.getSubjectPublicKeyInfo();

    ContentSigner signer = identifiedSigner.borrowContentSigner();

    PKCS10CertificationRequest p10Req;
    try {
      p10Req = p10Gen.generateRequest(signer, subjectPublicKeyInfo, subjectDN, extensions);
    } finally {
      identifiedSigner.returnContentSigner(signer);
    }

    File file = new File(outputFilename);
    saveVerbose("saved PKCS#10 request to file", file, p10Req.getEncoded());
    return null;
  }
  public static void testGenP12() throws Exception {

    String rootCerBase64 =
        "MIIDvTCCAqWgAwIBAgIEEioP6zANBgkqhkiG9w0BAQsFADCBjjELMAkGA1UEBhMC"
            + "Q04xETAPBgNVBAgTCHNoYW5naGFpMREwDwYDVQQHEwhzaGFuZ2hhaTEzMDEGA1UE"
            + "Cgwq5LiK5rW36YeR6bm/6YeR6J6N5L+h5oGv5pyN5Yqh5pyJ6ZmQ5YWs5Y+4MQsw"
            + "CQYDVQQLEwJJVDEXMBUGA1UEAxMOb3Blbi5qbGZleC5jb20wHhcNMTQwODIxMDM0"
            + "NTQ5WhcNMjQwODE4MDM0NTQ5WjCBjjELMAkGA1UEBhMCQ04xETAPBgNVBAgTCHNo"
            + "YW5naGFpMREwDwYDVQQHEwhzaGFuZ2hhaTEzMDEGA1UECgwq5LiK5rW36YeR6bm/"
            + "6YeR6J6N5L+h5oGv5pyN5Yqh5pyJ6ZmQ5YWs5Y+4MQswCQYDVQQLEwJJVDEXMBUG"
            + "A1UEAxMOb3Blbi5qbGZleC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK"
            + "AoIBAQCQ4q4Yh8EPHbAP+BMiystXOEV56OE+IUwxSS7fRZ3ZrIEPImpnCiAe1txZ"
            + "vk0Lgv8ZWqrj4ErOT5FoOWfQW6Vva1DOXknCzFbypJMjqVnIS1/OwB64sYg4naLc"
            + "mM95GAHtEv9qxIWLbPhoLShz54znRNbM7mZJyT4BwLhKuKmfdo3UEuXvcoUFLN2l"
            + "f2wiTNmgMgpxcnCsWAx2nJaonPGCVXeQu0PXCVmCTyUUCWdT7P1io5yEpuRP/Dac"
            + "//g7Em8rkulgeO7e3gnEbrgrczsr2H1KJLTBjQmyWeWZg7LRYML6oHODrrDb0x++"
            + "yDT01p2BJHlvw/UzJq3I/CCci0lFAgMBAAGjITAfMB0GA1UdDgQWBBS1Lo57VqvU"
            + "BnfyJu51JO9csLJenjANBgkqhkiG9w0BAQsFAAOCAQEACcfPaVl5PIkBZ6cXyHuj"
            + "rJZkZH7Koqhx12DNeCoohdQkRda/gWeHVPsO7snK63sFhoY08OGVgvTRhgzwSBxJ"
            + "cx9GkCyojfHo5xZoOlSQ01PygyScd42DlseNiwXZGBfoxacLEYkIP6OXrDa+wNAP"
            + "gHnLI+37tzkafoPT0xoV/E9thvUUKX1jSIL5UCoGuso6FWLiZgDxD8wKgd22FcYo"
            + "T7B7DHG4R+0rgav81J9xjgOR3ayvNrb86iVvVBmrIiM7Gc2hf5PMiiAOaISST2cJ"
            + "x90X7TUA/f0qrYKveTvkRT77nLfzHV1a+PTS7PwkCXUt/NRm4VwseyGIgQ4FXH6W"
            + "zw==";

    // 解析root CA 证书
    X509Certificate rootcaCertificate =
        CertificateCoder.getX509Certificate(Base64.decodeBase64(rootCerBase64));
    // 解析root CA 私钥
    String rootcaDer = FileUtils.readFileToString(new File("d:\\rootcakey.pem"), "UTF-8");
    PrivateKey rootcaPrivateKey = PKCSCertificateCoder.getPrivateKeyFromPem(rootcaDer, "");
    System.out.println(rootcaPrivateKey);

    // 1.生成用户密钥对
    Security.addProvider(new BouncyCastleProvider());
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
    kpg.initialize(2048);
    KeyPair kp = kpg.genKeyPair();

    // 2.生成用户证书请求
    PKCS10CertificationRequest p10 = genPKCS10(kp);
    SubjectPublicKeyInfo subPublicKeyInfo = p10.getSubjectPublicKeyInfo();
    RSAKeyParameters rsa = (RSAKeyParameters) PublicKeyFactory.createKey(subPublicKeyInfo);
    RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent());
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey publicKey = kf.generatePublic(rsaSpec);

    // 3.生成用户证书
    X509Certificate clientCertificate =
        buildEndEntityCert(publicKey, rootcaPrivateKey, rootcaCertificate);
    FileUtils.writeByteArrayToFile(new File("d:\\client.cer"), clientCertificate.getEncoded());

    // 4.生成用户p12文件
    storeP12(
        kp,
        new X509Certificate[] {clientCertificate, rootcaCertificate},
        "d:\\client.p12",
        "123456");

    FileOutputStream fos = new FileOutputStream(new File("d:\\client1.p12"));
    X509Certificate[] chain =
        new X509Certificate[] {rootcaCertificate, clientCertificate, clientCertificate};
    genPKCS12File(fos, kp.getPrivate(), chain);
  }