Skip to Content
Neue Version 12 verfügbar 🎉
ObfuscatorFIPS-Konformität

FIPS-Konformität

Mit Babel Obfuscator geschützte Assemblys laufen auf Hosts im FIPS-Modus. Diese Seite erklärt, wie sich die Schutzfunktionen, die auf Entschlüsselung zur Laufzeit beruhen, also Codeverschlüsselung (MSIL), Zeichenfolgenverschlüsselung, Ressourcenverschlüsselung und Wert- und Arrayverschlüsselung, auf solchen Hosts verhalten, welches Startproblem in Containern auftreten kann und wie Sie es beheben: entweder bei der Verschleierung, indem Sie mit dem eigenständigen verwalteten AES von Babel schützen, oder auf der Ebene der Umgebung.

Hintergrund

Viele Kunden stellen auf Hosts bereit, deren Betriebssystem im FIPS-Modus läuft. Unter Linux ist das an /proc/sys/crypto/fips_enabled = 1 zu erkennen. In diesem Modus soll der Kryptografieanbieter der Plattform (OpenSSL unter Linux) jede kryptografische Operation über ein zertifiziertes FIPS-Modul ausführen.

Ein häufiges Problem entsteht, wenn ein Container das FIPS-Flag des Hosts erbt, sein Basisimage aber keinen zertifizierten OpenSSL-FIPS-Anbieter enthält. OpenSSL 3 versucht dann, in den FIPS-Modus zu wechseln, kann das Modul des FIPS-Anbieters nicht laden und gerät in einen fehlerhaften Zustand, in dem jede Hash- und Verschlüsselungsoperation fehlschlägt, nicht nur die, die FIPS normalerweise nicht zulässt.

Das ist ein Zustand der Umgebung, kein Fehler in der verschleierten Assembly oder in Babel Obfuscator. Er ist unabhängig von Babel dokumentiert, siehe dotnet/dotnet-docker#5849  und dotnet/runtime#87884 . Er betrifft jede auf OpenSSL gestützte .NET-Kryptografie im Prozess, einschließlich TLS (HttpClient, gRPC), nicht nur verschleierten Code.

Wie sich das Problem in verschleierten Assemblys zeigt

Wenn eine Assembly mit einer Funktion geschützt ist, die Inhalte zur Laufzeit entschlüsselt, vor allem Codeverschlüsselung und Zeichenfolgenverschlüsselung, fügt Babel eine kleine Laufzeitkomponente ein, die Methodenrümpfe und Zeichenfolgen mit dem Kryptografieanbieter der Plattform entschlüsselt. Auf einem Host mit defektem FIPS ist dieser Anbieter unbrauchbar. Die Entschlüsselung läuft in einem Typinitialisierer, und die Assembly startet deshalb nicht, noch bevor Ihr Code ausgeführt wird:

System.TypeInitializationException: The type initializer for '...' threw an exception. ---> Interop+Crypto+OpenSslCryptographicException: error:0308010C:digital envelope routines::unsupported at System.Security.Cryptography.AesImplementation.CreateTransform(...)

Sie können diesen Startfehler bei der Verschleierung verhindern, indem Sie die Assembly mit dem Algorithmus verwaltetes AES von Babel schützen: Die eingefügte Laufzeitkomponente entschlüsselt dann ohne den Kryptografieanbieter der Plattform, siehe Mit verwaltetem AES auf einem Host mit defektem FIPS starten weiter unten. Die OpenSSL-Umgebung zu reparieren (ebenfalls unten beschrieben) empfiehlt sich dennoch, wenn Sie den Container kontrollieren, weil dadurch auch andere auf OpenSSL gestützte Operationen im Prozess wie TLS wieder funktionieren.

Mit verwaltetem AES auf einem Host mit defektem FIPS starten

Babel Obfuscator kann eine eigenständige verwaltete AES-Entschlüsselungsroutine in der geschützten Assembly mitliefern, sodass die eingefügte Laufzeitkomponente nicht mehr vom Kryptografieanbieter der Plattform abhängt. Schützen Sie die Assembly mit dem Wert encryption=aesmanaged des Schalters --use:

babel MyApp.dll --msilencryption --use encryption=aesmanaged

oder in einem MSBuild- oder .babel-Projekt:

<Use>encryption=aesmanaged</Use>

Der Obfuscator verschlüsselt weiterhin mit dem Anbieter der Plattform auf dem Buildhost (der intakt ist) und erzeugt denselben Chiffretext. Es ändert sich nur die Entschlüsselungsroutine, die in der geschützten Assembly mitgeliefert wird. So startet die Assembly auf einem Host mit defektem FIPS ohne jede Änderung an der Umgebung. Assemblys, die mit einer früheren Babel-Version geschützt wurden, müssen neu verschleiert werden, um die verwaltete Entschlüsselungsroutine zu erhalten.

Leistung. Die verwaltete Entschlüsselungsroutine arbeitet mit etwa 40 MB/s, das hardwarebeschleunigte AES der Plattform dagegen mit mehreren GB/s. Bei der Zeichenfolgen-, der Ressourcen- und der üblichen (zwischengespeicherten) Codeverschlüsselung fallen diese Kosten einmalig beim Start an und sind nicht spürbar. Die Ausnahme ist die Codeverschlüsselung einer Methode mit cache=false, deren Rumpf bei jedem Aufruf entschlüsselt wird: Kombinieren Sie cache=false bei häufig durchlaufenen Methoden nicht mit encryption=aesmanaged, und lassen Sie den Methodencache eingeschaltet (die Standardeinstellung), damit die Entschlüsselung nur einmal stattfindet.

Lösung in Containern

Machen Sie OpenSSL im Container nutzbar. Jede der beiden Optionen behebt das Symptom in der Laufzeitkomponente der Verschleierung und das Problem bei jeder anderen auf OpenSSL gestützten Operation in Ihrem Prozess (zum Beispiel, wenn dieselbe Assembly auch Babel Licensing oder TLS verwendet).

Option 1: FIPS im Container nicht automatisch aktivieren

In .NET-Images auf Basis von Ubuntu beachtet OpenSSL die Umgebungsvariable OPENSSL_FORCE_FIPS_MODE. Setzen Sie sie auf 0, damit OpenSSL nicht versucht, mit einem Anbieter in den FIPS-Modus zu wechseln, den das Image nicht enthält.

In einem Dockerfile:

ENV OPENSSL_FORCE_FIPS_MODE=0

oder in docker-compose.yml:

environment: OPENSSL_FORCE_FIPS_MODE: 0

Verwenden Sie diese Option, wenn der Container selbst nicht FIPS-validiert sein muss: Der Host bleibt im FIPS-Modus, und nur OpenSSL in diesem Container verzichtet auf den fehlerhaften automatischen Wechsel in den FIPS-Modus.

Option 2: Basisimage mit zertifiziertem FIPS-Anbieter verwenden

Wenn die FIPS-Konformität im Container verlangt wird, verwenden Sie ein Basisimage mit einem validierten FIPS-Anbieter, damit die Kryptografieschicht korrekt initialisiert wird und nicht fehlschlägt:

  • .NET-Images für Azure Linux 3.0 (mcr.microsoft.com/dotnet/aspnet:8.0-azurelinux3.0 und ähnliche), die den FIPS-zertifizierten Anbieter SymCrypt von Microsoft enthalten,
  • .NET-Images auf Basis von Red Hat UBI 9 (registry.access.redhat.com/ubi9/dotnet-90 und ähnliche) oder
  • Ubuntu Pro mit den FIPS-zertifizierten OpenSSL-Paketen.

Umgebung prüfen

Eine kurze Prüfung im Container zeigt, ob OpenSSL intakt ist:

# Fails on a broken-FIPS host, succeeds once fixed echo test | openssl dgst -sha1
  • Ein Fehler mit error:03000086 (oder eine Meldung, dass fips.so nicht geladen werden kann): OpenSSL ist im fehlerhaften Zustand. Wenden Sie Option 1 oder 2 an.
  • Eine normale Zeile SHA1(stdin)= ...: OpenSSL ist intakt, und verschleierte Assemblys starten normal.

Wenn Sie die Umgebung nicht ändern können

Wenn Sie weder das Basisimage noch die Umgebungsvariablen beeinflussen können und die Zielumgebung strikt an FIPS gebunden bleiben muss, schützen Sie die Assembly mit dem oben beschriebenen Algorithmus verwaltetes AES (--use encryption=aesmanaged), damit die eingefügte Entschlüsselungsroutine den Anbieter der Plattform nicht benötigt. So startet eine geschützte Assembly auch auf einem Host mit defektem OpenSSL ohne Eingriff in die Umgebung, und alle Funktionen mit Entschlüsselung zur Laufzeit bleiben verfügbar: Codeverschlüsselung, Zeichenfolgenverschlüsselung, Ressourcenverschlüsselung und Wert- und Arrayverschlüsselung. Beachten Sie, dass andere auf OpenSSL gestützte Operationen im selben Prozess (etwa TLS) weiterhin fehlschlagen, bis die Umgebung repariert ist. Wenden Sie sich an den Support , wenn Sie Unterstützung für eine bestimmte Bereitstellung benötigen.

Last updated on