Rámec digitálního podepisování konvencí otevřených balíčků

 

David Meltzer a Andrey Shur
Microsoft Corporation

Dne

Platí pro:
   Architektura digitálního podepisování OPC
   Standard digitálního podpisu W3C XML
   Microsoft .NET 3.0 Framework

Shrnutí: Popisuje architekturu digitálního podepisování OPC, poskytuje přehled komponent balíčku a podpůrných služeb a příklady zásad podepisování a jejich implementace. (12 tištěných stránek)

Obsah

Úvod
Komponenty architektury digitálního podepisování OPC
   Standard digitálního podpisu XML
   Reprezentace digitálních podpisů v balíčcích
   Podepisování částí a relací
Podpora programování pro podpisy balíčků
   Podpisové části balíčku a relace
   Ověřování certifikátů a podpisů
Zásady podepisování aplikací
   Dokumenty XPS
   Podpora programování pro podpisy XPS
Reference

Úvod

Model balení určený konvencí OPC (Open Packaging Conventions) popisuje balíčky, části a relace. Balíčky obsahují části, které obsahují obsah a prostředky. Relace jsou definovány pro propojení balíčku s částmi a pro propojení různých částí v balíčku.

Tento článek popisuje architekturu digitálního podepisování OPC a poskytuje přehled komponent balíčku a podpůrných služeb a příklady zásad podepisování a jejich implementace.

Podpisová architektura zahrnuje infrastrukturu pro reprezentaci digitálních podpisů a služby pro vytváření a ověřování podpisů. Podpisová architektura umožňuje použití standardu digitálního podpisu XML W3C na části balíčku a relace.

Pomocí podpisové architektury vlastníci balíčků formátů definují a implementují zásady podepisování specifické pro jejich formáty. Zásady určují, jak podepsat a ověřit integrální obsah konkrétních formátů, a ztělesňují, jak se podpisy používají pro různé pracovní postupy. Ve skutečnosti může pro jeden formát existovat několik zásad definovaných pro použití v různých fázích životního cyklu dokumentu.

Zásady podepisování pro formát založený na balíčku se vyjadřují z hlediska podpisových částí a relací a případně dalších charakteristik dokumentu (například ověření zamýšleného zobrazovacího zařízení, hloubky barev nebo verze aplikace). Zásady podepisování určují, které součásti dokumentu se mají podepsat a které se mají ponechat bez znaménka(pokud vůbec). Můžete například implementovat zásadu podepisování, která umožňuje přidání nových částí a relací do balíčku, nebo může způsobit zneplatnění podpisu, pokud se do balíčku přidají nové části nebo podpisy.

Tento článek předpokládá znalost specifikace Open Packaging Conventions a W3C Recommendation XML-Signature Syntax and Processing.

Komponenty architektury digitálního podepisování OPC

Standard digitálního podpisu XML

Podpisová architektura pro balíčky používá standard digitálního podpisu XML, jak je definováno v doporučení W3C XML syntaxe a zpracování podpisu. Toto doporučení určuje syntaxi XML a pravidla zpracování pro vytváření a ukládání digitálních podpisů.

Standard definuje typ elementu podpisu XML, schéma a požadavky na shodu pro podepisování a ověřování jakéhokoli druhu digitálního prostředku. Schéma také definuje prvky pro odkazování na prostředky a určení algoritmů souvisejících s podpisy.

Funkce digitálních podpisů

Digitální podpis lze použít k určení, jestli se podepsaný obsah od podepsání změnil. Podpis obsahuje manifest obsahu, který se zatřiďuje podle dobře známého algoritmu a při vytvoření se uloží do podpisu. Pokud chcete zjistit, jestli se obsah změnil, znovu se vytvoří hodnota hash podepsaného obsahu a porovná se s hodnotou hash uloženou v podpisu.

Digitální podpis lze také použít k identifikaci podepisující osoby obsahu. Identita podepisující osoby je reprezentována certifikátem přidruženým k podpisu. Certifikát může být vložen do podpisu nebo dostupný jinde.

