Asked by:
The operation was canceled by the user in an application that uses digital signature under IIS

Question
-
User-35855200 posted
The idea of the
web app
is to sign documents with adigital signature
that is loaded from asmart card
.It is published and set to work on a
local user
machine. I am usingIIS
for that matter to set thebindings
and enable to acceptclient certificates
.It communicates with a
web app
that is hosted on thecloud
.I am successfully getting the
certificate
from thesmart card
and theprivate key
as well.I use the
private key
to sign the document.private InvoiceResult SignDocument(XmlDocument doc) { InvoiceResult resultValue; try { var (resultValue2, certificate) = GetDefaultCertificateStoredOnTheCard(); resultValue = resultValue2; SignXmlDocumentWithCertificate(doc, certificate); resultValue = InvoiceResult.Success; } catch (Exception ex) { _log.TraceInformation($"Error when compute signature and it is : {ex.Message}"); _log.TraceInformation($"Additional info => stack trace : {ex.StackTrace}"); resultValue = InvoiceResult.CannotSignXmlFiles; } return resultValue; } public (InvoiceResult resultValue, X509Certificate2 cert) GetDefaultCertificateStoredOnTheCard() { var resultValue = InvoiceResult.Success; using X509Store x509Store = new X509Store(StoreName.My, StoreLocation.CurrentUser); X509Store store = x509Store; store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly); X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindByTimeValid, DateTime.Now, true); certs = certs.Find(X509FindType.FindByThumbprint, Settings.Default.Thumbprint, true); if (certs.Count == 0) { resultValue = InvoiceResult.CannotFindSignature; } X509Certificate2 cert = certs[0]; if (cert.HasPrivateKey) { // software cert _ = cert.PrivateKey as RSACryptoServiceProvider; } else { // certificate from smartcard CspParameters csp = new CspParameters(1, "Microsoft Base Smart Card Crypto Provider") { Flags = CspProviderFlags.UseDefaultKeyContainer }; _ = new RSACryptoServiceProvider(csp); } return (resultValue, cert); } private InvoiceResult SignXmlDocumentWithCertificate(XmlDocument xmlDoc, X509Certificate2 cert) { InvoiceResult resultValue = InvoiceResult.Success; SignedXml signedXml = new SignedXml(xmlDoc) { //we will sign it with private key SigningKey = cert.PrivateKey }; if (cert.PrivateKey == null) { resultValue = InvoiceResult.CannotSignXmlFiles; // throw new ArgumentException("Please make sure the application for electronic signatures is installed, so the private key can be obtained from the smart card!"); } Reference reference = new Reference { //sign the entire doc Uri = "" }; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); //PublicKey part RSACryptoServiceProvider rsaprovider = (RSACryptoServiceProvider)cert.PublicKey.Key; RSAKeyValue rkv = new RSAKeyValue(rsaprovider); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); //We add the public key here keyInfo.AddClause(rkv); signedXml.KeyInfo = keyInfo; _log.TraceInformation($"Cert has private key or not? {cert.HasPrivateKey}"); signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. _log.TraceInformation($"It computes the signature succesfully"); XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true)); _log.TraceInformation($"It appends the signature succesfully"); return resultValue; }
It works fine on
Release/Debug
but not inPublish
. It gets apopup
, asks for aPIN
and once thePIN
has been entered the docs are signed.It gets to the
signedxml.ComputeSignature
and it returns an error :The operation was canceled by the user.
Here is the exception that has been thrown :
System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature) at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash) at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash) at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()
The only way I get the same error on
release/debug
is if I cancel the window which asks for aPIN
.It is an
IIS
setting and a permission issue, but I have tried various things to no avail. The certificate can be found if I requireSSL
onClient Side
is ticked and set it toAccept
as in the image :I have also tried exporting the
private key
which I saw on various posts, however, because it is asmart card
I am unable to export thePrivate Key
, I can only use it which is what I am doing with my code.I also tried to run the same app from the .exe which succesfully digitally signs the xml but the window won't even open and asks for the user pin. I even tried to call Powershell and execute the script in that folder but once it is published - it does not execute nor opens a window.
Tuesday, December 10, 2019 8:57 AM
All replies
-
User-719153870 posted
Hi DimitarGrozdanov,
It works fine on
Release/Debug
but not inPublish
. It gets apopup
, asks for aPIN
and once thePIN
has been entered the docs are signed.It gets to the
signedxml.ComputeSignature
and it returns an error :The operation was canceled by the user.
According to the description, you are using an Interactive Service in IIS which "display a user interface and receive user input." , in your case, a popup to receive a PIN input.
As you can see at the start of the document,
"Services cannot directly interact with a user as of Windows Vista. Therefore, the techniques mentioned in the section titled Using an Interactive Service should not be used in new code.".
This kind of technology is outdate and IIS does not support user interaction anymore. That's why your program can work in local but throw error in IIS.
Best Regard,
Yang Shen
Wednesday, December 11, 2019 10:01 AM