我将EnvelopedData封装在SignedData中,然后封装在EnvelopedData中。 加密 - >签名 - >加密。但是,当我解密消息并从解密内容中创建CMSSingedData时,我收到错误:
org.bouncycastle.cms.CMSException: IOException reading content.
at org.bouncycastle.cms.CMSUtils.readContentInfo(Unknown Source)
Caused by: java.io.IOException: DER length more than 4 bytes: 98
at org.bouncycastle.asn1.ASN1InputStream.readLength(Unknown Source)
这是代码,我在其中创建EnvelopedData:
CMSSignedDataStreamGenerator signedGenerator;
CMSEnvelopedDataStreamGenerator envelopedGenerator;
try {
signedGenerator = getCMSSignedDataStreamGenerator(builder);
envelopedGenerator = getCMSEnvelopedDataStreamGenerator(builder);
OutputStream envelopedStream2 = envelopedGenerator.open(CMSObjectIdentifiers.signedData,out,settings.getEncryptor());
OutputStream signingStream = signedGenerator.open(CMSObjectIdentifiers.envelopedData,envelopedStream2,encapsulate);
OutputStream envelopedStream1 = envelopedGenerator.open(signingStream,settings.getEncryptor());
content.writeTo(envelopedStream1);
envelopedStream1.close();
signingStream.close();
envelopedStream2.close();
}catch (CMSException e){
throw new IOException(e.toString());
}catch (MessagingException e) {
throw new IOException(e.toString());
}
这是我的测试:
@Test
public void testEncryptSignEncrypt() throws Exception{
Properties props = System.getProperties();
Session session = Session.getDefaultInstance(props, null);
RecipientId recId = new JceKeyTransRecipientId(cert);
MimeMessage msg = new MimeMessage(session, new FileInputStream("EncryptSignEncryptPCKS7"));
SMIMEEnveloped m = new SMIMEEnveloped(msg);
ContentInfo contentInfo = m.toASN1Structure();
EnvelopedData envData = EnvelopedData.getInstance(contentInfo.getContent());
System.out.println("The content of enveloped data " + envData.getEncryptedContentInfo().getContentType());
assertEquals(CMSObjectIdentifiers.signedData, envData.getEncryptedContentInfo().getContentType(), "The content of enveloped data, should be SignedData");
byte[] cont = decrypt(smimeKey,m,cert);
CMSSignedData signedData = new CMSSignedData(cont);
assertEquals(CMSObjectIdentifiers.envelopedData.toString(), signedData.getSignedContentTypeOID(), "The content of signed data, should be enveloped data");
assertEquals(true, verify(signedData), "the message was altered!");
}
private static byte[] decrypt(SmimeKey key, CMSEnvelopedData envelopedData, X509Certificate cert) throws CMSException{
RecipientId recId = new JceKeyTransRecipientId(cert);
RecipientInformationStore recipients = envelopedData.getRecipientInfos();
RecipientInformation recipient = recipients.get(recId);
byte[] cont = recipient.getContent(new JceKeyTransEnvelopedRecipient(smimeKey.getPrivateKey()).setProvider("BC"));
return cont;
}