Digitální podpis "nezamkne" dokument ani nezpůsobí jeho šifrování (i když už může být zašifrovaný). Po podepsání zůstane obsah dokumentu beze změny. Digitální podpisy nezabrání zobrazení podepsaného obsahu nezamýšlenými uživateli.

Reprezentace digitálních podpisů v balíčcích

Aplikace začleňují digitální podpisy do balíčku pomocí zadané konfigurace částí a relací.

Podpisová architektura používá elementy a atributy z oboru názvů balení, kde to povoluje standard digitálního podpisu XML. Prvky podpisu definované v oboru názvů balení podporují funkce specifické pro balíček, které rozšiřují standard, aniž by mu odporovalo. Souhrn doplňků najdete v části "Úpravy specifikace digitálního podpisu XML" specifikace OPC.

Součásti balíčku definované pro podpisovou architekturu jsou část Origin, část Podpis XML a část Certifikát. Každý z nich má dobře definovaný typ obsahu. Dobře definované typy relací se používají pro propojení podpisových částí v balíčku, jak je uvedeno v dodatku H " Standardní obory názvů a typy obsahu" specifikace OPC.

Část původu digitálního podpisu

Část Původ digitálního podpisu je výchozím bodem pro procházení podpisů v balíčku. Část Původ digitálního podpisu je cílená z kořenového adresáře balíčku pomocí vztahu Původ digitálního podpisu . Více částí podpisu může být zacíleno z části Původ. Pokud balíček neobsahuje žádné podpisy, část Origin nebude k dispozici.

Digitální podpis – část s podpisem XML

Části podpisu XML digitálního podpisu obsahují značky definované ve standardu W3C Digital Signature a také v oboru názvů balení. Části jsou zacílené z kódu XML části Původ digitálního podpisu s vztahem Digitální podpis .

Část certifikátu digitálního podpisu

Certifikát X.509 vyžadovaný pro identifikaci podepisující osoby, pokud je umístěn v balíčku, může být vložen v části Podpis XML nebo uložen v samostatné části certifikátu. Volitelná část Certifikát je cílená z části Podpis XML s vztahem Certifikátu digitálního podpisu . Část Certifikát je možné sdílet mezi několika částmi podpisu.

Vlastní podpisové části

Vlastní části podpisu (specifické pro aplikaci) jsou povoleny, ale nejsou zpracovávány podpisovou architekturou. Část podpisu, která obsahuje jinou formu podpisu než podpis XML, musí být identifikována vlastním typem obsahu. Kromě toho musí být relace s vlastním typem relace použita k cílení na část z části Původ digitálního podpisu.

Podepisování částí a relací

Standard digitálního podpisu XML umožňuje podepisování adresovatelných prostředků, které jsou pro balíček součástí. Podpisová architektura umožňuje podepisování částí. Relace v balíčku, uložené v části relace, mohou být podepsány všechny najednou nebo je možné zadat podmnožinu relací pro podepsání.

Typ obsahu části je podepsán spolu s obsahem části, aby se zajistilo, že část v platně podepsaném balíčku bude použita nebo vykreslena podle očekávání. Vzhledem k tomu, že typ obsahu není adresovatelným prostředkem, používá se k podepisování hodnoty typu obsahu přístup specifický pro balíček. Když je balíček podepsaný, typ obsahu každé podepsané části je uložen v komponentě dotazu identifikátoru URI odkazující na podepsanou část. Když je balíček spotřebován, OPC Digital Signing Framework používá hodnotu typu obsahu k zajištění, že typ obsahu části se nezměnil od podepsání části.

Pokud je část relací podepsaná jako celek, jsou podepsány všechny relace definované v této části. Pro podporu zásad podepisování, které umožňují změnu určitého obsahu balíčku bez zneplatnění podpisu, podpisová architektura poskytuje mechanismus pro podepisování zadaných relací. K podepisování zadaných relací používá podpisová architektura speciální transformaci, transformaci relací (viz Transformační algoritmy).

