Home All Groups Group Topic Archive Search About

ComputeSignature: The Keyset is not defined

Author
8 Jun 2009 1:20 PM
mtrekker
When using ComputeSignature function I always end up with an error: The
keyset is not defined. I am using SmartCard. Any explanation to this error ?

public void Encrypt(string FileName)
        {
            string tempFile = Path.GetTempFileName();
            byte[] file = null;


            using (BinaryReader reader = new BinaryReader(new
FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
            {
                file = new byte[reader.BaseStream.Length];
                reader.Read(file, 0, file.Length);
            }


            //// Signature

            // create ContentInfo (what is signed)
            ContentInfo content = new ContentInfo(file);

            // object representing a signed message
            SignedCms signedMessage = new SignedCms(content);

            // create CmsSigner (who signs)
            CmsSigner signer = new CmsSigner(_signer);

            signer.IncludeOption = X509IncludeOption.EndCertOnly;

            // sign the message
            signedMessage.ComputeSignature(signer, false);

            // create serialized representation
            byte[] signedBytes = signedMessage.Encode();


            //// Encryption

            // create ContentInfo (what is encrypted)
            ContentInfo signedContent = new ContentInfo(signedBytes);

            // object representing an encrypted message
            EnvelopedCms encryptedMessage = new EnvelopedCms(signedContent);

            // add recipients
            CmsRecipientCollection recipients = new CmsRecipientCollection();
            foreach (X509Certificate2 cert in _recipients)
            {
                CmsRecipient recipient = new CmsRecipient(cert);
                recipients.Add(recipient);
            }

            // encrypt the message
            encryptedMessage.Encrypt(recipients);

            // create serialized representation
            byte[] signedAndEncryptedBytes = encryptedMessage.Encode();

            using (BinaryWriter writer = new BinaryWriter(new
FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None)))
            {
                writer.Write(signedAndEncryptedBytes);
            }

            File.Delete(FileName);
            File.Move(tempFile, FileName);
        }

Author
8 Jun 2009 4:05 PM
mtrekker
Am I correct that in this error case I need to set ACLs privileges on the
private key file ? How to do that programmaticaly ???

Show quoteHide quote
"mtrekker" wrote:

> When using ComputeSignature function I always end up with an error: The
> keyset is not defined. I am using SmartCard. Any explanation to this error ?
>
> public void Encrypt(string FileName)
>         {
>             string tempFile = Path.GetTempFileName();
>             byte[] file = null;
>
>
>             using (BinaryReader reader = new BinaryReader(new
> FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
>             {
>                 file = new byte[reader.BaseStream.Length];
>                 reader.Read(file, 0, file.Length);
>             }
>
>
>             //// Signature
>            
>             // create ContentInfo (what is signed)
>             ContentInfo content = new ContentInfo(file);
>
>             // object representing a signed message
>             SignedCms signedMessage = new SignedCms(content);
>            
>             // create CmsSigner (who signs)
>             CmsSigner signer = new CmsSigner(_signer);
>
>             signer.IncludeOption = X509IncludeOption.EndCertOnly;
>
>             // sign the message
>             signedMessage.ComputeSignature(signer, false);
>
>             // create serialized representation
>             byte[] signedBytes = signedMessage.Encode();
>
>
>             //// Encryption
>            
>             // create ContentInfo (what is encrypted)
>             ContentInfo signedContent = new ContentInfo(signedBytes);
>
>             // object representing an encrypted message
>             EnvelopedCms encryptedMessage = new EnvelopedCms(signedContent);
>
>             // add recipients
>             CmsRecipientCollection recipients = new CmsRecipientCollection();
>             foreach (X509Certificate2 cert in _recipients)
>             {
>                 CmsRecipient recipient = new CmsRecipient(cert);
>                 recipients.Add(recipient);
>             }
>            
>             // encrypt the message
>             encryptedMessage.Encrypt(recipients);
>            
>             // create serialized representation
>             byte[] signedAndEncryptedBytes = encryptedMessage.Encode();
>
>             using (BinaryWriter writer = new BinaryWriter(new
> FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None)))
>             {
>                 writer.Write(signedAndEncryptedBytes);
>             }
>
>             File.Delete(FileName);
>             File.Move(tempFile, FileName);
>         }
Are all your drivers up to date? click for free checkup

Author
8 Jun 2009 4:23 PM
mtrekker
In addition, is there any difference when this certificate is connected with
SmartCard ?

Show quoteHide quote
"mtrekker" wrote:

> Am I correct that in this error case I need to set ACLs privileges on the
> private key file ? How to do that programmaticaly ???
>
> "mtrekker" wrote:
>
> > When using ComputeSignature function I always end up with an error: The
> > keyset is not defined. I am using SmartCard. Any explanation to this error ?
> >
> > public void Encrypt(string FileName)
> >         {
> >             string tempFile = Path.GetTempFileName();
> >             byte[] file = null;
> >
> >
> >             using (BinaryReader reader = new BinaryReader(new
> > FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
> >             {
> >                 file = new byte[reader.BaseStream.Length];
> >                 reader.Read(file, 0, file.Length);
> >             }
> >
> >
> >             //// Signature
> >            
> >             // create ContentInfo (what is signed)
> >             ContentInfo content = new ContentInfo(file);
> >
> >             // object representing a signed message
> >             SignedCms signedMessage = new SignedCms(content);
> >            
> >             // create CmsSigner (who signs)
> >             CmsSigner signer = new CmsSigner(_signer);
> >
> >             signer.IncludeOption = X509IncludeOption.EndCertOnly;
> >
> >             // sign the message
> >             signedMessage.ComputeSignature(signer, false);
> >
> >             // create serialized representation
> >             byte[] signedBytes = signedMessage.Encode();
> >
> >
> >             //// Encryption
> >            
> >             // create ContentInfo (what is encrypted)
> >             ContentInfo signedContent = new ContentInfo(signedBytes);
> >
> >             // object representing an encrypted message
> >             EnvelopedCms encryptedMessage = new EnvelopedCms(signedContent);
> >
> >             // add recipients
> >             CmsRecipientCollection recipients = new CmsRecipientCollection();
> >             foreach (X509Certificate2 cert in _recipients)
> >             {
> >                 CmsRecipient recipient = new CmsRecipient(cert);
> >                 recipients.Add(recipient);
> >             }
> >            
> >             // encrypt the message
> >             encryptedMessage.Encrypt(recipients);
> >            
> >             // create serialized representation
> >             byte[] signedAndEncryptedBytes = encryptedMessage.Encode();
> >
> >             using (BinaryWriter writer = new BinaryWriter(new
> > FileStream(tempFile, FileMode.Create, FileAccess.Write, FileShare.None)))
> >             {
> >                 writer.Write(signedAndEncryptedBytes);
> >             }
> >
> >             File.Delete(FileName);
> >             File.Move(tempFile, FileName);
> >         }
Author
8 Jun 2009 8:35 PM
Joe Kaplan
When the private key is on the smart card, you can't adjust the ACL for the
key like you would with a key on the file system that is not protected.
Basically, if the CSP for the card is working and the card is inserted, it
SHOULD just prompt you for the PIN.  How are you building up the signer
object?

Also, have you tested signing with the smart card in other apps (works fine
in Outlook or similar)?

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Show quoteHide quote
"mtrekker" <mtrek***@discussions.microsoft.com> wrote in message
news:BFB32284-C90C-47C6-BF7D-50B680A018CA@microsoft.com...
> In addition, is there any difference when this certificate is connected
> with
> SmartCard ?
>
> "mtrekker" wrote:
>
>> Am I correct that in this error case I need to set ACLs privileges on the
>> private key file ? How to do that programmaticaly ???
>>
>> "mtrekker" wrote:
>>
>> > When using ComputeSignature function I always end up with an error: The
>> > keyset is not defined. I am using SmartCard. Any explanation to this
>> > error ?
>> >
>> > public void Encrypt(string FileName)
>> >         {
>> >             string tempFile = Path.GetTempFileName();
>> >             byte[] file = null;
>> >
>> >
>> >             using (BinaryReader reader = new BinaryReader(new
>> > FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
>> >             {
>> >                 file = new byte[reader.BaseStream.Length];
>> >                 reader.Read(file, 0, file.Length);
>> >             }
>> >
>> >
>> >             //// Signature
>> >
>> >             // create ContentInfo (what is signed)
>> >             ContentInfo content = new ContentInfo(file);
>> >
>> >             // object representing a signed message
>> >             SignedCms signedMessage = new SignedCms(content);
>> >
>> >             // create CmsSigner (who signs)
>> >             CmsSigner signer = new CmsSigner(_signer);
>> >
>> >             signer.IncludeOption = X509IncludeOption.EndCertOnly;
>> >
>> >             // sign the message
>> >             signedMessage.ComputeSignature(signer, false);
>> >
>> >             // create serialized representation
>> >             byte[] signedBytes = signedMessage.Encode();
>> >
>> >
>> >             //// Encryption
>> >
>> >             // create ContentInfo (what is encrypted)
>> >             ContentInfo signedContent = new ContentInfo(signedBytes);
>> >
>> >             // object representing an encrypted message
>> >             EnvelopedCms encryptedMessage = new
>> > EnvelopedCms(signedContent);
>> >
>> >             // add recipients
>> >             CmsRecipientCollection recipients = new
>> > CmsRecipientCollection();
>> >             foreach (X509Certificate2 cert in _recipients)
>> >             {
>> >                 CmsRecipient recipient = new CmsRecipient(cert);
>> >                 recipients.Add(recipient);
>> >             }
>> >
>> >             // encrypt the message
>> >             encryptedMessage.Encrypt(recipients);
>> >
>> >             // create serialized representation
>> >             byte[] signedAndEncryptedBytes = encryptedMessage.Encode();
>> >
>> >             using (BinaryWriter writer = new BinaryWriter(new
>> > FileStream(tempFile, FileMode.Create, FileAccess.Write,
>> > FileShare.None)))
>> >             {
>> >                 writer.Write(signedAndEncryptedBytes);
>> >             }
>> >
>> >             File.Delete(FileName);
>> >             File.Move(tempFile, FileName);
>> >         }
Author
9 Jun 2009 6:51 AM
mtrekker
I found out that I need to use PKCS11 provider to access my SmartCard. Any
suggestions how to start investigating ?

Show quoteHide quote
"Joe Kaplan" wrote:

> When the private key is on the smart card, you can't adjust the ACL for the
> key like you would with a key on the file system that is not protected.
> Basically, if the CSP for the card is working and the card is inserted, it
> SHOULD just prompt you for the PIN.  How are you building up the signer
> object?
>
> Also, have you tested signing with the smart card in other apps (works fine
> in Outlook or similar)?
>
> --
> Joe Kaplan-MS MVP Directory Services Programming
> Co-author of "The .NET Developer's Guide to Directory Services Programming"
> http://www.directoryprogramming.net
> "mtrekker" <mtrek***@discussions.microsoft.com> wrote in message
> news:BFB32284-C90C-47C6-BF7D-50B680A018CA@microsoft.com...
> > In addition, is there any difference when this certificate is connected
> > with
> > SmartCard ?
> >
> > "mtrekker" wrote:
> >
> >> Am I correct that in this error case I need to set ACLs privileges on the
> >> private key file ? How to do that programmaticaly ???
> >>
> >> "mtrekker" wrote:
> >>
> >> > When using ComputeSignature function I always end up with an error: The
> >> > keyset is not defined. I am using SmartCard. Any explanation to this
> >> > error ?
> >> >
> >> > public void Encrypt(string FileName)
> >> >         {
> >> >             string tempFile = Path.GetTempFileName();
> >> >             byte[] file = null;
> >> >
> >> >
> >> >             using (BinaryReader reader = new BinaryReader(new
> >> > FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
> >> >             {
> >> >                 file = new byte[reader.BaseStream.Length];
> >> >                 reader.Read(file, 0, file.Length);
> >> >             }
> >> >
> >> >
> >> >             //// Signature
> >> >
> >> >             // create ContentInfo (what is signed)
> >> >             ContentInfo content = new ContentInfo(file);
> >> >
> >> >             // object representing a signed message
> >> >             SignedCms signedMessage = new SignedCms(content);
> >> >
> >> >             // create CmsSigner (who signs)
> >> >             CmsSigner signer = new CmsSigner(_signer);
> >> >
> >> >             signer.IncludeOption = X509IncludeOption.EndCertOnly;
> >> >
> >> >             // sign the message
> >> >             signedMessage.ComputeSignature(signer, false);
> >> >
> >> >             // create serialized representation
> >> >             byte[] signedBytes = signedMessage.Encode();
> >> >
> >> >
> >> >             //// Encryption
> >> >
> >> >             // create ContentInfo (what is encrypted)
> >> >             ContentInfo signedContent = new ContentInfo(signedBytes);
> >> >
> >> >             // object representing an encrypted message
> >> >             EnvelopedCms encryptedMessage = new
> >> > EnvelopedCms(signedContent);
> >> >
> >> >             // add recipients
> >> >             CmsRecipientCollection recipients = new
> >> > CmsRecipientCollection();
> >> >             foreach (X509Certificate2 cert in _recipients)
> >> >             {
> >> >                 CmsRecipient recipient = new CmsRecipient(cert);
> >> >                 recipients.Add(recipient);
> >> >             }
> >> >
> >> >             // encrypt the message
> >> >             encryptedMessage.Encrypt(recipients);
> >> >
> >> >             // create serialized representation
> >> >             byte[] signedAndEncryptedBytes = encryptedMessage.Encode();
> >> >
> >> >             using (BinaryWriter writer = new BinaryWriter(new
> >> > FileStream(tempFile, FileMode.Create, FileAccess.Write,
> >> > FileShare.None)))
> >> >             {
> >> >                 writer.Write(signedAndEncryptedBytes);
> >> >             }
> >> >
> >> >             File.Delete(FileName);
> >> >             File.Move(tempFile, FileName);
> >> >         }
>
>
Author
9 Jun 2009 2:56 PM
Joe Kaplan
So, there is no Windows CSP support for your smart card?  That's a little
strange on a Windows machine but I suppose it is possible.

From what I can tell, the CmsSigner object only supports private keys that
are stored with normal Windows key containers or protected with via Windows
CSPs, so I don't see how you'll be able to make this work.  The only thing I
can think of would be to find a .NET PKCS#11 library that will allow you to
access the private key on the smart card, then create an in memory key
container and somehow use that to build up the certificate object you use to
create the CmsSigner.  However, I'm not really sure about if this would even
work.  I've not seen this scenario attempted.

Ideally you'd have a CSP driver for your card instead.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
Show quoteHide quote
"mtrekker" <mtrek***@discussions.microsoft.com> wrote in message
news:CA826B60-5A39-45D0-AEB8-DBF25EC0EF9E@microsoft.com...
>I found out that I need to use PKCS11 provider to access my SmartCard. Any
> suggestions how to start investigating ?
>
> "Joe Kaplan" wrote:
>
>> When the private key is on the smart card, you can't adjust the ACL for
>> the
>> key like you would with a key on the file system that is not protected.
>> Basically, if the CSP for the card is working and the card is inserted,
>> it
>> SHOULD just prompt you for the PIN.  How are you building up the signer
>> object?
>>
>> Also, have you tested signing with the smart card in other apps (works
>> fine
>> in Outlook or similar)?
>>
>> --
>> Joe Kaplan-MS MVP Directory Services Programming
>> Co-author of "The .NET Developer's Guide to Directory Services
>> Programming"
>> http://www.directoryprogramming.net
>> "mtrekker" <mtrek***@discussions.microsoft.com> wrote in message
>> news:BFB32284-C90C-47C6-BF7D-50B680A018CA@microsoft.com...
>> > In addition, is there any difference when this certificate is connected
>> > with
>> > SmartCard ?
>> >
>> > "mtrekker" wrote:
>> >
>> >> Am I correct that in this error case I need to set ACLs privileges on
>> >> the
>> >> private key file ? How to do that programmaticaly ???
>> >>
>> >> "mtrekker" wrote:
>> >>
>> >> > When using ComputeSignature function I always end up with an error:
>> >> > The
>> >> > keyset is not defined. I am using SmartCard. Any explanation to this
>> >> > error ?
>> >> >
>> >> > public void Encrypt(string FileName)
>> >> >         {
>> >> >             string tempFile = Path.GetTempFileName();
>> >> >             byte[] file = null;
>> >> >
>> >> >
>> >> >             using (BinaryReader reader = new BinaryReader(new
>> >> > FileStream(FileName, FileMode.Open, FileAccess.Read,
>> >> > FileShare.Read)))
>> >> >             {
>> >> >                 file = new byte[reader.BaseStream.Length];
>> >> >                 reader.Read(file, 0, file.Length);
>> >> >             }
>> >> >
>> >> >
>> >> >             //// Signature
>> >> >
>> >> >             // create ContentInfo (what is signed)
>> >> >             ContentInfo content = new ContentInfo(file);
>> >> >
>> >> >             // object representing a signed message
>> >> >             SignedCms signedMessage = new SignedCms(content);
>> >> >
>> >> >             // create CmsSigner (who signs)
>> >> >             CmsSigner signer = new CmsSigner(_signer);
>> >> >
>> >> >             signer.IncludeOption = X509IncludeOption.EndCertOnly;
>> >> >
>> >> >             // sign the message
>> >> >             signedMessage.ComputeSignature(signer, false);
>> >> >
>> >> >             // create serialized representation
>> >> >             byte[] signedBytes = signedMessage.Encode();
>> >> >
>> >> >
>> >> >             //// Encryption
>> >> >
>> >> >             // create ContentInfo (what is encrypted)
>> >> >             ContentInfo signedContent = new
>> >> > ContentInfo(signedBytes);
>> >> >
>> >> >             // object representing an encrypted message
>> >> >             EnvelopedCms encryptedMessage = new
>> >> > EnvelopedCms(signedContent);
>> >> >
>> >> >             // add recipients
>> >> >             CmsRecipientCollection recipients = new
>> >> > CmsRecipientCollection();
>> >> >             foreach (X509Certificate2 cert in _recipients)
>> >> >             {
>> >> >                 CmsRecipient recipient = new CmsRecipient(cert);
>> >> >                 recipients.Add(recipient);
>> >> >             }
>> >> >
>> >> >             // encrypt the message
>> >> >             encryptedMessage.Encrypt(recipients);
>> >> >
>> >> >             // create serialized representation
>> >> >             byte[] signedAndEncryptedBytes =
>> >> > encryptedMessage.Encode();
>> >> >
>> >> >             using (BinaryWriter writer = new BinaryWriter(new
>> >> > FileStream(tempFile, FileMode.Create, FileAccess.Write,
>> >> > FileShare.None)))
>> >> >             {
>> >> >                 writer.Write(signedAndEncryptedBytes);
>> >> >             }
>> >> >
>> >> >             File.Delete(FileName);
>> >> >             File.Move(tempFile, FileName);
>> >> >         }
>>
>>

Bookmark and Share