E-fatura?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

İlk dikkatimi çeken XmlDocument.Save yapmanız. Bu komut standart writer'ı kullanır, bir önceki mesajımda bahsettiğim new line karekterinizi değiştirir. bu noktada writer nesnesini kendiniz tanımlayıp kullanmalısınız.
Kullanıcı avatarı
cengaver
Üye
Mesajlar: 111
Kayıt: 01 Nis 2014 05:02
Konum: İstanbul

Re: E-fatura?

Mesaj gönderen cengaver »

Bahsettiğiniz değişikliği yaptım fakat bir gelişme olmadı, bir kaç düzenleme daha yapıp aşağıdaki hale getirdim, tekrar inceleyebilirmisiniz gözden kaçırdığım ne olabilir?

Kod: Tümünü seç

public void createEnvelopedBes  ( string aLisansFile         /* Örnek = C:\Sirius_XADES\lisans\lisans.xml */
                                , string aConfigXmlYol       /* Örnek = C:\Sirius_XADES\config\ */
                                , string aPinNo              /* Örnek = 123456 */
                                , bool aNitelik              /* Örnek = False */
                                , string aSignatureID        /* Örnek = RBC0160000000009 */
                                , string aXML                /* Örnek = C:\Temp\Orjinal.XML */
                                , string aSignedXmlFilePath  /* Örnek = C:\Temp\Yeni.XML */
)
{
  LicenseUtil.setLicenseXml(new FileStream(aLisansFile, FileMode.Open)); // Lisans dosyası yükleniyor
  Set_SMART_CARD_PIN(aPinNo);                                            // NESNEYE kartın pin bilgisi veriliyor

  XmlDocument envelopeDoc = new XmlDocument();
  envelopeDoc.PreserveWhitespace = true;
  envelopeDoc.Load (aXML); /* aXML burada full file path olarak değerlendirilir. */

  string aConfigXmlFile = aConfigXmlYol + @"xmlsignature-config.xml";    // xmlsignature-config.xml dosyasının tam olarak nerede olduğu söyleniyor
  Context context = new Context(aConfigXmlYol);    // çalışma klasörü ile içerik oluşturuluyor
  context.Config = new Config(aConfigXmlFile);     // Config dosyası yükleniyor
  context.Document = envelopeDoc;                  // imzalanacak belge içeriği alınıyor

  XMLSignature signature = new XMLSignature(context, false); // create signature according to context, with default type (XADES_BES)
  signature.SigningTime = DateTime.Now;
  signature.Id = "imzaid_" + aSignatureID;

  envelopeDoc.DocumentElement.GetElementsByTagName("ext:ExtensionContent").Item(0).AppendChild(signature.Element); // attach signature to envelope

  Transforms transforms = new Transforms(context);
  transforms.addTransform(new Transform(context, TransformType.ENVELOPED.Url)); // ENVELOPED kısmını burası ayarlıyor.

  signature.addDocument( "", "text/xml", transforms, DigestMethod.SHA_256, false); // URI'si boş referansı burası üretiyor...
  // signature.SignedInfo.SignatureMethod = SignatureMethod.RSA_SHA256;

  /* Smartkart listesi üretiliyor, birden fazla varsa kullanıcı aralarından birini seçecek... */
  String[] terminals = SmartOp.getCardTerminals();
  String terminal;
  if (terminals == null || terminals.Length == 0) throw new SmartCardException("Kart takılı bir e-imza/e-mühür (USB) aygıtı yok");

  int index = 0;
  if (terminals.Length == 1) terminal = terminals[index];
  else {
    index = askOption(null, null, terminals, "Okuyucu Listesi", new String[] { "Tamam" });
    terminal = terminals[index];
  }
  Pair<long, CardType> slotAndCardType = SmartOp.getSlotAndCardType(terminal);
  
  bsc = new P11SmartCard(slotAndCardType.getmObj2());
  bsc.openSession(slotAndCardType.getmObj1());
  List<byte[]> allCerts = bsc.getSignatureCertificates();
  ECertificate signingCert = selectCertificate(aNitelik, false, allCerts); /* Mali mühür için false, false kombinasyonu gerekiyor...  */

  signature.addKeyInfo(signingCert);
  bsc.login(aPinNo);
  mSigner = bsc.getSigner(signingCert, Algorithms.SIGNATURE_RSA_SHA256);

  // İmzala...
  signature.sign(mSigner);

  // CR+LF kullanacak şekilde ayarla 
  XmlWriterSettings ayarlar = new XmlWriterSettings();
  ayarlar.NewLineChars = "\r\n";
  ayarlar.Indent = true;
  ayarlar.Encoding = Encoding.UTF8;
  XmlWriter yazar = XmlWriter.Create(aSignedXmlFilePath, ayarlar);

  // Yeni dosyaya yaz.
  envelopeDoc.WriteTo(yazar); //envelopeDoc.Save(aSignedXmlFilePath); // .save = eski yöntem
  yazar.Close();
}
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