Transformace relací vytvoří část relací obsahující pouze zadanou sadu relací. Získaná část relace se používá k podepisování a při ověřování podpisu.

Podpora programování pro podpisy balíčků

K podepisování a ověřování podpisů mohou aplikace používat třídy .NET 3.0 PackageDigitalSignatureManager. Třídy specifické pro balíček, definované v oboru názvů System.IO.Packaging , vycházejí z tříd digitálních podpisů rozhraní Microsoft .NET 3.0 Framework definovaných v oboru názvůSystem.Security.Cryptography.Xml .

PackageDigitalSignatureManager Třída se používá k vytváření a ověřování podpisů a umísťování infrastruktury podpisů do balíčku. Podpis je reprezentován objekt založený na PackageDigitalSignature třídy.

Podpisové části balíčku a relace

Aplikace definuje seznam částí a relací, které se mají podepsat podle zásad podepisování. Aplikace pak volá Metodu PackageDigitalSignatureManager.Sign() k vytvoření podpisu a přidání infrastruktury podpisů do balíčku.

Následující ukázkový kód ukazuje podepsání všech částí balíčku s výjimkou částí relací, podepsání všech existujících relací pocházejících z kořenového adresáře balíčku a vložení certifikátu použitého k podepisování v části Podpis XML. Vzorový kód předpokládá, že na začátku balíčku neexistují žádné podpisy a před ověřením se použije pouze jeden podpis.

Zahájení procesu podepisování

Chcete-li začít pracovat s podpisy v balíčku, nejprve vytvořte PackageDigitalSignatureManager, jak je znázorněno níže.

    // Open the package.
    Package package = Package.Open(filename);

    // Create the PackageDigitalSignatureManager
      PackageDigitalSignatureManager dsm =
        new PackageDigitalSignatureManager(package);

Možnosti vložení certifikátu

Certifikát může být reprezentován buď jako řetězec vložený do samotného podpisu, jako samostatná část balíčku, nebo jako prostředek mimo balíček. Pokud má být certifikát umístěn v rámci balíčku, aplikace určuje, jak bude certifikát zachován pomocí možností vložení PackageDigitalSignature.CertificateOption vlastnost. Po vytvoření Třídy PackageDigitalSignatureManager jsou nastaveny možnosti vložení certifikátu, jak je znázorněno v ukázkovém kódu níže.

    //Specify that the certificate is embedded in the signature held
    //in the XML Signature part.

    //Certificate embedding options include:
    // InSignaturePart – Certificate is embedded in the signature.
    // InCertificatePart – Certificate is embedded in a 
    //                     separate certificate part

    dsm.CertificateOption =
        CertificateEmbeddingOption.InSignaturePart;

Seznam podepsaných součástí

Seznam částí, které se mají podepsat, se zadává pomocí identifikátorů URI, které tyto části adresují. V této ukázce budou podepsány všechny části v balíčku s výjimkou částí relací, které jsou odfiltrovány pomocí metody PackUriHelper.IsRelationshipPartUri().

    //Initialize a list to hold the part URIs to sign.

    System.Collections.Generic.List<Uri> partsToSign =
        new System.Collections.Generic.List<Uri>();

    //Add each part to the list, except relationships parts.
    foreach (PackagePart packagePart in package.GetParts())
    {
        if (!PackUriHelper.IsRelationshipPartUri(packagePart.Uri))
      partsToSign.Add(packagePart.Uri);
  }

Seznam podepsaných relací

Jednotlivé relace se podepisují pomocí transformace relací. Podepisování relací tímto způsobem umožňuje přidání nových relací do balíčku bez zneplatnění podpisu.

Relace se vyberou pro podepisování vytvořením seznamu objektů PackageRelationshipSelector , které se použijí v době podepisování. Objekty PackageRelationshipSelector lze vytvořit jako skupinu podle typu relace (jak je definováno v části Standardní obory názvů a typy obsahu konvence Open Packaging) nebo mohou být vytvořeny jednotlivě zadáním ID relace, jak je uvedeno v následující ukázce.

     //Create list of selectors for the list of relationships

     List<PackageRelationshipSelector> relationshipSelectors = 
          new List<PackageRelationshipSelector>();

     //Create one selector for each package-level relationship, based on id

  foreach (PackageRelationship relationship in package.GetRelationships())
            {
                relationshipSelectors.Add(new
                    PackageRelationshipSelector(relationship.sourceUri, 
                    PackageRelationshipSelectorType.Id, relationship.Id));
            }

Při vytváření PackageRelationshipSelector s PackageRelationshipSelectorType.Id se pro podepsání vybere jedna relace se zadaným jedinečným ID. Při vytváření selektoru s PackageRelationshipSelectorType.Type se pro podepisování vyberou všechny relace se zadaným typem. Pokud se relace stejného typu později přidají do balíčku, podpis bude zneplatněn.

Vytvoření objektu certifikátu

Před podpisem se získá platný certifikát X.509 vytvořením instance objektu typu System.Security.Cryptography.X509Certificates.X509Certificate2. Tento objekt je předán PackageDigitalSignatureManager.Sign() metoda v době podpisu. Další informace o vytváření objektů certifikátů naleznete System.Security.Cryptography.X509Certificates obor názvů.

Použití podpisu

Po vytvoření seznamu částí a vztahů k podepsání a získání objektu certifikátu volá aplikace PackageDigitalSignatureManager.Sign() metoda.

     //Sign package using components created above

     PackageDigitalSignature signature = dsm.Sign(partsToSign, 
          x509Certificate, relationshipSelectors);

     //After signing, close the package.
     //The signature will be persisted in the package.
     package.Close();

Při zavolání metody Sign() se vygeneruje hodnota hash a uloží v manifestu podpisu a vytvoří se část podpisu. Pokud už infrastruktura podpisů v balíčku existuje, přidá se nová část podpisu (pokud je povolená). Pokud infrastruktura v balíčku ještě neexistuje, metoda Sign() vytvoří infrastrukturu a umístí ji do balíčku.

Ověřování certifikátů a podpisů

Aplikace můžou ověřit certifikát nebo podpis. Před ověřením podpisu by měl být certifikát ověřený. Objekt, který představuje podpis v balíčku PackageDigitalSignature, má vlastnost "Podepisující", která vrátí certifikát použitý k vytvoření podpisu, pokud je v balíčku. Pokud certifikát není vložen v balíčku, aplikace získá certifikát z umístění, které aplikace zná.

Metoda PackageDigitalSignatureManager.VerifyCertificate() slouží k ověření získaného certifikátu, kontrole struktury certifikátu, data vypršení platnosti a stavu řetězu. Další informace o stavu řetězu najdete v tématu X509ChainStatusFlag – výčet v knihovně tříd rozhraní .NET Framework.

Vývojáři aplikací můžou stav certifikátu použít k podpoře svých zásad podepisování. Aplikace může například určit, že jsou přijatelné pouze certifikáty vydané po určitých datech.

Metoda PackageDigitalSignatureManager.VerifySignatures() slouží k ověření všech podpisů v balíčku. Tato metoda ověřuje pouze podpisy, nikoli certifikáty přidružené k podpisům.

Vzorový kód níže lze použít k ověření certifikátu a podpisu v balíčku v podpisových vzorcích. Vzorový kód předpokládá, že do balíčku nebyly přidány žádné další podpisy.

    // Open the package.

    Package package = Package.Open(filename);

    // Create the PackageDigitalSignatureManager

    PackageDigitalSignatureManager dsm =
        new PackageDigitalSignatureManager(package);

    // Verify the collection of certificates in the package (one, in this case)

        foreach(PackageDigitalSignature signature in pdsm.Signatures)
        {
        if(PackageDigitalSignatureManager.VerifyCertificate(signature.Signer)
            != X509ChainStatusFlags.NoError)
              {
                // Application-specific code for error handling 
                // or certificate validation 
              }
        }
 
   // For this example, if all certificates are valid,
   // verify all signatures in the package.
 
    VerifyResult vResult = dsm.VerifySignatures(false);
    Console.WriteLine("Result " + vResult.ToString());

    // Close the package.

    package.Close();

