XML Encryption: šifrování částí XML

XML Encryption ukládá šifrovaná data a informace o algoritmu do XML struktury. Šifrování chrání důvěrnost; důvěryhodnost dokumentu a jeho původ musí aplikace ověřit zvlášť.

Autor: Aktualizováno

Co se šifruje

Lze šifrovat element, jeho obsah nebo obecná data. EncryptedData obsahuje CipherData a informace pro zpracování. EncryptedKey může nést šifrovaný klíč; není to totéž jako vlastní datový klíč.

Jak poznat obálku

Fragment níže je pouze tvar obálky: zástupná hodnota není platný šifrovaný text. Algorithm musí odpovídat použitému algoritmu, klíči, nonce a autentizačním údajům, které vytváří knihovna.

Jak poznat obálku
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
 <xenc:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
 <xenc:CipherData><xenc:CipherValue>BASE64_SIFROVANYCH_DAT</xenc:CipherValue></xenc:CipherData>
</xenc:EncryptedData>

Verze a algoritmy

Verze 1.1 je doporučení W3C z roku 2013 a zahrnuje AES-GCM. Schéma dovolující algoritmus ještě neznamená, že je vhodný pro novou aplikaci. Povol pouze algoritmy a parametry požadované bezpečnostním profilem; nepřijímej libovolný Algorithm od vstupu.

Bezpečné zpracování

Použij udržovanou knihovnu, omez reference a velikosti a neprozrazuj rozdílnými chybami detaily dešifrování. Také dešifrované XML parsuj bezpečně. HTTPS nenahrazuje šifrování dokumentu uloženého na disku a XML Encryption nenahrazuje autorizaci aplikace.

Zašifrování a dešifrování dokumentu s Apache Santuario v Javě

EncryptDemo.java — XMLCipher API Apache Santuario 4.x
import javax.crypto.KeyGenerator;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.xml.security.Init;
import org.apache.xml.security.encryption.XMLCipher;
import org.xml.sax.InputSource;
import java.io.StringReader;
public class EncryptDemo {
  public static void main(String[] args) throws Exception {
    Init.init();
    var factory = DocumentBuilderFactory.newDefaultInstance();
    factory.setNamespaceAware(true);
    factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
    factory.setAttribute(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
    var doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(
        "<zprava><text>XML &amp; JSON</text></zprava>")));
    var generator = KeyGenerator.getInstance("AES");
    generator.init(256);
    var key = generator.generateKey();
    var encrypt = XMLCipher.getInstance(XMLCipher.AES_256_GCM);
    encrypt.init(XMLCipher.ENCRYPT_MODE, key);
    encrypt.doFinal(doc, doc.getDocumentElement(), false);
    System.out.println(doc.getDocumentElement().getLocalName());
    var decrypt = XMLCipher.getInstance();
    decrypt.init(XMLCipher.DECRYPT_MODE, key);
    decrypt.doFinal(doc, doc.getDocumentElement(), false);
    var output = TransformerFactory.newDefaultInstance();
    output.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "");
    output.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
    output.newTransformer().transform(new DOMSource(doc), new StreamResult(System.out));
  }
}
JDK; lib obsahuje xmlsec a jeho runtime závislosti, Windows používá místo : oddělovač ;
javac -cp "lib/*" EncryptDemo.java
java -cp ".:lib/*" EncryptDemo

Z Maven artefaktu org.apache.santuario:xmlsec připni podporovanou 4.x verzi a její závislosti podle POM; v ověření příkladu používáme 4.0.4. Výstup nejdřív ukáže EncryptedData, potom obnoví zprava/text s hodnotou XML & JSON. CipherValue generuje knihovna včetně údajů potřebných pro AES-GCM; nepředepisuj vlastní pevný nonce. CipherValue se při různých bězích liší.

Příklad šifruje celý root element. Boolean true v doFinal by znamenal šifrování obsahu daného elementu, nikoli celé obálky. Náhodný AES klíč zde zůstává pouze v paměti procesu, proto příklad není ukládací formát se správou dlouhodobých klíčů. Pro předání jinému příjemci dohodni bezpečnou správu klíčů nebo odpovídající EncryptedKey mechanismus.

Jak ověřovat cizí šifrovaný dokument

Nejdřív bezpečně parsuj omezený vstup a ověř očekávané umístění EncryptedData. Potom povol konkrétní algoritmus a druh klíče podle profilu aplikace. Příjemci nemá stačit, že dokument uvádí libovolné Algorithm. Rozlišuj inline CipherValue od CipherReference odkazujícího na externí data; pokud jej nepotřebuješ, nepovoluj jej.

Po dešifrování ověř obnovenou strukturu a autorizaci stejně jako u jiného vstupu. Špatný klíč nebo změněný autentizovaný ciphertext má vést k odmítnutí, ne k částečnému použití plaintextu. Kryptografická chyba nesmí vyvolat druhý, méně přísný způsob zpracování. Úspěšné AES-GCM dešifrování neříká, který obchodní subjekt je oprávněn dokument poslat.

Zápis zpráv a postup zpracování popisuje XML Encryption 1.1. Použité API vychází z Apache Santuario. Pro prokázání původu navazuje XML Signature; pro ochranu parseru XXE.