0

I've a problem that occurs when getting certificate and putting to xml file. Should I use private key for signing? I see only public key in certificate. There is no private key in my certificate.

                        byte[] ckaIdd = objectAttributess[0].GetValueAsByteArray();
                        string ckaLabel = objectAttributess[1].GetValueAsString();
                        byte[] ckaValue = objectAttributess[2].GetValueAsByteArray();
                        var _rawData = ckaValue ?? throw new ArgumentNullException(nameof(ckaValue));
                        var _parsedCertificate = new X509Certificate2(_rawData);
                        ECertificate cert = new ECertificate(_parsedCertificate.GetRawCertData());

                        string signatureListString = "";
                        XmlDocument document = new XmlDocument();
                        document.Load(@"C:\Users\MyUser\Desktop\myfile.xml");
                        Esya e = new Esya();
                        Context context = e.CreateContext();
                        context.Document = document;
                        XMLSignature signature = new XMLSignature(context, false);

                        signature.addKeyInfo(new ECertificate(cert.getEncoded()));

                        //signature.sign(v);  << ! My problem is with this line

                        var inv = (XmlElement)signature.Document.GetElementsByTagName("Invoice")[0];
                        signatureListString += inv.OuterXml + "\n";

                        var elementCount = (XmlElement)document.GetElementsByTagName("ElementCount")[0];
                        if (elementCount != null)
                        {
                            elementCount.InnerText = "1";
                        }

                        var element = (XmlElement)document.GetElementsByTagName("ElementList")[0];
                        if (element != null)
                        {
                            element.InnerXml = signatureListString;
                        }

                        var xmlPageSettings = document.GetElementsByTagName("Invoice");
                        foreach (XmlElement xmlElement in xmlPageSettings)
                        {
                            xmlElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
                            xmlElement.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
                        }

                        session.Logout();
                        return cert;
                    }
                }

What should I do with signature.sign(v);? How can I add signature to xml file?

TEngineer
  • 95
  • 1
  • 18
  • Yes, a private key is required for signing. – bartonjs Apr 06 '18 at 15:02
  • But the private key in the certificate appears to be false. What can I do about it? – TEngineer Apr 06 '18 at 15:25
  • That depends on how you expect to talk to your HSM. I see quite a lot of cert cloning going on. Maybe however you originally got `_rawData` had the ability to reference the private key. Maybe a Windows cert store has a linking entry from the cert you expect to the HSM. – bartonjs Apr 06 '18 at 15:32
  • There is [Pkcs11Interop.X509Store](https://github.com/Pkcs11Interop/Pkcs11Interop.X509Store) project that does all the heavy lifting for you. For more details [take a look at my older answer to similar question](https://stackoverflow.com/a/46440711/3325704). – jariq Apr 06 '18 at 21:05
  • @jariq I am trying to make an example from the Pkcs11Interop.X509Store project. I manage the device using the Pkcs11Admin project. But the certificate shows private keys false. I do not know how to use private keys. – TEngineer Apr 07 '18 at 06:00
  • @BartonJS, I can get certifications. But I can not get the private keys. The device is away and I am trying to reach it with a client. – TEngineer Apr 07 '18 at 06:03
  • 2
    @TEngineer X509Certificate2::PrivateKey can be used only with CSP/CNG based keys. You cannot use with PKCS#11 based keys. That's one of the reasons why I've started Pkcs11Interop.X509Store project. – jariq Apr 07 '18 at 15:49
  • I can not apply the Pkcs11Interop.X509Store project. My Projem Framework 4.5. But I think 4.6 is necessary. How should I follow your path? – TEngineer Apr 10 '18 at 06:05

1 Answers1

1

You have to implement class inherited from System.Security.Cryptography.RSA class, use Pkcs11Interop in its implementation and then use instance of your custom class as a SigningKey.

jariq
  • 11,681
  • 3
  • 33
  • 52
  • You used public key for this operation. base.KeySizeValue = _certContext.CertificateInfo.ParsedCertificate.GetRSAPublicKey().KeySize; When used in this way : signedXml.ComputeSignature() >> does not calculate key value.They said it should be a private key for signing, but I can not get a private key. – TEngineer Apr 13 '18 at 04:24