«
«
Kullanıcı Masası
Hoşgeldin Ziyaretçi

Kategoriler
NTGFatura Socket İmzalama Aracı

NTGFatura Socket İmzalama Aracı


E-Fatura/E-Arşiv imzalamakla alakalı daha öncede bir kaç makale yazmıştım, ama daha önce yazdığım makaleler PHP odaklı makalelerdi. Bu yazımda ise Soket bağlantıdan bahsetmek istiyorum.

Soket bağlantı ile imza atmak için yapmanız gerek çokta bir şey yok aslında, KamuSM'den aldığınız elektronik imzayı pc'ye taktıktan sonra tek yapmanız gerek yazının sonunda sizlerle paylaşmış olduğum imzalama aracını indirip Java yüklü bir pc'de çalıştırmak, aracı çalıştırdığınız zaman sizden port girmenizi veya varsayılan portu kullanmanızı isteyecektir, ardından 6 haneli KamuSM'den aldığınız e-imzanın şifresini girmenizi isteyecektir. Şifreyi girdikten sonra "IMZALAMAK ICIN VERI BEKLENIYOR..." ibaresini görmeniz gerekiyor, eğer bu ibareyi görmüyorsanız bir sorun var demektir. Bu uyarının çıkmamasının en büyük sebebi Runtime Parameters bölümüne girilen -Xmx256m değerinin eksik olmasıdır, resimli açıklama için inceleyebilirsiniz: https://forum.efatura.gov.tr/view.php?id=327

Her şey hazır sayılır ve faturaları imzalamak için son bir adım kaldı, o da fatura verisini base64 olarak ilgili porta yollama işlemi, bunun için jQuery kullanabilirsiniz veya başka bir yöntem de kullanabilirsiniz.

Örnek jQuery:

Kod Çizelgesi:[Hepsini Seç] 

<!DOCTYPE html>
<head>
    <meta charset="utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function() {
            $('#submit').click(function() {

                let $base64verisi = 'base64 ile encode edilmiş XML verisi...';
                let $rapor = 'E-Arşiv rapor imzalanacaksa burası true olacak fatura imzalanacaksa false olacak...';
                let $seriimza = 'Seri imza atılacaksa true normal imza atılacaksa false olacak...';

                $.ajax({
                    type: "POST",
                    url: 'http://localhost:44444',
                    data: $base64verisi+','+$rapor+','+$seriimza,
                    success: function(cevap) {
                        if(cevap != 'false')
                        {
                            // Gelen veri "cevap" değişkeni içerisinde base64...
                        }
                        else console.log("hata oluştu !");
                    }
                });
            });
        });
    </script>
</head>
<body>
    <button id="submit">Test</button>
</body>
</html>


Örnek Java:


Kod Çizelgesi:[Hepsini Seç] 

package ntg.bls;

import java.awt.GraphicsEnvironment;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.Console;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.List;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import ntg.bls.SampleBase;
import ntg.bls.SmartCardManager;
import tr.gov.tubitak.uekae.esya.api.asn.x509.ECertificate;
import tr.gov.tubitak.uekae.esya.api.common.ESYAException;
import tr.gov.tubitak.uekae.esya.api.smartcard.pkcs11.SmartCardException;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.C14nMethod;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.Context;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.DigestMethod;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.SignatureMethod;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.TransformType;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.XMLSignature;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.XMLSignatureException;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.model.Transform;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.model.Transforms;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.model.xades.ClaimedRole;
import tr.gov.tubitak.uekae.esya.api.xmlsignature.model.xades.SignerRole;

public class anadosya {

    static ServerSocket server;
    static int port 44444;
    static String yeniport;

    static String degistir;
    static String degistirSonuc;
    static List<Stringsonuc;
    static String GelenVeri;
    static String PIN null;
    static String SeriImza;
    static String Rapor;
    static Node eklenecekalan;

    static SampleBase sampleBase;
    