Zásady podepisování aplikací

Aplikace využívající formáty založené na balíčcích definují své vlastní zásady jako součást podpisové architektury. Zásady jsou určeny typy elementů a požadavky pracovního postupu formátu. V této části jsou popsány zásady podepisování pro jeden formát založený na balíčku společnosti Microsoft: formát dokumentu XPS.

Dokumenty XPS

Formát dokumentu XPS je založen na konvencích otevřeného balení, jak je uvedeno ve specifikaci papíru XML. Specifikace DOKUMENTU XML definuje zásady pro podepisování dokumentů XPS. V rámci této zásady jsou k dispozici možnosti podepisování pro podporu funkcí aplikace nebo pracovního postupu.

Zásady podepisování pro balíčky dokumentů XPS

Zásady podepisování pro dokumenty XPS popisují sadu částí a vztahů, které musí být podepsány, aby bylo možné obsah ověřit. V rámci této zásady může aplikace vytvořit podpis, který volitelně obsahuje kombinaci konkrétních částí, které jsou doplňkové k obsahu, jako je například část CoreProperties. Podepsáním těchto částí zabráníte jejich změně bez zneplatnění podpisu. Kromě toho mohou aplikace volitelně podepsat část vztahů připojenou k části Digitální podpis Původ v podpisu a zakázat přidávání nových podpisů do dokumentu bez zneplatnění podpisu.

Aby byl podpis platný, zásady podepisování dokumentu XPS vyžadují, aby byly do podpisu zahrnuty určité části a vztahy. Nelze podepsat žádné nerozpoznané části nebo relace. Při ověřování podpisu musí aplikace potvrdit, že jsou podepsány všechny požadované části a relace.

Podepsat části dokumentu XPS

Následující tabulka obsahuje seznam částí, které musí být podepsány ve všech dokumentech XPS, a části, které jsou volitelně podepsány. U relací zásada podepisování xps určuje, že požadované relace (relace cílící na požadované části) jsou vždy podepsané pomocí transformace relací definované OPC. Pokud je část podepsaná, musí být podepsány také relace, které na ni cílí.

Typ dílu Zásady
Část FixedDocumentSequence Musí být podepsáno
Část FixedDocument Musí být podepsáno
Části DocumentStructure Musí být podepsáno
Část SignatureDefinitions Musí být podepsáno
Části FixedPage Musí být podepsáno
Požadované části prostředků (například písma nebo obrázky) Musí být podepsáno
Části StoryFragments Musí být podepsáno
Části miniatur Musí být podepsáno
Část CoreProperties Volitelně podepsané
Část Původ digitálního podpisu Volitelně podepsané
Část certifikátu digitálního podpisu Volitelně podepsané
PrintTicket – díly Volitelně podepsané
Zahodit části Ovládací prvek Volitelně podepsané

Další informace o zásadách podepisování ve formátu XPS najdete v části "Funkce balíčku dokumentů XPS: Digitální podpisy: Pravidla podepisování" ve specifikaci dokumentu XML.

Zásady podepisování kompatibility značek

Specifikace dokumentu XML popisuje způsob zahrnutí alternativního obsahu do dokumentu XPS: kompatibilita značek. Alternativní obsah je umístěn v elementech z oboru názvů Kompatibilita značek. Podle zásad nelze dokumenty XPS, které mají prvky a atributy kompatibility značek, platně podepsat, pokud podpisová aplikace nerozpozná všechny alternativy obsahu jako ekvivalentní. Podepsat nebo ověřit lze pouze dokumenty XPS obsahující prvky a atributy, které jsou rozpoznány.

Protisignatury

Na obsah dokumentu XPS lze použít více než jeden podpis. Například obsah představující právní smlouvu může vyžadovat, aby podpisy použilo několik osob, které označují podepsaný obsah a identitu podepisující osoby.