Yine bozar aşağıdaki satır nedeniyle:
ayarlar.NewLineChars = "\r\n";
Encoding bom'suz olmalı, direk utf8 yapmayın.
xmlwriter'ı close etmeden önce flush etmeniz gerekiyor diye hatırlıyorum.
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

cac:Signature içinde bulunan alana referans etmelisiniz, matematiksel doğrulamayı geçtiğinizde bu hatayı alacaksınız.
GİB test portalinden imzalanmış bir fatura alıp incelemenizi tavsiye ederim.
Kullanıcı avatarı
cengaver
Üye
Mesajlar: 111
Kayıt: 01 Nis 2014 05:02
Konum: İstanbul

Re: E-fatura?

Mesaj gönderen cengaver »

mkysoft,

Bahsettiğiniz kontrolleri yaptım, kıyaslamalar için de e-fatura portalinde sunulan imzalı efatura örneklerini kullandım, bunların halâ geçerli olup olmadığını da e-belge görüntüleyici ile kontrol ettim.

3) ESYA API'lerinin <ds:X509SubjectName> tagını üretmediğini fark ettim ama bunu nasıl ekleye bileceğimi bulamadım, bir öneriniz var mı?

1) NewLineChars parametresini de kontrol ettim, şu an itibariyle orjinal XML dosyasının hiç bir şekilde bozulmadığını teyit edebiliyorum. Yani orjinal xml ile imzalı xml arasında imza dışında hiç bir değişiklik yok. TextDiff denen ücretsiz bir yazılım var, ayrıca bununla da kontrol ettim birebir aynı

2)

Kod: Tümünü seç

    <cac:DigitalSignatureAttachment>
      <cac:ExternalReference>
        <cbc:URI>#Signature_RBC0170000000001</cbc:URI>
      </cac:ExternalReference>
    </cac:DigitalSignatureAttachment>
  </cac:Signature>
kısmından bahsediyorsunuz, #Signature_RBC0170000000001 değerini aşağıdaki taglara da yazdım;

a)

Kod: Tümünü seç

<ds:Signature Id="Signature_RBC0170000000001">
b)

Kod: Tümünü seç

<xades:QualifyingProperties xmlns:xades="http://uri.etsi.org/01903/v1.3.2#" Target="#Signature_RBC0170000000001">
C# Kodunun son hali aşağıda yer alıyor;

Kod: Tümünü seç

