2

我正在使用下面的代码向端点发送 CMP 证书请求:

public static void main(String[] args) {
    try
    {
        System.out.println("In...");
        final BigInteger certReqId = BigInteger.valueOf(1);
        final byte[] senderNonce = "12345".getBytes();
        final byte[] transactionId = "23456".getBytes();
        KeyPairGenerator kpi = KeyPairGenerator.getInstance("RSA");
        kpi.initialize(2048);
        KeyPair keyPair = kpi.generateKeyPair();

        // Now on to the CMP
        CertificateRequestMessageBuilder 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 POP
        msgbuilder.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 message
        GeneralName recipient = new GeneralName(issuerDN);
        ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);
        pbuilder.setMessageTime(new Date());

        // senderNonce
        pbuilder.setSenderNonce(senderNonce);

        // TransactionId
        pbuilder.setTransactionID(transactionId);

        // Key Id used (required) by the recipient to do a lot of stuff
        pbuilder.setSenderKID("KeyID".getBytes());
        pbuilder.setBody(pkibody);
        JcePKMACValuesCalculator jcePkmacCalc = new JcePKMACValuesCalculator();
        final AlgorithmIdentifier digAlg = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")); // SHA1
        final AlgorithmIdentifier macAlg = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.2.7")); // HMAC/SHA1
        jcePkmacCalc.setup(digAlg, macAlg);
        PKMACBuilder macbuilder = new PKMACBuilder(jcePkmacCalc);
        MacCalculator macCalculator = macbuilder.build("47GKM7h06sfl".toCharArray());
        ProtectedPKIMessage message = pbuilder.build(macCalculator);

        PKIMessage pkiMessage = message.toASN1Structure();
        byte[] new_bytes = sendCmpHttp(pkiMessage.getEncoded());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private static byte[] sendCmpHttp(byte[] message ) throws IOException {
    // POST the CMP request

    final String urlString = "endpoint";
    // final String urlString = "http://localhost/ejbca/publicweb/cmp";

    URL url = new URL(urlString);
    final HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setDoOutput(true);
    con.setRequestMethod("POST");
    con.setRequestProperty("Content-type", "application/pkixcmp");
    con.connect();
    // POST it
    OutputStream os = con.getOutputStream();
    os.write(message);
    os.close();


    System.out.println("httpRespCode: " + con.getResponseCode());
    System.out.println("Content Type: " + con.getContentType());
    System.out.println("CacheControl:" + con.getHeaderField("Cache-Control"));
    System.out.println("Pragma:" + con.getHeaderField("Pragma"));
    System.out.println("Pragma:" + con.getResponseMessage());

    // Now read in the bytes
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    // This works for small requests, and CMP requests are small enough
    InputStream in = con.getInputStream();
    int b = in.read();
    while (b != -1) {
        baos.write(b);
        b = in.read();
    }
    baos.flush();
    in.close();
    byte[] respBytes = baos.toByteArray();
    System.out.println(baos.toString());
    // is Null respBytes);
    // respBytes.length > 0
    return respBytes;
}

当我将字节响应转换为字符串时,我得到一些不可读的字符 + POPO 验证失败。

4

1 回答 1

2

你得到的响应不是一个字符串,它是一个PKIMessage对象。您可以通过这种方式将二进制数据转换为对象:

ASN1InputStream is = new ASN1InputStream(new ByteArrayInputStream(new_bytes));

PKIMessage pkiMessage = PKIMessage.getInstance(is.readObject());

GeneralPKIMessage generalPKIMessage = new GeneralPKIMessage(pkiMessage.getEncoded());

System.out.println(generalPKIMessage);

对于失败和成功的 CMP 操作,您都会获得一个 PKIMessage 对象。您可以在该对象中找到错误消息或用户证书(取决于您正在执行的 CMP 操作)。

于 2020-03-23T15:02:27.780 回答