I'm are receiving signed and encrypted content from a third party. I'm informed that the message structure is PKCS7 (1.2.840.113549.1.7.4 - SignedAndEnvelopedData).
I have successfully decrypted the message content using the following code:
var message = File.ReadAllBytes(@"C:\PKI\receivedMessage");
var cmsEnvelopedData = new CmsEnvelopedData(message);
var recipients = cmsEnvelopedData.GetRecipientInfos();
var cert = GetPfxFileCertFromDisk();
var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(TransformRSAPrivateKey(cert.PrivateKey));
var privateKey = privateKeyInfo.ToAsn1Object().GetDerEncoded();
var myPrivateKey = PrivateKeyFactory.CreateKey(privateKey);
var decryptedMessage = string.Empty;
foreach (RecipientInformation recipientInfo in recipients.GetRecipients())
{
byte[] data = recipientInfo.GetContent(myPrivateKey);
decryptedMessage = Encoding.ASCII.GetString(data);
}
However I did have to make a modification to the Bouncy Castle EnvelopedData class...
public EnvelopedData(
Asn1Sequence seq)
{
int index = 0;
version = (DerInteger) seq[index++];
object tmp = seq[index++];
if (tmp is Asn1TaggedObject)
{
originatorInfo = OriginatorInfo.GetInstance((Asn1TaggedObject) tmp, false);
tmp = seq[index++];
}
recipientInfos = Asn1Set.GetInstance(tmp);
index++; // ADDED THIS LINE to Bouncy Castle implementation
encryptedContentInfo = EncryptedContentInfo.GetInstance(seq[index++]);
if (seq.Count > index)
{
unprotectedAttrs = Asn1Set.GetInstance((Asn1TaggedObject) seq[index], false);
}
}
The structure of the message we are receiving does not appear to be CMSEvelopedData according to RFC 5652, hence adding the additional index++ to enable successful parsing.
I added the additional index++ to skip an item in the ASNSequence containing content marked as ASN.1 1.3.14.3.2.26 (SHA-1), however there is no actual hashed content present.
Of note the ASN1Sequence also contains an item containing Signer Information. I can parse it out to an instance of the SignerInformationStore class.
From here I'm not sure how I can verify the message signature? I have studied examples of using the CmsSignedData class, however I'm still confused about how to create a CmsSignedData instance and verify the message.