SOAP - Signieren und Verschlüsseln

Mit der Einführung von SOAP (Simple Object Access Protocoll) wurde ein wichtiger Schritt in der Vereinfachung von Informations- und Datenübertragungen getätigt. Die Protokollstruktur basiert hierbei auf der Auszeichnungssprache XML (eXtended Markup Language) und ermöglicht somit ein wesentlich flexibleres Nachrichtenhandling als es mit reinen http-Lösungen und den RPC’s als eigenständige Anwendungen möglich wäre. Erst die richtige Kombination aus diesen Protokollen ermöglicht eine hocheffiziente und problemlose Kommunikation im Internet in Bezug auf die heute notwendigen technischen Anforderungen bei Web-Diensten und App‘s.

Im heutigen Datenaustausch über das Internet werden massenweise sicherheitsrelevante Daten und Informationen übertragen. Einige Beispiele hierzu wären Internet-Shops oder das Kontomanagement über entsprechende Smartphone- oder PC-Apps. Hier werden vor allem schützenswerte persönliche Daten und auch kritische Informationen wie Kontodaten und Passwörter abgefragt und übertragen. An dieser Stelle gilt es nun entsprechende Sicherheitsvorkehrungen zu treffen und die Datenübertragung dahingehend bestmöglich zu sichern. Die Verwendung von SOAP ermöglicht hier die Verwendung von digitalen Signaturen und hocheffizienten Verschlüsselungen.

Digitale Signaturen für Nachrichten

Bei einer ungesicherten Verbindung über LAN oder WLAN kann eine versendete Nachricht inhaltlich jederzeit ohne großem Aufwand mitgelesen werden. Es sind aber nicht nur die Inhalte an sich gefährdet, es können auch die XML-Schemata gelesen, interpretiert und die internen Abläufe der Webservices damit möglicherweise ermittelt werden. Beides bietet zusätzliche Angriffspunkte zu den eigentlich transportierten offenen Daten. SOAP bietet hierzu jedoch mehrere und verschiedene Ansätze, um eine Datenübertragung entsprechend zu sichern. Zum einen kann eine digitale Signatur den Original-Absender bestätigen und eine zusätzliche Verschlüsselung die eigentlichen Informationen und Daten schützen.

Vereinfacht dargestellt ermöglicht die digitale Signatur eine Kennzeichnung des Absenders. In der Praxis wird einer SOAP-Nachricht eine digitale Signatur im SOAP-Body-Element mit einem privaten Schlüssel erstellt und das entsprechende Zertifikat zusammen mit der Signatur in den Kopf der Anforderung eingefügt. Der oder die Empfänger können dann ganz einfach überprüfen, ob die Nachricht auch vom ursprünglichen Absender stammt und dass er seit seiner Unterzeichnung auch unverändert blieb. Der folgende Codeauszug zeigt exemplarisch das Erzeugen einer neuen Signatur und die Erstellung eines neuen SOAP-Kontextes.

X509Certificate cert = (X509Certificate)store.Certificates[listBox1.SelectedIndex];
X509SecurityToken certToken = new X509SecurityToken(cert);
proxy.RequestSoapContext.Security.Tokens.Add(certToken);
proxy.RequestSoapContext.Security.Elements.Add(new Signature(certToken));

Beim Signieren von SOAP-Nachrichten ist zu beachten, dass die Standardmethode in der Regel den SOAP-Hauptteil und verschiedenen SOAP-Headerteile umfasst. In der Praxis gibt es oftmals Anforderungen, nur bestimmte SOAP-Teile zu signieren. Immer wenn ein Intermediär bestimmte SOAP-Teile ändert, würde diese bei einer Standard-Signierung ungültig werden. Werden jedoch nun bestimmte unveränderbare Elemente signiert, bleiben diese bei Änderungen erhalten. In der Signature-Klasse bietet die Option SignatureOptions verschiedene Flags für die einzelnen Teile wie folgt an:

  • IncludePath

  • IncludePathAction

  • IncludePathFrom

  • IncludePathId

  • IncludePathTo

  • IncludeSoapBody

  • IncludeTimestamp

  • IncludeTimestampCreated

  • IncludeTimestampExpires

  • IncludeNone

Sie können für die Option eine beliebige Kombination der Flags verwenden. Einzige Ausnahme bietet die Option IncludeNone. Mit diesem Flag wird erreicht, dass keine anderen Flags in der Option enthalten sein dürfen.

Verschlüsselung mit Token und Zertifikaten

Um eine effektive Verschlüsselung von SOAP-Nachrichten durchführen zu können, sollte ein entsprechendes Token vorhanden sein. Für das Erstellen eines Zertifikates sieht der WSS-Standard (Web Services Security) verschiedene Möglichkeiten vor. Zum einen wird hier das X.509-Zertifikat favorisiert und zum anderen die Verwendung verschiedener Token. Hier wird grundsätzlich zwischen folgenden Token unterschieden:

  • Benutzernamentoken

  • Binärtoken

Bevor wir also eine SOAP-Nachricht signieren können müssen wir jedoch feststellen können, wer die Signierung vorgenommen hat. Im WWS wird ein Element mit der Bezeichnung <UsernameToken> definiert. Hierin stehen die nachfolgend gezeigten 3 unterschiedliche Formen zur Verfügung:

<!-- Keine Passwortvergabe -->
<UsernameToken>
<Username>Volkmar</Username>
</UsernameToken>
<!-- Klartext Passwort -->
<UsernameToken>
<Username>Volkmar</Username>
<Password Type="wsse:PasswordText">#d7T1*?u14f70Ab22</Password>
</UsernameToken>
<!-- Base64-kodiertes Passwort -->
<UsernameToken>
<Username>Volkmar</Username>
<Password Type="wsse:PasswordDigest">I2Q3VDEqP3UxNGY3MEFiMjI=</Password>
</UsernameToken>