Při přidání nového podpisu se vždy vytvoří nová relace v rámci části relace připojené k části Původ digitálního podpisu. Chcete-li přidat nové podpisy do dokumentu XPS bez zneplatnění stávajících podpisů, musí tato část relací zůstat nepodepsaná (i když podmnožina relací může být podepsána). Pokud je součástí podpisu část relace, bude tento podpis zneplatněn všemi následně použitými podpisy.

Ověřování podpisů XPS

Kromě definování vytvoření podpisu zásady podepisování XPS také určují, jak ověřit podpis jako platný. Zásady definují stavy platnosti podpisu, mezi které patří nekompatibilní, nefunkční, sporný a platný, jak je znázorněno v následující tabulce.

Stav podpisu Jsou všechny požadované části a vztahy podepsané? Podpis obsahuje jenom rozpoznaný obsah? Hodnota hash podepsaného obsahu je ověřená? Rozpoznává se obsah kompatibility podepsaných značek? Je certifikát platný?
Nekompatibilní NO

ANO

Není k dispozici

NO

Není k dispozici

Není k dispozici

Není k dispozici

Není k dispozici

Není k dispozici

Není k dispozici

Zlomené ANO ANO NO Není k dispozici Není k dispozici
Sporné ANO

ANO

ANO

ANO

ANO

ANO

NO

ANO

Není k dispozici

NO

Platné ANO ANO ANO ANO ANO

Prohlížeč souborů XPS zobrazí pochybné a poškozené podpisy ve formátu XPS i platné podpisy ve formátu XPS. Nekompatibilní podpisy nejsou uvedené.

Podpora programování pro podpisy XPS

Při práci s dokumentem XPS mohou aplikace používat metody ve třídě XpsDigitalSignature . Tato třída je založena na PackageDigitalSignature třídy a zahrnuje metody, které splňují algoritmy a požadavky zadané ve specifikaci digitálního podpisu XPS. Metody podepisování a ověřování ověřují, že jsou podepsány všechny požadované části a vztahy dokumentu XPS.

Podepsání dokumentu XPS

XpsDocument.SignDigitally() Metoda slouží k podepsání dokumentu XPS. Před voláním metody musí mít aplikace certifikát X.509, který lze získat pomocí objektu System.Security.Cryptography.X509Certificates.X509Certificate2.

     // Open the XPS Document

     XpsDocument document = new XpsDocument(dstContainer,
          FileAccess.ReadWrite);

     // Obtain the certificate object from a file

     X509Certificate certificate =
          509Certificate.CreateFromCertFile(certFilename);

     // Create the signature and add it to the document using
     // the OPC Signing Framework

     document.SignDigitally(certificate, true, 
          XpsDigSigPartAlteringRestrictions.None);

XpsDigSigPartAlteringRestrictions lze použít k určení dalších omezení podpisu na základě zásad podepisování. Tento parametr určuje, jestli se mají z podpisu vyloučit části CoreMetadata a/nebo SignatureOrigin . Vyloučené části pak mohou být později změněny bez zneplatnění podpisu. Například vyloučení části CoreMetadata z podpisu umožní aplikaci změnit některé vlastnosti dokumentu bez zneplatnění podpisu.

PrintTicket a DiscardControl části jsou vyloučeny z podpisů vytvořených SignDigitally() metoda, i když tyto části mohou být volitelně podepsány specifickým způsobem aplikace.

Ověření podpisu dokumentu XPS

Jeden nebo více podpisů může být uložen v dokumentu XPS. Podpisy lze získat z XpsDocument.Signatures vlastnost. Každý podpis je reprezentován instancí XpsDigitalSignature objektu .

V následující ukázce se ověřuje jenom první podpis v kolekci.

     // Open the XPS Document.

     // Obtain the first enumerated signature.

     foreach (XpsDigitalSignature digitalSignature in
              document.Signatures)
     { 
          // Verify the signature object, if present.

          if (digitalSignature.Verify() ==
     System.IO.Packaging.PackageDigitalSignature.VerifyResult.Success)
          {
         //Signature is valid
          }
     }

Reference