I'm trying to decrypt a EnvelopedCms that was encrypted using a non-default AlgorithmIdentifier like this:
ContentInfo contentInfo = new ContentInfo(data); EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo, new AlgorithmIdentifier(new System.Security.Cryptography.Oid("2.16.840.1.101.3.4.1.42"))); CmsRecipientCollection recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, certificates); envelopedCms.Encrypt(recipients); byte[] encryptedData = envelopedCms.Encode();
The encryption works as expected. Now when I try to decrypt the envelopedCms
using something like this:
EnvelopedCms envelopedCms = new EnvelopedCms(); envelopedCms.Decode(encryptedData ); envelopedCms.Decrypt(certificates); byte[] decryptedData = envelopedCms.ContentInfo.Content;
I notice that a.) the access to the certificate takes quite long (longer then when using the default AlgorithmIdentifier) and b.) I get this error message:
System.Security.Cryptography.CryptographicException: Access denied
Which, looking at the source where this fails, is probably not the issue. Now I see that I haven't provided the encryption algorithm to use in the decrypt method anywhere and I believe that's the issue but I'm not sure how to specify the AlgorithmIdentifier
for the decryption.
From the documenation I can see that the EnvelopedCms.Decrypt
can take a RecipientInfo
which can specify the algorithm but since we used multiple certificates for the encryption I'm not sure how to build such an object. Ideally I was thinking that the correct RecipientInfo
, containing the actually used AlgorithmIdentifier
, is already contained in the EnvelopedCms.RecipientInfos
array. But it seems like this is not the case.
Can anyone get the decrypt code above working?
1 Answers
Answers 1
Although my answer may lead to some incomplete tangents, I believe that it will get you the same assertion that I have come to. The fact is that I use a X509Store allows me to locate the certificates that my machine has. I then pass the collection into the CmsReceipientCollection with a X509Certificate2Collection that is found from my store.Certificates. This method takes 128ms to execute. HTH!
[TestMethod] public void TestEnvelopedCMS() { X509Store store = new X509Store("MY", StoreLocation.CurrentUser); store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates; X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false); byte[] data = new byte[256]; //lets change data before we encrypt data[2] = 1; ContentInfo contentInfo = new ContentInfo(data); EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo, new AlgorithmIdentifier(new System.Security.Cryptography.Oid("2.16.840.1.101.3.4.1.42"))); CmsRecipientCollection recipients = new CmsRecipientCollection(SubjectIdentifierType.IssuerAndSerialNumber, fcollection); envelopedCms.Encrypt(recipients); byte[] encryptedData = envelopedCms.Encode(); //lets decrypt now envelopedCms.Decode(encryptedData); envelopedCms.Decrypt(fcollection); byte[] decryptedData = envelopedCms.ContentInfo.Content; //grab index from byte[] var item = decryptedData.Skip(2).Take(1).FirstOrDefault(); var item2 = data.Skip(2).Take(1).FirstOrDefault(); Assert.IsTrue(item == item2); }
0 comments:
Post a Comment