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

Kategoriler
PFX İle E-Fatura İmzalama - PHP
KamuSM'nin test amaçlı kullanım için dağıtmakta olduğu sertifikalara bu adresten ulaşabilirsiniz: http://www.kamusm.gov.tr/hizmetler/test_sistemi/test_sistemi_kullanici_sertifikalari.jsp indirmiş olduğunuz sertifikalar ile PHP ortamında E-Fatura XML dosyalarına rahatlıkla imza atabilirsiniz. Ancak eğer Akis ve benzeri smart kartlar ile imza atacaksanız bu fonksiyonlar işinizi görmeyecektir, kartlar ile imza atmak için bu konumuzu inceleyebilirsiniz: http://yucelkahraman.com.tr/php-icin-e-fatura-imzalama-araci.html


PFX ile E-Fatura İmzalama Fonksiyonları:

Kod Çizelgesi:[Hepsini Seç] 
function imzaBul($objVeri$bul$konum=0$ns='http://www.w3.org/2000/09/xmldsig#')
{
    if ($objVeri instanceof DOMDocument$veri $objVeri;
    else $veri $objVeri->ownerDocument;
    
    if ($veri)
    {
        $xpath = new DOMXPath($veri);
        $xpath->registerNamespace('ntgimza'$ns);
        $bulunan $xpath->query($bul$objVeri);

        if(is_null($konum)) $imzaXml $bulunan;
        else $imzaXml $bulunan->item($konum);

        return $imzaXml;
    }
    return null;
}

function tagOlustur($isim$deger=null$ns=false)
{
    $XMLDSIGNS 'http://www.w3.org/2000/09/xmldsig#';

    $imzveri = new DOMDocument();;

    if($ns == true)
    {
        if (! is_null($deger)) {
            $sonuc $imzveri->createElementNS($XMLDSIGNS$isim$deger);
        } else {
            $sonuc $imzveri->createElementNS($XMLDSIGNS$isim);
        }
    }
    else
    {
        if (! is_null($deger)) {
            $sonuc $imzveri->createElement($isim$deger);
        } else {
            $sonuc $imzveri->createElement($isim);
        }
    }
    return $sonuc;
}

/* Anahtar Okuma Fonksiyonu */
function AnahtarYukle($anahtar$tur 'private'$sifre='')
{
    switch ($tur)
    {
        case 'private':
            if (!$anhtr openssl_get_privatekey($anahtar$sifre)) die('Anahtar çıkarılamıyor');
        break;
        
        default:
            if (!$anhtr openssl_get_publickey($anahtar)) die('Anahtar çıkarılamıyor');
        break;
    }

    return $anhtr;
}

/* PFX İle E-Fatura İmzalama */
function Imzala()
{
    $ENVELOPED 'http://www.w3.org/2000/09/xmldsig#enveloped-signature';
    $ANA_TEMA '<Signature xmlns="http://www.w3.org/2000/09/xmldsig#"></Signature>';
    $URI_ETSI_V132 'http://uri.etsi.org/01903/v1.3.2#';
    $SHA256 'http://www.w3.org/2001/04/xmlenc#sha256';
    $SIGNED_PROP 'http://uri.etsi.org/01903#SignedProperties';
    $RSA_SHA256 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256';
    $C14N_COMMENTS 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments';
    $onek 'ds';
    $bul = array("<S""</S""xmlns=");
    $deg = array("<$onek:S""</$onek:S""xmlns:$onek=");
    $ANA_TEMA str_replace($bul$deg$ANA_TEMA);

    $sertifika_dosya 'sertifika.pfx';
    $sertifika_sifre '123456';

    if (is_file($sertifika_dosya) and !empty($sertifika_sifre))
    {
        if (openssl_pkcs12_read(file_get_contents($sertifika_dosya), $sertifikaSonuc$sertifika_sifre))
        else exit('Sertifika Hatalı !');
    }
    else exit('Sertifika Bulunamadı !');

    $FaturaNo "NTG2017000000001";
    $ana_id 'Signature_'.$FaturaNo;
    $SHA_256 'sha256';
    $dosya_adi 'TemelFatura.xml';

    $dom = new DOMDocument();
    $dom->loadXML($ANA_TEMA);
    $imzaXml $dom->documentElement;

    $veri = new DOMDocument();
    $veri->load($dosya_adi);
    $veriPath = new DOMXPath($veri);

    $imzaXml->setAttribute('Id'$ana_id);

    /* SignedInfo Oluşturuluyor */
    $SignedInfo tagOlustur('ds:SignedInfo'nulltrue);
    $SignedInfo->setAttribute('Id''SignedInfo');
    $imzaXml->appendChild($SignedInfo);

    $CanonicalizationMethod tagOlustur('ds:CanonicalizationMethod');
    $CanonicalizationMethod->setAttribute('Algorithm'$C14N_COMMENTS);
    $SignedInfo->appendChild($CanonicalizationMethod);

    $SignatureMethod tagOlustur('ds:SignatureMethod');
    $SignatureMethod->setAttribute('Algorithm'$RSA_SHA256);
    $SignedInfo->appendChild($SignatureMethod);

     /* Referans 1 Alanı */
    $Reference1 tagOlustur('ds:Reference'nulltrue);
    $Reference1->setAttribute('URI''');
    $Reference1_Transforms1 tagOlustur('ds:Transforms');
    $Reference1_Transforms2 tagOlustur('ds:Transform');
    $Reference1_Transforms2->setAttribute('Algorithm'$ENVELOPED);
    $Reference1_Transforms1->appendChild($Reference1_Transforms2);
    $Reference1->appendChild($Reference1_Transforms1);
    $Reference1_DigestMethod tagOlustur('ds:DigestMethod');
    $Reference1_DigestMethod->setAttribute('Algorithm'$SHA256);
    $Reference1->appendChild($Reference1_DigestMethod);
    $Reference1_DigestValue tagOlustur('ds:DigestValue'base64_encode(hash($SHA_256$veri->C14N(falsetruenullnull), true))); /* Referans 1 Değeri Atanıyor */
    $Reference1->appendChild($Reference1_DigestValue);
    $SignedInfo->appendChild($Reference1);

     /* Referans 2 Alanı */
    $Reference2 tagOlustur('ds:Reference'nulltrue);
    $Reference2->setAttribute('Id''SignedProperties-Reference');
    $Reference2->setAttribute('Type'$SIGNED_PROP);
    $Reference2->setAttribute('URI''#SignedProperties');
    $Reference2_DigestMethod tagOlustur('ds:DigestMethod');
    $Reference2_DigestMethod->setAttribute('Algorithm'$SHA256);
    $Reference2->appendChild($Reference2_DigestMethod);
    $Reference2_DigestValue tagOlustur('ds:DigestValue'nulltrue);
    $Reference2->appendChild($Reference2_DigestValue);
    $SignedInfo->appendChild($Reference2);


    $SignatureValue tagOlustur('ds:SignatureValue');
    $SignatureValue->setAttribute('Id''id1');
    $imzaXml->appendChild($SignatureValue);

    $key AnahtarYukle($sertifikaSonuc['pkey']);
    $privateKey openssl_pkey_get_details($key); 

    $KeyInfo tagOlustur('ds:KeyInfo');

     /* RSA Key Alanı */
    $KeyValue tagOlustur('ds:KeyValue');
    $RSAKeyValue tagOlustur('ds:RSAKeyValue');
    $Modulus tagOlustur('ds:Modulus'chunk_split(base64_encode($privateKey['rsa']['n']), 64""));
    $Exponent tagOlustur('ds:Exponent'chunk_split(base64_encode($privateKey['rsa']['e']), 64""));
    $RSAKeyValue->appendChild($Modulus);
    $RSAKeyValue->appendChild($Exponent);
    $KeyValue->appendChild($RSAKeyValue);
    $KeyInfo->appendChild($KeyValue);

     /* Sertifika X509 */
    $X509Data tagOlustur('ds:X509Data');
    $X509SubjectName tagOlustur('ds:X509SubjectName');
    $X509Certificate tagOlustur('ds:X509Certificate');
    $X509Data->appendChild($X509SubjectName);
    $X509Data->appendChild($X509Certificate);
    $KeyInfo->appendChild($X509Data);

    $KeyInfo->appendChild($X509Data);
    $imzaXml->appendChild($KeyInfo);

    /* Object Alanı */
    $objectNode tagOlustur('ds:Object');
    $imzaXml->appendChild($objectNode);

    $QualifyingProperties tagOlustur('xades:QualifyingProperties');
    $QualifyingProperties->setAttribute('xmlns:xades'$URI_ETSI_V132);
    $QualifyingProperties->setAttribute('Target'$ana_id);

    $objectNode->appendChild($QualifyingProperties);

    $SignedProperties tagOlustur('xades:SignedProperties');
    $SignedProperties->setAttribute('Id''SignedProperties');
    $QualifyingProperties->appendChild($SignedProperties);
    $SignedSignatureProperties tagOlustur('xades:SignedSignatureProperties');
    $SignedProperties->appendChild($SignedSignatureProperties);
    $SigningTime tagOlustur('xades:SigningTime'gmdate(DATE_ATOM));
    $SignedSignatureProperties->appendChild($SigningTime);

    $SigningCertificate tagOlustur('xades:SigningCertificate');
    $SignedSignatureProperties->appendChild($SigningCertificate);

    $Cert tagOlustur('xades:Cert');
    $SigningCertificate->appendChild($Cert);

    $CertDigest tagOlustur('xades:CertDigest');
    $Cert->appendChild($CertDigest);

    $DigestMethod tagOlustur('ds:DigestMethod');
    $DigestMethodAttrAlgorithm $imzaXmlOwn->createAttribute('Algorithm'); $DigestMethodAttrAlgorithm->value $SHA256;
    $DigestMethod->appendChild($DigestMethodAttrAlgorithm);
    $CertDigest->appendChild($DigestMethod);

    /* Object Digest Atanıyor */
    $arr explode("\n"$sertifikaSonuc['cert']);
    array_shift($arr); array_pop($arr);
    $data base64_decode(implode(PHP_EOL$arr));

    $DigestValue tagOlustur('ds:DigestValue'base64_encode(hash('sha256'$datatrue)));
    $CertDigest->appendChild($DigestValue);

    /* Sertifika Getir */
    $sertifikalar $sertifikaSonuc509($sertifikaSonuc['cert'], true);

    $AdDegeri '';
    $X509SrtfkDegeri '';

    /* Public Sertifika Ayarlanıyor */
    foreach ($sertifikalar as $X509Srtfk)
    {
        if ($sertifikaVerisi openssl_x509_parse("-----BEGIN CERTIFICATE-----\n".chunk_split($X509Srtfk64"\n")."-----END CERTIFICATE-----\n"))
        {
            if (! empty($sertifikaVerisi['subject']))
            {
                if (is_array($sertifikaVerisi['subject']))
                {
                    $parcalar = array();
                    foreach ($sertifikaVerisi['subject'] AS $anahtar => $deger)
                    {
                        if (is_array($deger))
                        {
                            foreach ($deger as $degerElm)
                                array_unshift($parcalar"$anahtar=$degerElm");
                        }
                        else array_unshift($parcalar"$anahtar=$deger");
                    }
                    $AdDegeri implode(','$parcalar);
                }
                else $AdDegeri $sertifikaVerisi['issuer'];
            }
            
            if (! empty($sertifikaVerisi['issuer']) && ! empty($sertifikaVerisi['serialNumber']))
            {
                if (is_array($sertifikaVerisi['issuer']))
                {
                    $parcalar = array();
                    foreach ($sertifikaVerisi['issuer'] AS $anahtar => $deger)
                        array_unshift($parcalar"$anahtar=$deger");
                    
                    $issuerDegeri implode(', '$parcalar);
                }
                else $issuerDegeri $sertifikaVerisi['issuer'];
                
                $IssuerSerial tagOlustur('xades:IssuerSerial');
                $Cert->appendChild($IssuerSerial);
                
                $x509Node tagOlustur('ds:X509IssuerName'$issuerDegeri);
                $IssuerSerial->appendChild($x509Node);
                
                $x509Node tagOlustur('ds:X509SerialNumber'$sertifikaVerisi['serialNumber']);
                $IssuerSerial->appendChild($x509Node);
            }
        }
        $X509SrtfkDegeri $X509Srtfk;
    }

    /* Public Sertifika Atanıyor */
    $X509SubjectName->nodeValue $AdDegeri;
    $X509Certificate->nodeValue $X509SrtfkDegeri;

    $SignerRole tagOlustur('xades:SignerRole''');
    $SignedSignatureProperties->appendChild($SignerRole);
    $SignerCalimedRoles tagOlustur('xades:ClaimedRoles''');
    $SignerRole->appendChild($SignerCalimedRoles);
    $SignerCalimedRole tagOlustur('xades:ClaimedRole''Tedarikçi');
    $SignerCalimedRoles->appendChild($SignerCalimedRole);

    /* XML ExtensionContent Alanına İmza Ekleniyor */
    $ExtensionContent $veriPath->query("//ext:ExtensionContent")->item(0);

    $document $ExtensionContent->ownerDocument;
    $signatureElement $document->importNode($imzaXmltrue);
    $ExtensionContent->insertBefore($signatureElement);
    $veriXML $veri->saveXML();

    /* İmza Eklendikten Sonra Veriler Tekrar Okunuyor */
    $yeniVeri = new DOMDocument();
    $yeniVeri->loadXML($veriXML);

    $Reference2_DigestValue imzaBul($yeniVeri'//ntgimza:Reference/ntgimza:DigestValue'1);
    $SignedPropertiesX imzaBul($yeniVeri'//ntgimza:SignedProperties'0$URI_ETSI_V132);

    /* Referans 2 Alanı Verisi Atanıyor */
    $Reference2_DigestValue->nodeValue base64_encode(hash($SHA_256$SignedPropertiesX->C14N(falsetruenullnull), true));

    /* SignedInfo Okunuyor */
    $SignedInfoX imzaBul($yeniVeri'//ntgimza:SignedInfo'0);

    /* SignedInfo İmzalanıyor */
    if (! openssl_sign($SignedInfoX->C14N(falsetruenullnull), $imzaSonuc$key$SHA_256)) {
        die('Veri İmzalama Hatası: ' openssl_error_string() . ' - '.$SHA_256);
    }

    /* SignatureValue Alanına SignedInfo Verisi Atanıyor */
    $SignatureValueX imzaBul($yeniVeri'//ntgimza:SignatureValue'0);
    $SignatureValueX->nodeValue base64_encode($imzaSonuc);

    /* XML Kaydediliyor */
    if (file_exists($dosya_adi)) unlink($dosya_adi);
    $yeniVeri->save($dosya_adi);

    return true;
}
/* PFX İle E-Fatura İmzalama */
Etiketler: , ,
Yorumlar  (Toplam: 2) Sıralama:
Avatar
Mert Deniz 15.01.2019-12:15:01
hem bunda hem diğerinde başarılı olmadım
sanırım kodlar eski biraz
$imzaXml->appendChild($SignedInfo);
yukardaki satırda aşağıdaki hatayı veriyor
------------------------------------------------------------------
Fatal error: Uncaught DOMException: Wrong Document Error in test.php :134 Stack trace: #0
Avatar
ByLegenS 23.01.2019-13:22:24
Kodlarda değişiklik yaptıysanız başka bir yerde hata olabilir, bu verdiğiniz kodlarda sadece imzaXml alanına SignedInfo elemanı ekleniyor.
Yorum Yaz
Onay Kodu .
 
Yücel KAHRAMAN