public void createEnvelopedBes  ( string aLisansFile            /* Misal = C:\Sirius_XADES\lisans\lisans.xml */
                                , string aConfigXmlYol          /* Misal = C:\Sirius_XADES\config\ */
                                , string aPinNo                 /* Misal = 123456 */
                                , bool aNitelik                 /* Misal = False */
                                , string aSignatureID           /* Misal = RBC0160000000009 */
                                , string aXML                   /* Misal = C:\Temp\Orjinal.XML */
                                , string aSignedXmlFilePath     /* Misal = C:\Temp\Yeni.XML */
)
{
    LicenseUtil.setLicenseXml(new FileStream(aLisansFile, FileMode.Open));    // Lisans dosyası yükleniyor
    Set_SMART_CARD_PIN(aPinNo);                                                // NESNEYE kartın pin bilgisi veriliyor
    string aConfigXmlFile = aConfigXmlYol + @"xmlsignature-config.xml";        // xmlsignature-config.xml dosyasının tam olarak nerede olduğu söyleniyor

    XmlDocument envelopeDoc = new XmlDocument();                            // Yeni bir XML nesnesi üretiliyor
    envelopeDoc.PreserveWhitespace = true;                                    // Yükelencek olan belgenin kılına dokunulmayacak demektir...
    envelopeDoc.Load (aXML);                                                // aXML burada full file path olarak değerlendirilir.

    Context context = new Context(aConfigXmlYol);                            //    XML Config klasörü ve içerik oluşturuluyor
    context.Config = new Config(aConfigXmlFile);                            //    Config dosyası yükleniyor
    context.Document = envelopeDoc;                                         //    imzalanacak belge içeriği alınıyor

    string cbc_URI = envelopeDoc.DocumentElement.GetElementsByTagName("cbc:URI").Item(0).InnerText.Trim(); //    ok
    string cbc_URI2 = cbc_URI.Remove(0, 1); // cbc_URI.Substring(2, cbc_URI.Length-1);

    XMLSignature signature = new XMLSignature(context, false);              // Mevcut içeriğe uygun Varsayılan (XADES_BES) türünde bir imza nesnesi üretilir.
    signature.Element.RemoveAttribute("xmlns:ds");
    signature.Element.SetAttribute("Id", cbc_URI2);
    signature.SigningTime = DateTime.Now;
    signature.SignedInfo.SignatureMethod = SignatureMethod.RSA_SHA256;
    signature.SignedInfo.Id = "SignedInfo"; /*1*/

    // add document as reference,
    Transforms transforms = new Transforms(context);
    transforms.addTransform(new Transform(context, TransformType.ENVELOPED.Url)); // ENVELOPED kısmını burası ayarlıyor.
    // Boş ID'li bir referans ekleniyor ( add whole document(="") with envelope transform, with SHA256 ) and don't include it into signature(false)
    signature.addDocument( "", "text/xml", transforms, DigestMethod.SHA_256, false); // URI'si boş referansı burası üretiyor...
    signature.SignedInfo.getReferenceByURI("").Element.RemoveAttribute("Id");

    // xades: SignedDataObjectProperties bu da silinecek...
    //signature.Document.GetElementsByTagName("xades:SignedDataObjectProperties").Item(0).RemoveAll();    BU NOKTADA HATA VERİYOR ?!
    
    // attach signature to envelope structure
    envelopeDoc.DocumentElement.GetElementsByTagName("ext:ExtensionContent").Item(0).AppendChild(signature.Element);
    //add signer role information
    SignerRole rol = new SignerRole(context, new ClaimedRole[] { new ClaimedRole(context, "Tedarikçi") });
    signature.QualifyingProperties.SignedSignatureProperties.SignerRole = rol;

    /* Smartkart listesi üretiliyor, birden fazla varsa kullanıcı aralarından birini seçecek... */
    String[] terminals = SmartOp.getCardTerminals();
    String terminal;
    if (terminals == null || terminals.Length == 0) throw new SmartCardException("Kart takılı bir e-imza/e-mühür (USB) aygıtı yok");
    int index = 0;
    if (terminals.Length == 1) terminal = terminals[index]; else 
    {
        index = askOption(null, null, terminals, "Okuyucu Listesi", new String[] { "Tamam" });
        terminal = terminals[index];
    }
    Pair<long, CardType> slotAndCardType = SmartOp.getSlotAndCardType(terminal);
    bsc = new P11SmartCard(slotAndCardType.getmObj2());
    bsc.openSession(slotAndCardType.getmObj1());
    List<byte[]> allCerts = bsc.getSignatureCertificates();
    ECertificate signingCert = selectCertificate(aNitelik, false, allCerts);

    signature.QualifyingProperties.Target = cbc_URI; // ŞART
    signature.QualifyingProperties.SignedSignatureProperties.SigningTime = signature.SigningTime; // ŞART

    //signingCert.isMaliMuhurCertificate(); // sertifina Dongılı bir mali mühür ise TRUE sonucunu veriyor...

    X509Certificate2 x509 = signingCert.asX509Certificate2();// Bu satır olmayacaksa alttaki satırın alternatifini kulan - 
    AsymmetricAlgorithm aKey = x509.PublicKey.Key; // ALTERNATİFİ = AsymmetricAlgorithm aKey = signingCert.asX509Certificate2().PublicKey.Key;
    signature.addKeyInfo(aKey);
    signature.addKeyInfo(signingCert);

    EName x509SN = signingCert.getSubject(); 
    MessageBox.Show("EKLENECEK : ...<ds:X509SubjectName>" + x509SN.stringValue() + " </ds:X509SubjectName>");
    //signature.KeyInfo.resolveCertificate();
    //signature.KeyInfo.resolvePublicKey();
    //signature.KeyInfo.Element.GetElementsByTagName("ds:X509Data").Item(0).PrependChild(new XmlNode("aa","www"));// AppendChild(aSubjectName);

    bsc.login(aPinNo);
    mSigner = bsc.getSigner(signingCert, Algorithms.SIGNATURE_RSA_SHA256);
    // ValidationResult Verifikasyon = signature.verify( signingCert); // SERTİFİKA

    /* İMZALA *************************************************************************************************************************/
    signature.sign(mSigner);
    // Satır sonlarını CR+LF kullanacak şekilde ayarla 
    XmlWriterSettings ayarlar = new XmlWriterSettings();
    ayarlar.NewLineChars = "\r\n";
    ayarlar.Indent = true;
    ayarlar.Encoding = Encoding.UTF8;
    XmlWriter yazar = XmlWriter.Create(aSignedXmlFilePath, ayarlar);

    // Yeni dosyaya yaz.
    envelopeDoc.WriteTo(yazar); //envelopeDoc.Save(aSignedXmlFilePath); // .save = eski yöntem
    yazar.Close();
    MessageBox.Show("Its Done !");
}
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

Sertifika adı zorunlu değil diye hatırlıyorum, eklemesende sorun olmaz. yinede eklemek istersen aşağıdaki gibi yapabilirsin.

Kod: Tümünü seç

var keyInfo = signature.createOrGetKeyInfo();
for (int i = 0; i < keyInfo.ElementCount; i++)
{
  if (keyInfo.get(i).GetType().IsAssignableFrom(typeof(keyinfo.X509Data)))
  {
    var x509Data = (keyinfo.X509Data)keyInfo.get(i);
    x509Data.add(new keyinfo.x509.X509SubjectName(context, signingCert.getSubject().stringValue()));
    break;
  }
}
Kullanıcı avatarı
cengaver
Üye
Mesajlar: 111
Kayıt: 01 Nis 2014 05:02
Konum: İstanbul

Re: E-fatura?

Mesaj gönderen cengaver »

mkysoft,

İmzalanan XML dosyalarını İmzager ile kontrol ettiğimde
"Sertifika Zinciri Sorunlu. Güvendiğiniz bir sertifika zinciri oluşturulamadı. Sertifikanın kök sertifikası güvenilir Sertifikalarınızdan biri olmayabilir." uyarısını veriyor,

KamuSM'nin mali mühürünü kullanıyoruz, sertifika da bu mali mühürün içinde zaten, acaba xml-signature-config.xml dosyasında bir ayar mı yapmak gerekir?

http://i.hizliresim.com/zaO2A7.jpg
Resim
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

İmzager'de doğrulama yapabilmek için bazı ayarlar yapmalısınız. Sertifika deposu içinden alt kök sertifikaları yüklemeniz gerekiyor zincir problemini çözmek için. Nasıl yapılacağını anlatan bir sayfa vardı kamusm üzerinde, şimdi bulamadım. Bulursam paylaşayım.

Önceki mesajmda bahsettiğim referans hatası alıyorsunuz. Yanlış referans kullanıyorsunuz. İmzalı xml'i yüklerseniz bakalım.
Kullanıcı avatarı
cengaver
Üye
Mesajlar: 111
Kayıt: 01 Nis 2014 05:02
Konum: İstanbul

Re: E-fatura?

Mesaj gönderen cengaver »

mkysoft,

Karşılaştırma yapabilmeniz için İmzayı atan kısım aşağıda yer alıyor, eğer imza atan projenin tamamını isterseniz onu da ekleyebilirim,

Bunun dışında istediğiniz orijinal ve İmzalı XML örneklerini de ekte bulabilirsiniz,

