🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.lang.delphi
Article #345076

Re: Obsługa szyfrowania \ wysyłki JPK w Delphi (kod źródłowy :))

#345076
From: konsul41
Date: Sat, 20 Aug 2016 18:11
264 lines
10929 bytes
>
> No jak widać z powyższego nie jest to proste :)
>
Pitu Pitu

Ponieważ nie znam za dobrze C# dlatego nie skończone(skończyła się 
licenicja na 2015), samemu dalej ciężko.

Używam Microsoft.XAdes z gita nie ze strony internetowej!

Należy używać NetFrameWork minimum 4.2 z uwagi na
CryptoConfig.AddAlgorithm...





Trzeba zmodyfikować aby działało AES256

do
namespace Microsoft.Xades
{
...
//trzeba dodać
     public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
     {
         public RSAPKCS1SHA256SignatureDescription()
         {
             base.KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
             base.DigestAlgorithm = typeof(SHA256Managed).FullName;
             base.FormatterAlgorithm = 
typeof(RSAPKCS1SignatureFormatter).FullName;
             base.DeformatterAlgorithm = 
typeof(RSAPKCS1SignatureDeformatter).FullName;
 
CryptoConfig.AddAlgorithm(typeof(SHA256CryptoServiceProvider), new 
string[0]);
         }

         public override AsymmetricSignatureFormatter 
CreateFormatter(AsymmetricAlgorithm key)
         {
             if (key == null)
             {
                 throw new ArgumentNullException("key");
             }
             RSAPKCS1SignatureFormatter formatter = new 
RSAPKCS1SignatureFormatter(key);
             formatter.SetHashAlgorithm("SHA256");
             return formatter;
         }
     }
}


Następnie zmienić funkcje ComputeSignature na

  public new void ComputeSignature()
         {
             this.BuildDigestedReferences();
             AsymmetricAlgorithm signingKey = base.SigningKey;
             if (signingKey == null)
             {
                 throw new 
CryptographicException("Cryptography_Xml_LoadKeyFailed");
             }
             if (base.SignedInfo.SignatureMethod == null)
             {
                 if (!(signingKey is DSA))
                 {
                     if (!(signingKey is RSA))
                     {
                         throw new 
CryptographicException("Cryptography_Xml_CreatedKeyFailed");
                     }
                     if (base.SignedInfo.SignatureMethod == null)
                     {
                         base.SignedInfo.SignatureMethod = 
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
                     }
                 }
                 else
                 {
                     base.SignedInfo.SignatureMethod = 
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
                 }
             }
 
CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), 
new string[]
             {
                 "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
             });
             SignatureDescription description = 
CryptoConfig.CreateFromName(base.SignedInfo.SignatureMethod) as 
SignatureDescription;
             if (description == null)
             {
                 throw new 
CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
             }
             HashAlgorithm hash = description.CreateDigest();
             if (hash == null)
             {
                 throw new 
CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
             }
             this.GetC14NDigest(hash, "ds");
             this.m_signature.SignatureValue = 
description.CreateFormatter(signingKey).CreateSignature(hash);
         }




Następnie w zdarzeniu przycisku

private void button_Click(object sender, RoutedEventArgs e)
         {


             // Sign the XML that was just created and save it in a
             // new file.
             OpenFileDialog openFileDialog1 = new OpenFileDialog();
             openFileDialog1.Filter = "XML|*.xml";
             openFileDialog1.Title = "Wybierz plik xml";
             if (openFileDialog1.ShowDialog() == 
System.Windows.Forms.DialogResult.OK)
             {
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);
                 X509Certificate2Collection scollection = 
X509Certificate2UI.SelectFromCollection(fcollection, "Wybierz 
Certyfikat", "Proszę wskazać certyfikat do podpisu", 
X509SelectionFlag.MultiSelection);
                 /* foreach (X509Certificate2 x509 in scollection)
                  {
                      XmlDocument doc = new XmlDocument();
                      byte[] rawdata = x509.RawData;
                      doc.PreserveWhitespace = false;
                      doc.Load(new 
XmlTextReader(System.IO.Path.GetDirectoryName(openFileDialog1.FileName) 
+ "\\initupload.xml"));
                      if (doc.DocumentElement == null) throw new 
InvalidOperationException("Invalid XML document; no root element found.");
                      sign(openFileDialog1.FileName,
 
System.IO.Path.GetDirectoryName(openFileDialog1.FileName) + 
"\\sinitupload.xml",
                           x509);
                      x509.Reset();
                  }
                  store.Close();*/
                 foreach (X509Certificate2 x509 in scollection)
                 {
                     signXades(openFileDialog1.FileName, x509); 
//funkcja podpisująca

                     x509.Reset();
                 }
                 store.Close();
                 System.Environment.Exit(1);
             }
         }

w x509 mamy certyfikat pobrany z karty


następnie podpisywanie