    public static void main(String[] argsthrows ExceptionIOExceptionXMLSignatureExceptionSmartCardExceptionESYAException {

        sampleBase = new SampleBase();

        Console console System.console();
       
        if(console == null && !GraphicsEnvironment.isHeadless()){
            String filename anadosya.class.getProtectionDomain().getCodeSource().getLocation().toString().substring(6);
            Runtime.getRuntime().exec(new String[]{"cmd","/c","start","cmd","/k","java -jar -Dfile.encoding=utf-8 \"" filename "\""});

        }

        System.out.println("VARSAYILAN PORT "+port+" DEGISTIRMEK ISTEMIYORSANIZ BOS BIRAKINIZ...");
        yeniport console.readLine("PORT GIRINIZ: ");
        
        if(!yeniport.isEmpty())
        {
            if (String.valueOf(yeniport).length() < 6
            {
                port Integer.parseInt(yeniport);
                 System.out.println("PORT "+port+" OLARAK GUNCELLENDI...");
            }
            else System.out.println("GIRDIGINIZ PORT COK UZUN OLDUGU ICIN KULLANILMADI, SU AN KULLANIMDA OLAN PORT "+port);

            System.out.println("-------------------------------------------------------------");
        }
        
        PIN = new String(console.readPassword("6 HANELI SIFREYI GIRINIZ: "));
          
        if (PIN != null && String.valueOf(PIN).length() != 6)
        {
            System.out.println("SIFRE 6 HANELI OLMALI ! LUTFEN KAPATIP TEKRAR ACINIZ...");
        }
        else
        {
            server = new ServerSocket(port);
    
            while (true)
            {
                System.out.println("\n");
                System.out.println("-------------------------------------------------------------");
                System.out.println("IMZALAMAK ICIN VERI BEKLENIYOR...");
                Socket socket server.accept();
            
                BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                BufferedWriter outToclient = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8));
    
                while ((inFromClient.readLine()).length() != 0);
    
                StringBuilder payload = new StringBuilder();
                while (inFromClient.ready()) {
                    payload.append((charinFromClient.read());
                }
    
                sonuc = new ArrayList<String>(Arrays.asList(payload.toString().split(",")));
    
                byte[] decodedVeri Base64.getDecoder().decode(sonuc.get(0));
    
                GelenVeri = new String(decodedVeri);
    
                Context context SampleBase.createContext();
                org.w3c.dom.Document dosya SampleBase.parse(GelenVericontext);
    
                Rapor sonuc.get(1);
                SeriImza sonuc.get(2);
    
                System.out.println("IMZALANIYOR...");
    
                try {
    
                    // create signature according to context,
                    // with default type (XADES_BES)
                    XMLSignature signature = new XMLSignature(contextfalse);
    
                    /* Seri İmza */
                    if (Rapor == "true")
                        eklenecekalan dosya.getDocumentElement().getElementsByTagName("baslik").item(0);
                    else if (SeriImza == "true")
                        eklenecekalan dosya.getDocumentElement().getElementsByTagName("oa:Signature").item(0);
                    else
                        eklenecekalan dosya.getDocumentElement().getElementsByTagName("ext:ExtensionContent").item(0);
    
                    eklenecekalan.setTextContent("");
                    eklenecekalan.appendChild(signature.getElement());
    
                    // false-true gets non-qualified certificates while true-false gets qualified ones
                    ECertificate cert SmartCardManager.getInstance().getSignatureCertificate(SampleBase.IS_QUALIFIED, !SampleBase.IS_QUALIFIED);
    
                    // use enveloped signature transform
                    Transforms transforms = new Transforms(context);
                    transforms.addTransform(new Transform(contextTransformType.ENVELOPED.getUrl()));
                    signature.addDocument(""nulltransformsDigestMethod.SHA_256nullfalse);
    
                    //signature.addKeyInfo(new ECertificate(cert.getEncoded()));
    
                    //add signer role information
                    SignerRole rol = new SignerRole(context, new ClaimedRole[]{ new ClaimedRole(context"Tedarikçi") });
                    signature.getQualifyingProperties().getSignedSignatureProperties().setSignerRole(rol);
    
                    signature.setSigningTime(Calendar.getInstance());
    
                    //e-fatura standards want signatureID to be same with cbc:URI
                    // get signatureID from e-fatura
                    String signatureID = ((Element)(dosya.getDocumentElement().getElementsByTagName("cbc:URI").item(0))).getTextContent();
                    String signatureIDwoNumberSign signatureID.substring(1);
                    Element dsSignature = (Element)(dosya.getDocumentElement().getElementsByTagName("ds:Signature").item(0));
                    dsSignature.setAttribute("Id"signatureIDwoNumberSign);
                    dsSignature.setAttribute("xmlns:ds""http://www.w3.org/2000/09/xmldsig#");
                    Element xadesQualifyingProperties = (Element)(dosya.getDocumentElement().getElementsByTagName("xades:QualifyingProperties").item(0));
                    xadesQualifyingProperties.setAttribute("Target""#" signatureIDwoNumberSign);
                    xadesQualifyingProperties.setAttribute("xmlns:xades""http://uri.etsi.org/01903/v1.3.2#");
    
                    // add signing time
                    signature.getSignedInfo().setCanonicalizationMethod(C14nMethod.INCLUSIVE_WITH_COMMENTS);
                    signature.getSignedInfo().setSignatureMethod(SignatureMethod.RSA_SHA256);
    
                    // add certificate to show who signed the document
                    signature.addKeyInfo(cert);
                    
                    signature.sign(SmartCardManager.getInstance().getSigner(PINcert));

                    // now sign it by using smart card
    
                    /* Seri İmza */
                    if (SeriImza == "true") {
                        XMLSignature counterSignature signature.createCounterSignature();
                        counterSignature.getSignedInfo().setSignatureMethod(SignatureMethod.RSA_SHA256);
                        counterSignature.addKeyInfo(new ECertificate(cert.getEncoded()));
                        counterSignature.sign(SmartCardManager.getInstance().getSigner(PINcert));
                    }
                    
                    if (Rapor == "true"signature.upgradeToXAdES_T(); 
                    
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    
                    Source xmlSource = new DOMSource(dosya);
                    StreamResult outputTarget = new StreamResult(outputStream);
                    TransformerFactory.newInstance().newTransformer().transform(xmlSourceoutputTarget);
    
                    String bytes64bytes Base64.getEncoder().encodeToString(outputStream.toByteArray());
    
                    outToclient.write("HTTP/1.1 200 OK\nContent-Type: text/plain; charset=UTF-8\nCache-Control: no-cache\nConnection: closed\nAccess-Control-Allow-Origin: *\n\n");
                    outToclient.write(bytes64bytes);
    
                    /* Karttan cikis yapiliyor */
                    //SmartCardManager.getInstance().logout();
    
                    outToclient.flush();
                    outToclient.close();
                    inFromClient.close();
                    socket.close();
    
                } catch (Exception x) {
                    System.out.println("IMZALAMA HATASI !");
    
                    outToclient.write("HTTP/1.1 200 OK\nContent-Type: text/plain; charset=UTF-8\nCache-Control: no-cache\nConnection: closed\nAccess-Control-Allow-Origin: *\n\n");
                    outToclient.write("false");
                    outToclient.flush();
                    outToclient.close();
                    inFromClient.close();
                    socket.close();
                    x.printStackTrace();
                }
                continue;
            }
        }
    }
}





Aracı indirmek ve kaynak kodlarına erişmek için : https://github.com/3zRasasi/NTGFatura-Socket-Imzalama-Araci

Ayrıca katkılarından ötürü bumblebeey'ye teşekkür ederim.
Yorumlar  (Toplam: 0) Sıralama:
Henüz yorum yapılmamış, ilk yorumu siz yazın.
Yorum Yaz
Onay Kodu .
 
Yücel KAHRAMAN