我正在用Java编写开源iOS移动设备管理模块。为此,我在[1]中提到Apple提供的Ruby代码。我已经设置了它,它对我来说很好。现在我需要将此代码转换为Java。到目前为止,我已经完成了PKIOperation的实现。在PKI操作中,我得到了#34; SCEP服务器返回了无效的响应"我认为这是由于我在PKIOperation时发送给设备的错误响应。
然而,当我在互联网上搜索时,我得到的是" maxHttpHeaderSize"因为我使用服务器作为Apache Tomcat。虽然我增加了,但仍然没有得到解决。
以下是我需要转换的代码 - 取自Apple提供的Ruby脚本
if query['operation'] == "PKIOperation"
p7sign = OpenSSL::PKCS7::PKCS7.new(req.body)
store = OpenSSL::X509::Store.new
p7sign.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)
signers = p7sign.signers
p7enc = OpenSSL::PKCS7::PKCS7.new(p7sign.data)
csr = p7enc.decrypt(@@ra_key, @@ra_cert)
cert = issueCert(csr, 1)
degenerate_pkcs7 = OpenSSL::PKCS7::PKCS7.new()
degenerate_pkcs7.type="signed"
degenerate_pkcs7.certificates=[cert]
enc_cert = OpenSSL::PKCS7.encrypt(p7sign.certificates, degenerate_pkcs7.to_der,
OpenSSL::Cipher::Cipher::new("des-ede3-cbc"), OpenSSL::PKCS7::BINARY)
reply = OpenSSL::PKCS7.sign(@@ra_cert, @@ra_key, enc_cert.to_der, [], OpenSSL::PKCS7::BINARY)
res['Content-Type'] = "application/x-pki-message"
res.body = reply.to_der
end
所以这就是我使用Bouncycastle库在Java中编写的。
X509Certificate generatedCertificate = generateCertificateFromCSR(
privateKeyCA, certRequest, certCA.getIssuerX500Principal()
.getName());
CMSTypedData msg = new CMSProcessableByteArray(
generatedCertificate.getEncoded());
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
receivedCert).setProvider(AppConfigurations.PROVIDER));
CMSEnvelopedData envelopedData = edGen
.generate(
msg,
new JceCMSContentEncryptorBuilder(
CMSAlgorithm.DES_EDE3_CBC).setProvider(
AppConfigurations.PROVIDER).build());
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder(
AppConfigurations.SIGNATUREALGO).setProvider(
AppConfigurations.PROVIDER).build(privateKeyRA);
List<X509Certificate> certList = new ArrayList<X509Certificate>();
CMSTypedData cmsByteArray = new CMSProcessableByteArray(
envelopedData.getEncoded());
certList.add(certRA);
Store certs = new JcaCertStore(certList);
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider(
AppConfigurations.PROVIDER).build()).build(
sha1Signer, certRA));
gen.addCertificates(certs);
CMSSignedData sigData = gen.generate(cmsByteArray, true);
return sigData.getEncoded();
此处返回的结果将输出到servlet输出流,其内容类型为&#34; application / x-pki-message&#34;。
我似乎正确地获得了CSR,并使用以下代码生成X509Certificate。
public static X509Certificate generateCertificateFromCSR(
PrivateKey privateKey, PKCS10CertificationRequest request,
String issueSubject) throws Exception {
Calendar targetDate1 = Calendar.getInstance();
targetDate1.setTime(new Date());
targetDate1.add(Calendar.DAY_OF_MONTH, -1);
Calendar targetDate2 = Calendar.getInstance();
targetDate2.setTime(new Date());
targetDate2.add(Calendar.YEAR, 2);
// yesterday
Date validityBeginDate = targetDate1.getTime();
// in 2 years
Date validityEndDate = targetDate2.getTime();
X509v3CertificateBuilder certGen = new X509v3CertificateBuilder(
new X500Name(issueSubject), BigInteger.valueOf(System
.currentTimeMillis()), validityBeginDate,
validityEndDate, request.getSubject(),
request.getSubjectPublicKeyInfo());
certGen.addExtension(X509Extension.keyUsage, true, new KeyUsage(
KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
ContentSigner sigGen = new JcaContentSignerBuilder(
AppConfigurations.SHA256_RSA).setProvider(
AppConfigurations.PROVIDER).build(privateKey);
X509Certificate issuedCert = new JcaX509CertificateConverter()
.setProvider(AppConfigurations.PROVIDER).getCertificate(
certGen.build(sigGen));
return issuedCert;
}
生成的证书通用名称为
通用名称:mdm(88094024-2372-4c9f-9c87-fa814011c525)
发行人:mycompany Root CA(93a7d1a0-130b-42b8-bbd6-728f7c1837cf),无
答案 0 :(得分:2)
一些想法(不是真正的答案)
1)由于各种原因,可能会返回“SCEP服务器返回无效响应”。一般来说,如果SCEP返回MDM客户端无法解析的任何内容,它将显示此错误。
2)看看jSCEP(https://code.google.com/p/jscep/)。这是SCEP服务器的java实现。而且我很确定它适用于iOS(我用它)。
你们都可以检查他们是如何处理它的(我记得他们也在使用Bouncy Castle)
另外,我宁愿在你的开源imlpementation中包含jSCEP而不是重新发明一个bycycle。 SCEP RFC有很多部分,jSCEP非常适合跟随它。