Das erste Element enthält nur den Benutzernamen und keinerlei Passwortangabe. Diese Form wird immer dann angewendet, wenn an anderer Stelle eine gesicherte Benutzerprüfung vorgesehen ist und nur der Benutzername benötigt wird. In der zweiten Variante wird neben dem Benutzernamen auch noch das Passwort im Klartext übertragen. Dies erfordert auf der Gegenseite eine Datenbank, in der Benutzer und Passwörter gespeichert sind und damit vergleichbar werden. Die dritte Methode verwendet eine um die Digest-Variante der Base64-Kodierung erweiterte Version des Passwortes und damit eine verschlüsselte Übertragung desgleichen.

Eine normale Base64-Codierung hat zunächst „nur“ den Vorteil der Absicherung, kann aber beispielsweise in Form einer Rücksendung des Passworts zu einer Authentifizierung als Absender führen. Wird jedoch die Digest-Variante eingesetzt, ist eine Zweckentfremdung nicht mehr möglich. Die Digest-Funktion im WSS bietet einen unveränderlichen Zusatz an. Hier wird ein Hashwert aus einer Kombination des Kennworts, einem „Nonce“ (funktionell eindeutige Zeichenfolge) sowie dem Erstellungszeitpunkt des Tokens gebildet. Damit ist eine Fälschung nicht mehr möglich.

Das WSS X.509-Sicherheitstoken

Das WSS enthält neben dem zuvor beschriebenen Username-Token auch noch das BinarySecurityToken-Element. Die Spezifikation definiert hierfür entsprechende Typen für das X.509 v3-Zertifikat und auch das Kerberos v5-Ticket-System. Bei der Anwendung des X.509-Tokens werden Sie schnell Ähnlichkeiten zum Username-Token feststellen können. Für eine Softwareentwicklung auf Microsoft-Basis wird hierzu einfach der private Benutzerspeicher für Zertifikate genutzt.

In der ursprünglichen Version des Microsoft.NET-Frameworks wurden jedoch keine speziellen Klassen für den Zugriff auf den Zertifikatsspeicher zur Verfügung gestellt. Microsoft hat hier mit dem WSE (Web Service Enhancement) jedoch spezielle Zugriffsklassen definiert, die das Arbeiten mit dem Zertifikatspeicher erheblich vereinfachen. Der folgende Code zeigt die Anwendung der Microsoft.Web.Services.Security.X509-Klasse, um eine ListBox mit den allgemeinen Namen aller Zertifikate im persönlichen Zertifikatsspeicher eines Benutzers zu füllen:

using Microsoft.Web.Services;
using Microsoft.Web.Services.Security;
using Microsoft.Web.Services.Security.X509;
...
private X509CertificateStore store;
...
private void Form1_Load(object sender, System.EventArgs e)
{
store = X509CertificateStore.CurrentUserStore(
X509CertificateStore.MyStore);
store.OpenRead();
foreach(X509Certificate cert in store.Certificates)
{
listBox1.Items.Add(cert.GetName());
}
}

Da wir nun Zugriff auf den Zertifikatsspeicher auf dem Windows-System haben, können wir das vom Benutzer aus der gefüllten Listbox gewählte Zertifikat auch sofort im entsprechenden SOAP-Kontext wie folgt zuweisen:

X509Certificate cert =
(X509Certificate)store.Certificates[listBox1.SelectedIndex];
proxy.RequestSoapContext.Security.Tokens.Add(
new X509SecurityToken(cert));

Auf der Serverseite ist der Zugriff auf das Benutzer-Zertifikat dem des Zugriffes auf das Benutzernamen-Zertifikat sehr ähnlich. Mit einer entsprechend angepassten Abfrage in der Webmethode kann nun auf das X.509-Zertifikat hin geprüft und weiter verfahren werden. Ein kleiner Quelltextauszug soll diese Integration kurz veranschaulichen:

// Only accept SOAP requests
SoapContext requestContext = HttpSoapContext.RequestContext;
if (requestContext == null)
{
throw new ApplicationException("Non-SOAP request.");
}
// We only allow requests with one security token
if (requestContext.Security.Tokens.Count == 1)
{
foreach (SecurityToken tok in requestContext.Security.Tokens)
{
// Only accept X.509 Certificates
if (tok is X509SecurityToken)
{
X509SecurityToken certToken = (X509SecurityToken)tok;
return "Hello "   certToken.Certificate.GetName();
}
else
{
throw new SoapException(
"X.509 security token required.",
SoapException.ClientFaultCode);
}
}
} ...

Fazit

Das Übertragen von Nachrichten und Daten über SOAP bietet einige wesentliche Vorteile im Netzwerkverkehr. Die WSS-Spezifikation stellt hierfür einen wichtigen Schritt zur Sicherung der Datenübertragung mittels HTTP, XML und SOAP dar. Eine solide Sicherheits-Infrastruktur ist die Basis für den dringend benötigten Datenschutz. Interoperable Webservices können auf unterschiedliche Möglichkeiten wie digitale Signaturen und Sicherheitstoken zurückgreifen. Wenn Sie beispielsweise mit Windows-Systemen arbeiten und entsprechende Webservices anbieten, so können Ihnen die Microsoft-WSE einen soliden und leicht zu integrierenden Ausgangspunkt für die Sicherung Ihrer Server- und Webdienste bieten.

Nach oben