SAP Web Service

Bei der Kommunikation über ein Netzwerk jeglicher Art ist Sicherheit das A und O. Dieser Artikel von Quanto Solutions befasst sich damit, eine RSA-SHA Signatur für einen SAP Web Service zu erstellen, um einen externen API Call sicherer zu machen.

Es spielt nicht nur die Verschlüsselung der ausgetauschten Nachrichten bei einem API Call, sondern auch eine sachgemäße Authentifizierung und Autorisierung von Benutzer-Anfragen eine kritische Rolle. Viele Web-APIs und Services verlassen sich deshalb auf Verfahren wie OAuth oder ähnliche Authentifizierungsmodelle, um den Zugriff auf bereitgestellte Ressourcen zu sichern.

In einem üblichen Szenario gibt es neben der öffentlichen Web-Schnittstelle einen zusätzlichen Authentifizierungs-Server, welcher bei erfolgreicher Authentifizierung des Clients einen Access Token bereitstellt, mit welchem nachfolgende Anfragen an die Ziel-Schnittstelle authentifiziert werden.

Die Prämisse ist einfach: Kein gültiger Token, kein Zugriff auf die API!

Doch auch der Zugriff auf den Authentifizierungs-Server selbst sollte gewisse Sicherheitsstandards implementieren. SSL und HTTPS sind eine Selbstverständlichkeit, doch darüber hinaus wird oftmals ein Signierungsverfahren für eingehende Web-Requests implementiert. Die Idee ist hier, dass der HTTP-Anfrage eine Signatur beigefügt wird, die üblicherweise durch eine Kombination aus dem RSA-Verschlüsselungsalgorithmus und einer SHA-Hashfunktion erzeugt wird (RSA-SHA). Unterschiedliche SHA-Implementierungen, wie SHA-1 oder SHA-256 können hier zum Einsatz kommen. Dem Client wird in der Regel ein Zertifikat zur Verfügung gestellt, mit dessen Private Key die RSA-Verschlüsselung vorgenommen wird. Kann der Client keine gültige Signatur liefern, wird die Anfrage abgelehnt.

Praxis-Szenario: RSA-SHA Signatur für einen SAP Web Service erstellen

In einem Praxis-Beispiel soll nun erläutert werden, wie die Generierung einer RSA-SHA Signatur für den Abruf eines Access Tokens aus einer SAP®-Umgebung heraus realisiert werden kann. Kürzlich befanden wir uns für ein Kundenprojekt in der Situation, aus dem SAP®-System des Kunden heraus einen SAP Web Service zu erstellen, welcher wie oben beschrieben über einen Authentifizierungs-Server gesichert war. Dieser Server erwartete eine Signatur im Header jedes Requests mit folgenden Vorgaben:

Signatur-Algorithmus: RSA mit SHA-1

Spezifikation: PKCS 1-v1.5

Zu signierender Input:
{ Zeitstempel der Anfrage } + { Zeitstempel Ablauf der Anfrage } + { Client Zertifikat }

Wir wollen uns in den nachfolgenden Abschnitten anschauen, wie eine erfolgreiche Realisierung dieser Anforderungen in SAP® aussehen kann.

1. Anlegen der RFC-Destination in SM59, um einen SAP Web Service zu erstellen

Die Erstellung einer RFC-Destination ist bekanntermaßen die Grundvoraussetzung für den Konsum externer Web Services in SAP®. Die Transaktion SM59 ist den meisten SAP®-Entwicklern ein Begriff und stellt ein Tool für die Verwaltung externer Endpoints in SAP Systemen zur Verfügung, die dann im ABAP-Code programmatisch angesprochen werden können.

Es muss also zunächst eine RFC-Destination für den Authentifizierungs-Server angelegt werden.

Selbstverständlich müssen bei einer SSL-gesicherten HTTPS-Verbindung die entsprechenden Konfigurationen unter „Anmeldung und Sicherheit“ vorgenommen werden. Soll ein SSL-Zertifikat verwendet werden, so muss dieses zunächst über die Transaktion STRUST als PSE hinterlegt werden. Dazu mehr in den folgenden Abschnitten. In unserem Beispiel ist eine SSL-gesicherte RFC-Destination bereits gegeben. Wichtig ist, dass es sich bei dem Zertifikat für die Generierung der Signatur und dem Zertifikat für die SSL-Verbindung nicht um dasselbe Zertifikat handeln muss.

2. Erstellung einer SSF-Applikation

Um Signaturen für einen bestimmten Anwendungsfall erzeugen zu können, ist es notwendig, einen entsprechenden Eintrag in der Transaktion SSFA anzulegen. SSF (Secure Store and Forward Mechanism) lässt uns Parameter für digitale Signaturverfahren festlegen, und ist somit genau das richtige Werkzeug für den Job!

In der Tabelle SSFAPPLIC muss zunächst ein Eintrag angelegt werden, welchen wir dann als Konfigurations-Basis in der SSFA-Transaktion verwenden können. Über die SE16 rufen wir uns also die Tabelle SSFAPPLIC auf und fügen eine neue Zeile hinzu.

Im Anschluss können wir einen korrespondierenden Eintrag in der SSFA-Transaktion vornehmen.

Je nach Use-Case können hier verschiedene Parameter Anwendung finden. In unserem Fall benötigen wir SHA1 als Hashalgorithmus und wählen für die Verschlüsselung AES128-CBC. Entscheidend ist auch das SSF-Format. Die auswählbaren Formate sind hier unter anderem abhängig von der verwendeten Version der SAP® Cryptographic Library. Sollte das gewünschte Format nicht verfügbar sein, so muss eine Aktualisierung der SAP® Cryptographic Library vorgenommen werden. Dies geschieht über die Kommandozeile und muss durch die SAP®-Basis durchgeführt werden.

In der SAP®-Umgebung unseres Kunden steht die geforderte PKCS Version (1-V1.5) wie oben aufgeführt zur Verfügung und wird für diesen Use-Case gewählt.

3. Erstellung einer PSE für den Private-Key mittels STRUST

Wie bei jeder Verschlüsselung benötigen wir für die Anwendung des RSA-Algorithmus einen Key. In diesem Fall wird der Private Key unseres Client-Zertifikats benötigt. Um diesen Key sicher im SAP®-System zu hinterlegen, verwenden wir die Transaktion STRUST.

Die STRUST erlaubt uns, sensible Daten wie Schlüsselpaare und Zertifikate in Form von PSEs (Personal Security Environment) sicher in der SAP®-Umgebung zu hinterlegen. Für die von uns angelegte SSF-Applikation können wir nun einen neuen PSE-Eintrag erzeugen und unseren Private Key hinterlegen.

Wir begeben uns also in die Transaktion STRUST und rechtsklicken die von uns angelegte SSFA.

In dem Dialogfenster nehmen wir noch die für unseren Anwendungsfall benötigen Einstellungen vor. Die Schlüssellänge sollte 2048 betragen. Für den Algorithmus wählen wir RSA mit SHA-1, so wie es der Authentifizierungs-Server erwartet.

Nun müssen wir noch unser Client-Zertifikat, welches auch den private Key enthält, in die angelegte PSE importieren. Das Client-Zertifikat liegt üblicherweise im .PEM-Format vor.

Wir selektieren also unsere SSF Applikation in STRUST und wählen „PSE -> Importieren“ im Menüband.

Die importierte PSE wird dann unter dem Punkt „Datei“ bzw. „File“ aufgelistet. Wir selektieren diese und wählen dann „PSE->Sichern als“. In dem sich daraufhin öffnenden Dialogfenster muss nun die zuvor angelegte SSF-Applikation ausgewählt werden.

Somit ist das Client-Zertifikat, welches für die Signatur benötigt wird, auf sichere Weise im SAP®-System hinterlegt und kann aus einem ABAP-Programm heraus abgerufen werden.

4. Erzeugung der Signatur und Aufruf des Web Service in ABAP

Zur Veranschaulichung der programmatischen Lösung in ABAP, erstellen wir einen Test-Report. In diesem gilt es, die folgenden Schritte auszuführen:

  1. Auslesen des Client-Zertifikates aus der PSE
  2. Erzeugung der Zeitstempel
  3. Generierung der Signatur mittels Zeitstempel und Zertifikat
  4. Setzen der Header im HTTP-Request
  5. Aufruf des Authentifizierungs-Web Service

Für das Auslesen des Zertifikats steht uns der Funktionsbaustein „SSFP_GETAPPCERTIFICATE“ zur Verfügung. Dieser liefert das Zertifikat über einen Exporting-Parameter als Byte-Folge (Typ XSTRING) zurück. Wichtig ist, für den Parameter „application“ den Namen unserer SSF-Applikation, wie zuvor in der SSFAPPLIC Tabelle angelegt, zu übergeben.

In unserem Fall soll die RSA-SHA1 Signatur über 3 Werte gebildet werden: einen Zeitstempel, der das Erstellungsdatum des Requests beschreibt, einen weiteren Zeitstempel, der das Ablaufdatum des Requests darstellt und schließlich das Client-Zertifikat. Für das Ablaufdatum addieren wir 20 Sekunden auf den aktuellen Zeitstempel.

Die Zeitstempel erzeugen wir zunächst im erwarteten Format (yyyyMMddThhmmss.000Z) als String, konkatenieren diese und wandeln den erzeugten String schließlich in einen XSTRING um.

Nun liegen uns das Client-Zertifikat (lv_xcertificate) sowie die beiden verketteten Zeitstempel (lv_xtimestamps) als XSTRINGs vor. Diese können wir wiederum verketten und als Input für den Signatur-Algorithmus verwenden. Hier kommt der wichtigste Funktionsbaustein zum Einsatz: „SSF_KRN_SIGN“. Dieser ist zuständig für das Generieren von Signaturen gemäß den Konfigurationen aus der SSFA-Transaktion.

Bei den Übergabe-Parametern ist hier einiges zu beachten. Als Hash-Algorithmus übergeben wir in unserem Fall „SHA1“ und für das Format geben wir „PKCS1-V1.5“ an. Diese Spezifikationen wurden im Vorfeld festgelegt und werden so vom angesprochenen Endpoint erwartet. Sie variieren somit je nach Anwendungsfall.

Die zu übergebene Tabelle „signer“ spezifiziert das SSFA-Profil, welches im Vorfeld über die SSFA angelegt wurde. Hier ist der festgelegte SSF-Profilname anzugeben.

Der Funktionsbaustein nimmt den zu signierenden Input als Binär-Tabelle entgegen. Daher nutzen wir vorab den Funktionsbaustein „SCMS_XSTRING_TO_BINARY“, um den zu signierenden XSTRING entsprechend zu konvertieren.

Im Erfolgsfall gibt der Funktionsbaustein die erzeugte Signatur ebenfalls als Binär-Tabelle zurück (Parameter „ostr_signed_data“). Tritt ein Fehler auf, wird über den Parameter „crc“ ein Error-Code zurückgeben, der für eine angemessene Fehlerbehandlung dienlich ist.

Im Binär-Format lässt sich die Signatur natürlich schwer an den Authentifizierungs-Server übergeben. Erwartet wird diese im URL-konformen Base64-Format. Um die Signatur in dieses Format zu bringen, muss sie erst wieder in einen String konvertiert werden. Dafür nutzen wir den folgenden Funktionsbaustein:

Der generierte String kann dann über die Methode cl_http_utility=>encode_base64 ins Base64-Format gebracht werden. Die URL-Konformität lässt sich herstellen, indem wir den Base64-codierten String nun durch folgende Zeichenersetzungen modifizieren.

Die Variable lv_signature enthält jetzt unsere endgültige Signatur für die erfolgreiche Authentifizierung. Der Server erwartet jedoch außerdem das Client-Zertifikat selbst als Header in der HTTP-Anfrage. Also kodieren wir das Zertifikat auf dieselbe Weise.

Es liegen uns nun alle Werte vor, die wir für ein erfolgreiches Request an den Authentifizierungs-Server benötigen. Für das Absetzen von HTTP-Requests kann die ABAP-Klasse „CL_HTTP_CLIENT“ genutzt werden. Eine Instanz lassen wir uns über die statische Methode „CREATE_BY_DESTINATION“erzeugen. Dabei ist es essenziell, den Namen der RFC-Destination zu spezifizieren.

Zuletzt müssen noch die erforderlichen Request-Header erstellt und dem abzusetzenden HTTP-Request hinzugefügt werden. Die Klasse CL_HTTP_CLIENT stellt entsprechende Instanz-Methoden zur Verfügung.

In unserem Anwendungsfall erwartet der Authentifizierungs-Server ein POST-Request und liefert den generierten Token im Body der HTTP-Response zurück. Wir fügen den Header „accept“ mit dem Wert „application/json“ an, da die zurückgelieferte Nachricht im JSON-Format erwartet wird. Ist alles korrekt, können wir nun die Antwort des Authentifizierungs-Servers über die Methode „GET_DATA“ auslesen. Das hierin enthaltene JSON-Objekt kann mithilfe der Utility-Methode „/ui2/cl_json=>deserialize“ in eine ABAP-Struktur deserialisiert werden. Schauen wir uns die Komponenten dieser Struktur an, finden wir schließlich den Access Token.

Fazit

Mit dem richtigen Know-How ist die Anwendung von unterschiedlichen Verschlüsselungsverfahren in SAP kein Problem. So können auch Endpunkte angebunden werden, deren Integration komplexere Anforderungen stellt als das Erstellen einer HTTP-Verbindung in der SM59. Die Buzzwords lauten hier: STRUST, SSFA und PSE. Wir hoffen, dass Sie nun die nötigen Kenntnisse haben, eine RSA-SHA Signatur für einen SAP Web Service selbst zu erstellen.

Ein erfahrener SAP Berater/in wie Quanto Solutions bringt die nötigen Kenntnisse für diese Tools mit.

Autoren: Peter Ritz & Alexander Herrfurth

Tags