Kod: Tümünü seç

		public void createEnvelopedBes(string aLisansFile            // Örnek = C:\XADES\lisans\lisans.xml   > KamuSM'nin lisans dosyası
										, string aConfigXmlYol          // Örnek = C:\XADES\config\             > xmlsignature-config.xml dosyasının pathi.
										, string aPinNo                 // Örnek = 123456                              > SmartKarttaki pin 
										, bool aNitelik                 // Örnek = False                               > Smartkarttaki sertifikanın nitelik durumu (Mali mühürde false oluyor )
										, string aSignatureID           // Örnek = RBC0160000000009                    > Fatura No
										, string aXML                   // Örnek = C:\Temp\Orjinal.XML                 
										, string aSignedXmlFilePath     // Örnek = C:\Temp\Yeni.XML                    
		)
		{
			LicenseUtil.setLicenseXml(new FileStream(aLisansFile, FileMode.Open));  // Lisans dosyası yükleniyor
			Set_SMART_CARD_PIN(aPinNo);                                             // NESNEYE kartın pin bilgisi veriliyor

			/* Smartkart listesi üretiliyor, birden fazla varsa kullanıcı aralarından birini seçecek... */
			String[] terminals = SmartOp.getCardTerminals();
			String terminal;
			if (terminals == null || terminals.Length == 0) throw new SmartCardException("Kart takılı bir e-imza/e-mühür (USB) aygıtı yok");
			int index = 0;
			if (terminals.Length == 1) terminal = terminals[index];
			else
			{
				index = askOption(null, null, terminals, "Okuyucu Listesi", new String[] { "Tamam" });
				terminal = terminals[index];
			}
			Pair<long, CardType> slotAndCardType = SmartOp.getSlotAndCardType(terminal);
			bsc = new P11SmartCard(slotAndCardType.getmObj2());
			bsc.openSession(slotAndCardType.getmObj1());
			List<byte[]> allCerts = bsc.getSignatureCertificates();
			ECertificate signingCert = selectCertificate(aNitelik, false, allCerts);

			XmlDocument envelopeDoc = new XmlDocument();                            // Yeni bir XML nesnesi üretiliyor
			envelopeDoc.PreserveWhitespace = true;                                  // Yükelencek olan belge olduğu gibi duracak, boşluk ve tab düzeltmesi yapılmayacak demektir...
			envelopeDoc.Load(aXML);                                                // Orjinal XML dosyası yükleniyor.

			string aConfigXmlFile = aConfigXmlYol + @"xmlsignature-config.xml";     // xmlsignature-config.xml dosyasının tam olarak nerede olduğu söyleniyor
			Context context = new Context(aConfigXmlYol);                           // XML Config klasörü ve içerik oluşturuluyor
			context.Config = new Config(aConfigXmlFile);                            // Config dosyası yükleniyor
			context.Document = envelopeDoc;                                         // imzalanacak belge içeriği alınıyor

			XMLSignature signature = new XMLSignature(context, false);              // Mevcut içeriğe uygun Varsayılan (XADES_BES) türünde bir imza nesnesi üretilir.
																					// attach signature to envelope structure
			XmlElement extContent = (XmlElement)envelopeDoc.DocumentElement.GetElementsByTagName("ext:ExtensionContent").Item(0);
			extContent.AppendChild(signature.Element);

			Transforms transforms = new Transforms(context);                              // add document as reference,
			transforms.addTransform(new Transform(context, TransformType.ENVELOPED.Url)); // ENVELOPED kısmını burası ayarlıyor.

			signature.addDocument("", "text/xml", transforms, DigestMethod.SHA_256, false); // Boş ID'li bir referans ekleniyor ( add whole document(="") with envelope transform, with SHA256 ) and don't include it into signature(false)

			//add signer role information
			SignerRole rol = new SignerRole(context, new ClaimedRole[] { new ClaimedRole(context, "Tedarikçi") }); // ileride parametrik olacak...
			signature.QualifyingProperties.SignedSignatureProperties.SignerRole = rol;

			X509Certificate2 x509 = signingCert.asX509Certificate2();  // Bu satır olmayacaksa alttaki satırın alternatifini kulan
			AsymmetricAlgorithm aKey = x509.PublicKey.Key;             // ALTERNATİFİ = AsymmetricAlgorithm aKey = signingCert.asX509Certificate2().PublicKey.Key;
			signature.addKeyInfo(aKey);
			signature.addKeyInfo(signingCert);

			var keyInfo = signature.createOrGetKeyInfo();
			for (int i = 0; i < keyInfo.ElementCount; i++)
			{
				if (keyInfo.get(i).GetType().IsAssignableFrom(typeof(tr.gov.tubitak.uekae.esya.api.xmlsignature.model.keyinfo.X509Data)))
				{
					var x509Data = (tr.gov.tubitak.uekae.esya.api.xmlsignature.model.keyinfo.X509Data)keyInfo.get(i);
					x509Data.add(new tr.gov.tubitak.uekae.esya.api.xmlsignature.model.keyinfo.x509.X509SubjectName(context, signingCert.getSubject().stringValue()));
					break;
				}
			}

			signature.QualifyingProperties.SignedSignatureProperties.SigningTime = DateTime.Now; // signature.SigningTime; // ŞART

			string cbc_URI = envelopeDoc.DocumentElement.GetElementsByTagName("cbc:URI").Item(0).InnerText.Trim(); //	ok
			string cbc_URI2 = cbc_URI.Remove(0, 1); // Baştaki # karakterini siliyor sadece...

			signature.Element.SetAttribute("Id", cbc_URI2);
			signature.QualifyingProperties.Target = cbc_URI; // ŞART

			bsc.login(aPinNo);
			mSigner = bsc.getSigner(signingCert, Algorithms.SIGNATURE_RSA_SHA256);

			signature.sign(mSigner); // İMZALA

			XmlWriterSettings ayarlar = new XmlWriterSettings();
			ayarlar.Indent = true;
			XmlWriter yazar = XmlWriter.Create(aSignedXmlFilePath, ayarlar);

			// Yeni dosyaya yaz.
			envelopeDoc.WriteTo(yazar);
			yazar.Close();
			MessageBox.Show("İmzalandı");

			/*
			ValidationResult Verifikasyon = signature.verify(signingCert);
			__(Verifikasyon.getCheckResult());

			ValidationSystem vs = CertificateValidation.createValidationSystem(tr.gov.tubitak.uekae.esya.api.certificate.validation.policy);
			vs.setBaseValidationTime(DateTime.UtcNow);
			CertificateStatusInfo csi = CertificateValidation.validateCertificate (vs, signingCert);
			*/

			/*			
			signature.Element.RemoveAttribute("xmlns:ds");
			signature.Element.SetAttribute("Id", cbc_URI2);
			signature.SigningTime = DateTime.Now;
			signature.SignedInfo.SignatureMethod = SignatureMethod.RSA_SHA256;
			signature.SignedInfo.Id = "SignedInfo"; //1

			// xades: SignedDataObjectProperties bu da silinecek...
			//signature.Document.GetElementsByTagName("xades:SignedDataObjectProperties").Item(0).RemoveAll();	BU NOKTADA HATA VERİYOR ?!
			//*signature.KeyInfo.add(new KeyValue(context, cert.asX509Certificate2().PublicKey.Key));
			//signingCert.isMaliMuhurCertificate(); // sertifina Dongılı bir mali mühür ise TRUE sonucunu veriyor...
			
			//ValidationResult Verifikasyon = signature.verify( signingCert); // SERTİFİKA

			//ayarlar.NewLineChars = "\r\n";
			//ayarlar.Encoding = Encoding.UTF8;

			*/
		}
Dosya ekleri
Ornek_XML.rar
(194.07 KiB) 418 kere indirildi
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

satır sonu karakteri probleminiz düzelmemiş görünüyor:
Resim

Esya Signature alanını \n oluşturuyor normalde. Elimle düzelttim ancak yine de geçmedi doğrulamadan. Sonra aşağıdaki satırı farkettim, bu satır imzalanmış xml'i hizalayacağı için bozacaktır.
ayarlar.Indent = true;
Onun dışında gözüme çarpan birşey yok.
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

Aşağıdaki kodları kullanarak kaydedin xml'i.

Kod: Tümünü seç

XmlWriterSettings ayarlar = new XmlWriterSettings();
ayarlar.Encoding = new System.Text.UTF8Encoding(false);
ayarlar.NewLineHandling = NewLineHandling.None;
XmlWriter yazar = XmlWriter.Create(aSignedXmlFilePath, ayarlar);
uparlayan
Üye
Mesajlar: 34
Kayıt: 09 Oca 2009 05:48

Re: E-fatura?

Mesaj gönderen uparlayan »

Kodların tamamını biraz daha elden geçirip sadeleştirdim, Mustafa Kerim YILMAZ ve Müslüm ÖZTÜRK'ten de teorik yardım aldım ve sonuç olarak mali mühür kullanarak e-fatura imzası atan sade bir prosedür geliştirebildik. Müslüm beyin gönderdiği örnekler e-defter ile ilgili idi fakat benzer bir yapıya sahipti o nedenle Müslüm ÖZTÜRK'e özellikle teşekkür etmek isterim. Denemelerimde mali mühür ve XML'i doğrulayabildim, e-belge görüntüleyici ile görüntüleyip oradan da doğrulamasını yapabildim. Gönül isterdi ki nitelikli bir sertifika ile de denemeler yapabilelim, elimizde nitelikli bir sertifika olmadığı için bu denemeyi yapamadım fakat büyük ihtimalle o notada da çalışacaktır.

Projenin tamamı KamuSM'nin örnek CSHARP projesinden devşirilmiştir ve ilgili siteden çekilebilir(, eski postlarda link vardı), dolayısıyla Bu prosedürü o projeye yamarsanız sonuç elde edebilirsiniz; Parametrelerin örnekleri de size neyi nereye koyacağınız konusunda bir ip ucu veriyor.

Hayırlı olsun, İşte (Allahın cezası, beyin yakan) ilgili Kod;

Kod: Tümünü seç

public void createEnvelopedBes  ( string aLisansFile         // Örnek = C:\Sirius_XADES\lisans\lisans.xml   > KamuSM'nin lisans dosyası
                                , string aConfigXmlYol       // Örnek = C:\Sirius_XADES\config\             > xmlsignature-config.xml dosyasının pathi.
                                , string aPinNo              // Örnek = 123456                              > SmartKarttaki pin 
                                , bool aNitelik              // Örnek = False                               > Smartkarttaki sertifikanın nitelik durumu (Mali mühürde false oluyor )
                                , string aSignerRol          // Örnek = Tedarikçi
                                , string aXML                // Örnek = C:\Temp\Orjinal.XML                 
                                , string aSignedXmlFilePath  // Örnek = C:\Temp\Yeni.XML                    
)
{
   /* Uğur PARLAYAN */
    LoadLicense(aLisansFile);
    Set_SMART_CARD_PIN(aPinNo);

    XmlDocument envelopeDoc = NewEnvelopeFromFilePath(aXML);
    string cbc_URI = envelopeDoc.DocumentElement.GetElementsByTagName("cbc:URI").Item(0).InnerText.Trim();
    string cbc_URI2 = cbc_URI.Remove(0, 1); // Sadece baştaki # karakterini siliyor...

    // imza nesnesi üretiliyor
    var context = CreateContext(aConfigXmlYol);
    if (context == null)
    {
        MessageBox.Show(string.Format("Context nesnesi oluşturulamadı: {0}", aConfigXmlYol));
        return;
    }
    context.Document = envelopeDoc;
    XMLSignature signature = new XMLSignature(context, false);
    if (envelopeDoc.DocumentElement != null)
    {
        envelopeDoc.DocumentElement.GetElementsByTagName("ext:ExtensionContent").Item(0).AppendChild(signature.Element);
    }
    else { MessageBox.Show("imza dosyaya eklenemedi!"); }

    Transforms transforms = new Transforms(context);
    transforms.addTransform(new Transform(context, TransformType.ENVELOPED.Url));

    signature.addDocument("", ""/*bu da boş kalacak, "text/xml" yazılmayacak...*/, transforms, DigestMethod.SHA_256, false);
    signature.SignedInfo.SignatureMethod = SignatureMethod.RSA_SHA256;
    signature.SignedInfo.CanonicalizationMethod = C14nMethod.INCLUSIVE_WITH_COMMENTS;

    signature.QualifyingProperties.SignedSignatureProperties.SigningTime = DateTime.Now;

    signature.Element.SetAttribute("Id", cbc_URI2);
    signature.QualifyingProperties.Target = cbc_URI; // ŞART

    SignerRole rol = new SignerRole(context, new ClaimedRole[] { new ClaimedRole(context, aSignerRol) });
    signature.QualifyingProperties.SignedSignatureProperties.SignerRole = rol;

    ECertificate cert = SmartCardManager.getInstance().getSignatureCertificate(aNitelik, false);
    signature.addKeyInfo(cert);
    var signer = SmartCardManager.getInstance().getSigner(aPinNo, cert);
    if (signer == null)
    {
        MessageBox.Show("İmza signer için Sertifika dosyası bulunamadı:");
        return;
    }

    KeyValue keyValue = new KeyValue(context, cert.asX509Certificate2().PublicKey.Key);
    signature.KeyInfo.add(keyValue);
    var keyInfo = signature.createOrGetKeyInfo();
    for (int i = 0; i < keyInfo.ElementCount; i++)
    {
        if (keyInfo.get(i).GetType().IsAssignableFrom(typeof(tr.gov.tubitak.uekae.esya.api.xmlsignature.model.keyinfo.X509Data)))
        {
            var x509Data = (tr.gov.tubitak.uekae.esya.api.xmlsignature.model.keyinfo.X509Data)keyInfo.get(i);
            x509Data.add(new tr.gov.tubitak.uekae.esya.api.xmlsignature.model.keyinfo.x509.X509SubjectName(context, cert.getSubject().stringValue()));
            break;
        }
    }
    signature.SigningTime = DateTime.Now;
    signature.sign(signer);

    XmlWriterSettings settings = new XmlWriterSettings { NewLineChars = "\r\n", Indent = true };
    XmlWriter writer = XmlWriter.Create(aSignedXmlFilePath, settings);

    envelopeDoc.WriteTo(writer);
    writer.Close();
}
En son uparlayan tarafından 16 Oca 2017 05:49 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
mkysoft
Kıdemli Üye
Mesajlar: 3103
Kayıt: 26 Ağu 2003 12:35
Konum: Berlin
İletişim:

Re: E-fatura?

Mesaj gönderen mkysoft »

@uparlayan yanlış kodu paylaşmış olabillir misiniz? Writer new line'ları değiştiriyor gibi görünüyor, sorun olabilir.
uparlayan
Üye
Mesajlar: 34
Kayıt: 09 Oca 2009 05:48

Re: E-fatura?

Mesaj gönderen uparlayan »

@mkysoft, kod doğru, test etmek için bahsettiğin satırı şu şekilde değiştirdiğimde de doğrulamayı başardım;

Kod: Tümünü seç

XmlWriterSettings settings = new XmlWriterSettings { NewLineChars = "\n", Indent = true };
Sanırım burada asıl sorun dosyayı yazarken değil, okurken ortaya çıkıyor. Yani eskisinde ben bunu bir text dosya gibi düşünüyordum ve özel bir işlemden geçirmiyordum, o noktada aşağıdaki prosedür ile sorunu çözmüş olduk. Bu noktadan sonra da nasıl kaydettiğin pek fark etmiyor, ki zaten doğrusu da öyle olmalıydı. Yani demek istediğim, mantıken dosyanın BOM'lu olup olmadığının veya UTF-8 ile kodlanıp kodlanmadığının bir öneminin olmaması gerekirdi. Aşağıdaki kod ile bunu halletmiş olduk;

Kod: Tümünü seç

public XmlDocument NewEnvelopeFromFilePath(string path)
{
	if (File.Exists(path))
	{
		byte[] bytes = File.ReadAllBytes(path);
		MemoryStream ms = new MemoryStream(bytes);
		XmlDocument doc = new XmlDocument { PreserveWhitespace = true };
		XmlReader reader = XmlReader.Create(ms);
		doc.Load(reader);
		return doc;
	}
	return null;
}
Resim
bumblebeey
Üye
Mesajlar: 1
Kayıt: 02 Eki 2019 10:09

Re: E-fatura?

Mesaj gönderen bumblebeey »

Arkadaşlar konuyu hortlatmış gibi olucam. ama imzalanan dosyay zaman damgasını nasıl ekliyoruz ? xmlsignature-config.xml içerisinde aşağıdaki alanları doldurmak yeterli oluyormu ?

Kod: Tümünü seç

<timestamp-server>
        <host>http://tzd.kamusm.gov.tr</host>
        <digest-alg>SHA-256</digest-alg>
        <!-- leave below settings blank, if not ESYA Timestamp Server! -->
		<!-- for test timestamp account mail to bilgi@kamusm.gov.tr  -->
        <userid>user_id</userid>
        <password>password</password>
    </timestamp-server>
extra olarak yeterli oluyorsa bunu imzalama aşamasında zaman damgası ekle veya ekleme aşamasında nasıl yönetebiliriz ?
Cevapla