private void signXades(string filepath, X509Certificate2 cert)
         {
             //string exportedKeyMaterial = 
cert.PrivateKey.ToXmlString(true);
             //RSACryptoServiceProvider key = new 
RSACryptoServiceProvider(new CspParameters(24));
             //key.PersistKeyInCsp = false;
            // key.FromXmlString(cert.PrivateKey.ToXmlString(true)); //= 
cert.PrivateKey;//    .FromXmlString(exportedKeyMaterial);
             XadesSignedXml signedXml = new XadesSignedXml(this.doc);
             signedXml.Signature.Id = "id-1234";
             signedXml.SigningKey = cert.PrivateKey;
             signedXml.SignedInfo.CanonicalizationMethod = 
"http://www.w3.org/2001/10/xml-exc-c14n#";
             signedXml.SignedInfo.SignatureMethod = 
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
             Reference reference = new Reference();
             reference.Id = "r-id-1";
             reference.Uri = "";
             reference.Type = "";
             reference.AddTransform(new XmlDsigExcC14NTransform());
 
reference.AddTransform(CreateXPathTransform("not(ancestor-or-self::Signature)"));
             reference.DigestMethod = 
"http://www.w3.org/2001/04/xmlenc#sha256";
             signedXml.AddReference(reference);
             KeyInfo keyInfo = new KeyInfo();
             keyInfo.AddClause(new KeyInfoX509Data(cert));
             signedXml.KeyInfo = keyInfo;
             Cert xadesCert = new Cert();
             xadesCert.IssuerSerial.X509IssuerName = cert.IssuerName.Name;
             xadesCert.IssuerSerial.X509SerialNumber = cert.SerialNumber;
             xadesCert.CertDigest.DigestMethod.Algorithm = 
"http://www.w3.org/2001/04/xmlenc#sha256";
             xadesCert.CertDigest.DigestValue = 
CryptHelper.Sha1(cert.RawData);
             XadesObject xades = new XadesObject();
             xades.QualifyingProperties.Target = string.Format("#{0}", 
signedXml.Signature.Id);
             xades.QualifyingProperties.SignedProperties.Id = 
string.Format("xades-{0}", signedXml.Signature.Id);
 
xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningTime 
= DateTime.Now;
 
xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyImplied 
= true;
 
xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningCertificate.CertCollection.Add(xadesCert);
 
//xades.QualifyingProperties.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier 
= new SignaturePolicyIdentifier();
             DataObjectFormat fmt = new DataObjectFormat();
             fmt.ObjectReferenceAttribute = string.Format("#{0}", 
reference.Id);
             fmt.MimeType = "text/xml";

 
xades.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection.Add(fmt);


             signedXml.AddXadesObject(xades);
             signedXml.ComputeSignature();
             this.doc.DocumentElement.AppendChild(signedXml.GetXml());
             //this.doc.Save(filepath);



             XmlElement xmlDigitalSignature = signedXml.GetXml();

             string filetosave = 
System.IO.Path.GetDirectoryName(filepath) + "\\sinitupload.xml";
             XmlTextWriter xmltw = new XmlTextWriter(filetosave, new 
UTF8Encoding(false));
             doc.WriteTo(xmltw);
             xmltw.Close();
         }

Plik w ten sposób podpisany wysłany do bramki komunikat
"podpis nie jest w formacie xades-base"


Kod jest do ogólnego dostępu i wykorzystania.
w zamian oczekuję na publiczne wskazanie dlaczego nie działa i 
poprawienie oraz publikację na tym forum poprawnego rozwiązania.

Na pohybe firmom żądającym za kilkanaście linijek kodu 5000zł, to nie żart.
Technical Details
Message-ID: <57b89d47$0$12542$65785112@news.neostrada.pl>
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin2!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail
References: <ba903091-a70e-4bf0-a5e0-b7d556d0b612@googlegroups.com> <95558486-40c6-4c81-871c-62e724395d69@googlegroups.com> <np1cd5$ck2$1@portraits.wsisiz.edu.pl> <57b5785f$0$12555$65785112@news.neostrada.pl> <38dbfd8a-d0d4-4413-9b5f-521a49e4a61b@googlegroups.com>

Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin2!goblin1!goblin.stu.neva.ru!newsfeed.neostrada.pl!unt-exc-02.news.neostrada.pl!unt-spo-a-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail
Subject: Re: Obsługa szyfrowania \ wysyłki
 JPK w Delphi (kod źródłowy :))
Newsgroups: pl.comp.lang.delphi
References: <ba903091-a70e-4bf0-a5e0-b7d556d0b612@googlegroups.com> <95558486-40c6-4c81-871c-62e724395d69@googlegroups.com> <np1cd5$ck2$1@portraits.wsisiz.edu.pl> <57b5785f$0$12555$65785112@news.neostrada.pl> <38dbfd8a-d0d4-4413-9b5f-521a49e4a61b@googlegroups.com>
From: "konsul41@wp.pl" <konsul41@wp.pl>
Date: Sat, 20 Aug 2016 20:11:20 +0200
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Thunderbird/45.2.0
MIME-Version: 1.0
In-Reply-To: <38dbfd8a-d0d4-4413-9b5f-521a49e4a61b@googlegroups.com>
Lines: 280
Message-ID: <57b89d47$0$12542$65785112@news.neostrada.pl>
Organization: Telekomunikacja Polska
NNTP-Posting-Host: nat-i488.elomza.pl
X-Trace: 1471716679 unt-rea-a-01.news.neostrada.pl 12542 91.192.89.211:1652
X-Complaints-To: abuse@news.neostrada.pl
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit