我正在尝试从 Android 设备向服务器发送一个证书签名请求。服务器在 iOS 设备上正常工作并遵循 SCEP procedure使用 OpenSSL。
所以这是我的问题: 我可以发送已签名的封装 CSR,但服务器无法读取封装的 CSR。服务器出现以下错误:
pki.rb:26:in 初始化:无法解析 PKCS7: header 太长(ArgumentError)
相关ruby服务器代码:
#receive object and put it in object data
[...]
# Verify Input Data
p7sign = OpenSSL::PKCS7.new(data)
store = OpenSSL::X509::Store.new
p7sign.verify(nil, store, nil, OpenSSL::PKCS7::NOVERIFY)
signers = p7sign.signers
# Encrypted data (LINE 26 :)
p7enc = OpenSSL::PKCS7.new(p7sign.data)
# Certificate Signing Request
csr = p7enc.decrypt(ssl.key, ssl.certificate)
# Signed Certificate
request = OpenSSL::X509::Request.new(csr)
Java代码(安卓):
我正在使用 Bouncy CaSTLe 生成 CSR,并使用 Volley (Google) 发送它。
主要内容:
//Generate PEM formated CSR
byte[] pemCsr = getPemFromCsr(generateCSR());
//Envelop it in a PKCS#7 object
byte[] envelopedData = getDerFromCMSEnvelopedData(envelopData(pemCsr));
//Sign it in a PKCS#7 object
byte[] signedData = getDerFromCMSSignedData(signData(envelopedData));
sendCsrRequest(signedData);
企业社会责任:
//Generate the CSR
private static PKCS10CertificationRequest genrateCertificationRequest(){
// Build the CN for the cert we
X500NameBuilder nameBld = new X500NameBuilder(BCStyle.INSTANCE);
nameBld.addRDN(BCStyle.CN, "cn");
nameBld.addRDN(BCStyle.O, "o");
nameBld.addRDN(BCStyle.NAME, "name");
X500Name principal = nameBld.build();
// Generate the certificate signing request (csr = PKCS10)
String sigAlg = "SHA1withRSA";
JcaContentSignerBuilder csb = new JcaContentSignerBuilder(sigAlg);
ContentSigner cs = csb.build(privateKey);
DERPrintableString password = new DERPrintableString("mychallenge");
PKCS10CertificationRequestBuilder crb = new JcaPKCS10CertificationRequestBuilder(principal, publicKey);
crb.addAttribute((ASN1ObjectIdentifier) PKCSObjectIdentifiers.pkcs_9_at_challengePassword, password);
PKCS10CertificationRequest csr = crb.build(cs);
return csr;
}
//Envelop the CSR
private static CMSEnvelopedData envelopData(byte[] pemCsr) {
CMSTypedData msg = new CMSProcessableByteArray(pemCsr);
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(x509Certificate).setProvider("BC"));
CMSEnvelopedData ed = edGen.generate(msg,new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider("BC").build());
return ed;
}
//Sign the enveloped CSR
private static CMSSignedData signData(byte[] data){
ContentSigner signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(signer, (X509Certificate) x509Certificate));
CMSTypedData cmsdata = new CMSProcessableByteArray(data);
CMSSignedData signedData = generator.generate(cmsdata, true);
return signedData;
}
我还有其他代码准备粘贴(Volley 请求、utils 转换器),但目前可能就足够了。
SCEP 已经在 iOS 设备上运行,所以服务器是干净的。 Ruby 可以创建签名的 PKCS#7,所以我想我的签名步骤没问题。 但是,如果我发送一个空的已签名 PKCS#7,我会出乎意料地遇到同样的错误。
在此先感谢您的帮助。
最佳答案
似乎信封的 ASN1 对于 OpenSSL 不正确。
与此同时,Google Volley 会自动在响应中添加“\n”,这也会引发问题。
关于java - 通过 SCEP 在 Java 中生成 CSR 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24019594/