java - CMP 证书申请
问题描述
我正在使用下面的代码向端点发送 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 验证失败。
解决方案
你得到的响应不是一个字符串,它是一个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 操作)。
推荐阅读
- javascript - 在赛普拉斯测试中,增量功能不起作用,每次都需要增加数字?
- javascript - React-Native:Native-base:失败的道具类型:提供给“View”的无效 props.style 键“NativeBase”
- c# - iText.Layout.Document 忽略合并 pdf 占用的空间
- c - 无延迟使用蜂鸣器[C] STM32
- jenkins - 为使用 jenkinsci kubernetes-plugin 创建的 jenkins slave 配置 Kubernetes cpu 内存请求和限制
- react-apollo - 访问 InMemoryCache 中 dataIdFromObject 内部的查询变量?
- amazon-web-services - 解决方案栈具体版本后如何从elasticbeanstalk获取最新的解决方案栈?
- python - 当列表大小不是某个值的倍数时,我应该引发什么错误?
- cmake - CMAKE:使用 ld(设置 CMAKE_CXX_LINK_EXECUTABLE)作为链接器的“-rdynamic”问题
- solr - 如何从 SOLR 结果中排除特定数据?