I have tried to use the System.Security.Cryptography.Xml.SignedXml class
to sign an Xml message with Xml-DSIG and using an Enveloped signature type
and the sha1RSA algorithm. Everything works fine with soft certificates
and some smartcard based certificates. I'm using X509Certificate2 to hold
the certificates. My problem is that our customers is forced (by law!) to
use a smart-card based personal certificate with strong protection. That
is a certificate that can't be accessed without the user being informed.
If a message is to be signed, the user will have to punch his pin code for
every message he?s signing. When I try to get the
X509Certificate2.PrivateKey property to set the SigningKey property in the
SignedXml class, it fails. I found a link to a message indicating the
reason why: http://www.ureader.com/message/200413.aspx. It says there:
"noticed that the CryptAcquireCertificatePrivateKey() call was using a
"silent" flag". It looks like the X509Certificate2 class is using
CryptoApi, and the PrivateKey property's get method is using
CryptAcquireCertificatePrivateKey() with the second parameter including
the CRYPT_ACQUIRE_SILENT_FLAG. That will not work with these certificates.
Now to my question: Is there any way to circumvent this? If the SignedXml
class could compute and expose the Hash-value, I could use InterOp and
write a small c++ routine that signs the hash, and returns the signature,
but it looks like the ComputeSignature is an atomic operation preventing
any customization. I already have working c++ code for signing a hash
using certificates with strong protection, using CryptoApi, but I hoped I
didn't have to write all the Xml-handling myself, but could use the
SignedXml class for that. Or most preferable: Force X509Certificate2 to
allow the CSP to show the PIN-dialog before returning the algorithm.
Regards
Rune Nergard