# Daten verschlüsseln



## OnDemand (26. Jun 2021)

Hallo zusammen,

ich muss in meiner DB Daten speichern die ich nicht gern im Klartext haben will. Ich könnte im Code was einbauen um das zu verschlüsseln, soweit so gut.

Gibt es vielleicht noch eine SQL Variante wo ich sogar nachträglich bereits abgelegte Daten verschlüsseln kann ohne, dass ich im Code was machen muss? Bin der Meinung da mal was gelesen zu haben, dass es da eine Mysql Funktion gibt, aber bin mir nicht mehr sicher und finde dazu auch nix mehr.

Edit: das hier meinte ich
INSERT INTO secrets (content) VALUES (AES_ENCRYPT('das ist mein geheimnis', 'mCgCizeXzYrXXTvxrNmrIsKO8vdaFs3ZzTo7UcQ8mr+Q/6KIpJDMdgeKH57weCqLH5vJ6aquAuI='));

AES ist jetzt nicht soooo der bringer (aber besser als Klartext) jemand ne gescheitere Idee? BTW nutzte Spring boot, vielleicht gibts da ja schon was onboard, dass man daten verschlüsselt speichert und beim select automatisch entschlüsselt


----------



## OnDemand (26. Jun 2021)

Wäre das hier eine sinnvolle Variante? https://sultanov.dev/blog/database-column-level-encryption-with-spring-data-jpa/


----------



## OnDemand (26. Jun 2021)

Hab es jetzt so gelöst, dass die entsprechende Spalte ein LONGBLOB wird und die Attribute in der Entity wie folgt:

```
@ColumnTransformer(
            read = "AES_DECRYPT(data_value, 'secret-......')",
            write = "AES_ENCRYPT (?, 'secret-......')"
    )
    private String dataValue;
```

Wer kennt sich aus? Würde so ggf. API Keys zu anderen System abspeichern, ist das halbwegs sicher? 100% Sicher ist wohl nur, die Daten nicht zu speichern. Aber wenn man wie API Keys, die Daten wieder decrypten muss find ich keine andere Lösung. Hash geht ja nur in eine Richtung.


----------



## Thallius (26. Jun 2021)

Fragen:

1) Warum must du die Keys in der Datenbank speichern? Sind die dynamisch? Ansonsten gehören die in eine config Datei.
2) Was willst du damit erreichen wenn Du die Daten AES verschlüsselst? Wer soll es nicht lesen können? Wenn jemand Zugriff auf deine DB hat kann er sie so auch entschlüsseln da für AES kein Salt benutzt wird
3) Normalerweise sollte jede moderne Hardware ihre Dateien auf der Festplatte automatisch verschlüsseln. Ein Auslesen aus den Datenbank Dateien ist damit eh nicht möglich wenn der User nicht ordnungsgemäß als User auf der Maschine angemeldet ist. Welches Szenario schwebt dir also vor wo jemand ohne Zugriffsrechte die Schlüssel lesen kann?


----------



## mrBrown (26. Jun 2021)

Thallius hat gesagt.:


> Wenn jemand Zugriff auf deine DB hat kann er sie so auch entschlüsseln da für AES kein Salt benutzt wird


What


----------



## temi (26. Jun 2021)

mrBrown hat gesagt.:


> What?


Ich nehme an, das gilt für den Fall "wenn der Schlüssel in der DB gespeichert ist".


----------



## OnDemand (26. Jun 2021)

Ich gehe mal davon aus, dass jemand irgendwie Zugriff auf die DB bekommt. Die API Keys sind dynamisch.

Szenarien:
1. Jemand kommt über phpMyAdmin und will die API keys haben  ( aktuell API Key nicht lesbar da als LONGBLOB gespeichert)
3. Jemand kommt über Konsole an die DB und kommt an die API Keys

Der Key für das AES decrypten ist im Code und wird benötigt um die Longblobs zu entschlüsseln. Ok im Code ist vielleicht auch nicht sonderlich sinnvoll. (Muss ich mal schauen ob Spring Boot / JPA die irgendwo anders hinstecken kann).
Es erschwert aber definitiv schon mal das auslesen der Daten "mit normalem Wissen"


----------



## Thallius (26. Jun 2021)

NicoDeluxe hat gesagt.:


> Es erschwert aber definitiv schon mal das auslesen der Daten "mit normalem Wissen"



Wer mit "normalem" Wissen schafft es denn eure Datenbank zu hacken um zugriff darauf zu bekommen?


----------



## mrBrown (26. Jun 2021)

Thallius hat gesagt.:


> Wer mit "normalem" Wissen schafft es denn eure Datenbank zu hacken um zugriff darauf zu bekommen?


Bei ner passenden Sicherheitslücke irgendwo im Stack bekommt das jeder hin, dafür reicht schon einfache SQL-Injection


----------



## mrBrown (26. Jun 2021)

Generell kannst du nur versuchen, einem möglichen Angreifer möglichst viele Hürden in den Weg zu legen.

Die Dinge verschlüsseln (AES ist da btw. völlig ausreichend) hilft schon mal gegen einige Angriffe. Wenn jemand Zugriff auf den Web-Service hat, hat er natürlich dann auch Zugriff auf den Schlüssel oder die entschlüsselten Daten.

Dagegen hilft z. B., den Teil der den Schlüssel kennt, auszulagern, extra zu sichern, und nur "indirekt" zugreifbar zu machen, z. B. in dem der keine HTTP-Schnittstelle anbietet.


----------



## OnDemand (26. Jun 2021)

Vielleicht mal ein kleiner Einblick , etwas umfänglicher.

DB Server:
Externer Zugriff nur auf 2 IPs und localhost
SSH mit starkem PW geschützt (wollen wir noch auf IP beschränken, geht aber nicht so einfach weil der Provider wechselnde IPs hat mit denen er den Server managed)

"Haupt-Server"
Hier liegt eine zentrale Applikation drauf die auf die DB zugreift (dessen IP ist freigegeben). Diese nutzt JPA und kennt den AES-Key. (JPA und SQL Injection - geht das überhaupt wenn man die Repositories nutzt? 

Die Haupt-App hat eine API nach aussen (mit Basic Auth abgesichert). Hier werde ich noch einbauen, dass ebenfalls nur unsere internen IPs drauf dürfen, da die API für Fremde nach außen nicht offen sein muss. 

Um an die Daten zu kommen, müsste also jemand den DB Server hacken (vermutlich SSH oder über eine Lücke im OS?) und dann noch das mysql Passwort herausfinden. 

Oder die Mysql Files abreifen. Die Sql Files dürften verschlüsselt sein, sehe ich das richtig? 

Oder aber er kennt unsere API Endpoints und verbindet sich, dann müsste er stand jetzt das User + PW kennen (später noch durch IP gesichert) wirds ja nicht mehr möglich sein von aussen auf die API zu kommen. 

Die Daten die ich mit AES sichern will, sind hauptsächer Userdaten wie deren Keys zu externen Systemen. Persönliche Daten wie Name, IBAN. Firmendaten (Adresse, Tel) stehen unverschlüsselt im Telefonbuch...das macht mE wenig Sinn.
GGF noch Email adressen der User ?


----------



## mrBrown (26. Jun 2021)

NicoDeluxe hat gesagt.:


> SSH mit starkem PW geschützt


Besser SSH mit Public-Key-Authentifizierung nutzen


----------



## OnDemand (26. Jun 2021)

Moment mal, haben wir glaube ich. Ich hab die Keydatei gespeichert daher ist mir das gar nicht mehr so bewusst. 
Login mit PW geht aber dennoch. Das lass ich gleich mal abschalten, danke für den Tipp


----------



## OnDemand (26. Jun 2021)

Alles in Allem ist das doch aber ein guter Plan oder gibts noch Verbesserungsvorschläge?
Hab da noch was gefunden, die anderen (internen) Services holen sich von der Haupt-App Daten und würden ohne https bekommen via API. Wenn die API aber nur auf 1 hört, halte ich das für ausreichend, was sagt ihr?!


----------



## Thallius (26. Jun 2021)

Also ohne HTTPS finde ich eigentlich immer ein NoGo.

Für externe Zugriffe auf die API würde ich auf jeden Fall oAuth2 nehmen und nicht Basic-Auth auch wenn es deutlich mehr aufwand ist


----------



## temi (26. Jun 2021)

NicoDeluxe hat gesagt.:


> Alles in Allem ist das doch aber ein guter Plan oder gibts noch Verbesserungsvorschläge?


Vielleicht eine Spinnerei, aber der Vorschlag von @mrBrown war ja ein separater Dienst für das Passwort. Vielleicht gibt es da ja auch was Fertiges, z. B. so wie KeePass.


----------



## OnDemand (26. Jun 2021)

Thallius hat gesagt.:


> Für externe Zugriffe auf die API würde ich auf jeden Fall oAuth2 nehmen und nicht Basic-Auth auch wenn es deutlich mehr aufwand ist


merk ich mir für unsere neue App vor, die wo wir grad verbessern ist eh nicht mehr so irre lange online. Da muss Basic noch reichen. Aber was glaubst du, wie viele andere Systeme Basic nehmen. Wir haben 6 fremde Systeme angebunden, alle nutzen Basic


----------



## mrBrown (26. Jun 2021)

temi hat gesagt.:


> Vielleicht eine Spinnerei, aber der Vorschlag von @mrBrown war ja ein separater Dienst für das Passwort. Vielleicht gibt es da ja auch was Fertiges, z. B. so wie KeePass.


Ich meinte nicht nur einen Service für das Passwort selbst, sondern ein vom Rest getrennter Service, der die Dinge, für die das Passwort nötig ist selbst macht, und das Passwort nie nach außen gibt 

Wenn der Service von außen nur über SSH erreichbar ist, hat man nahezu alle Angriffsmöglichkeiten ausgeschlossen.



NicoDeluxe hat gesagt.:


> merk ich mir für unsere neue App vor, die wo wir grad verbessern ist eh nicht mehr so irre lange online. Da muss Basic noch reichen. Aber was glaubst du, wie viele andere Systeme Basic nehmen. Wir haben 6 fremde Systeme angebunden, alle nutzen Basic


Basic schützt auch nur die Client-Daten, deine eigenen Daten kann man damit nicht schützen – für reine M2M Kommunikation über HTTPS reicht Basic meist aus, Angriffsmöglichkeiten gibts da wenige.


----------



## OnDemand (26. Jun 2021)

Hm wie genau meinst du. Mein Main Service ist im prinzip nicht zu erreichen ausser jemand kommt per SSH und kopiert sich die jar Datei und reversed sie. Dann kommt er an den AES key, hat dann aber noch keine Info was er damit macht. Die DB Verbindungdaten liegen in Dateien da kommt nur der root User ran (der sich mit dem KeyFile per SSH einloggen muss)


----------



## mrBrown (26. Jun 2021)

NicoDeluxe hat gesagt.:


> Hm wie genau meinst du. Mein Main Service ist im prinzip nicht zu erreichen ausser jemand kommt per SSH und kopiert sich die jar Datei und reversed sie. Dann kommt er an den AES key, hat dann aber noch keine Info was er damit macht. Die DB Verbindungdaten liegen in Dateien da kommt nur der root User ran (der sich mit dem KeyFile per SSH einloggen muss)



"nicht erreichbar" heißt genau das - es gibt keine Möglichkeit den Service irgendwie direkt von außen anzusprechen, insbesondere nicht über HTTP.

Wenn SSH per public-key die einzige Zugriffsmöglichkeit ist, hat ein Angreifer keine realistische Möglichkeit.


----------



## OnDemand (26. Jun 2021)

über HTTP nur über unsere API (die ja aber nur an 2 IP antwortet) Dann müsste er den anderen Server oder meinen lokalen Rechner kapern.


----------



## mrBrown (26. Jun 2021)

NicoDeluxe hat gesagt.:


> über HTTP nur über unsere API (die ja aber nur an 2 IP antwortet) Dann müsste er den anderen Server oder meinen lokalen Rechner kapern.


Nahezu alle größeren in letzter Zeit bekannt gewordenen Hacks liefen über das kapern lokaler Rechner


----------



## OnDemand (26. Jun 2021)

Ok ich nutze Mac, hilft das 😂


----------



## mihe7 (26. Jun 2021)

NicoDeluxe hat gesagt.:


> AES ist jetzt nicht soooo der bringer


Wie meinst Du das? Hab ich was verpasst?


----------



## OnDemand (26. Jun 2021)

Habs mit Sha verwechselt sorry


----------



## mihe7 (26. Jun 2021)

NicoDeluxe hat gesagt.:


> Moment mal, haben wir glaube ich. Ich hab die Keydatei gespeichert daher ist mir das gar nicht mehr so bewusst.
> Login mit PW geht aber dennoch. Das lass ich gleich mal abschalten, danke für den Tipp


BTW: wir haben alles abgeschaltet, was nicht benötigt wird. Man verliert zwar ggf. die Kompatibilität zu Clients und ist auch nicht mehr ganz SSH-konform, das ist aber dann Problem der Clients  Bei der Einrichtung orientieren wir uns an den Empfehlungen des BSI, ergänzen diese aber um weitere (z. B. Curve 22519 statt ECDH), setzen größere Schlüssel ein, nur DH-Gruppen 16 und 18 (4096, 8192 Bits) usw.


----------



## OnDemand (26. Jun 2021)

Hat jemand ne Idee, wie ich an der Stelle meine IP ausspucken kann? Scheint ne andere als localhost zu sein


```
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .authorizeRequests().antMatchers("/**").hasIpAddress("127.0.0.1")
            .anyRequest().authenticated()
            .and()
            .httpBasic();
}
```



mihe7 hat gesagt.:


> BTW: wir haben alles abgeschaltet, was nicht benötigt wird. Man verliert zwar ggf. die Kompatibilität zu Clients und ist auch nicht mehr ganz SSH-konform, das ist aber dann Problem der Clients  Bei der Einrichtung orientieren wir uns an den Empfehlungen des BSI, ergänzen diese aber um weitere (z. B. Curve 22519 statt ECDH), setzen größere Schlüssel ein, nur DH-Gruppen 16 und 18 (4096, 8192 Bits) usw.


ooookay das ist zu technisch, das interessiert bestimmt meinen Servermenschen


----------



## mrBrown (26. Jun 2021)

NicoDeluxe hat gesagt.:


> Hat jemand ne Idee, wie ich an der Stelle meine IP ausspucken kann? Scheint ne andere als localhost zu sein


Was hast du da überhaupt vor??


----------



## OnDemand (26. Jun 2021)

Ich teste den API Zugriff auf eine Whitelisted IP zu beschränken (im og Code meine lokale IP). Auf einem Testserver klappts, bekomme nur Zugriff wenn ich von einer dort angegebenen IP komme. Lokal klappts nicht, hab scheibar keine 127.0.0.1 auf meinem lokalen Rechner.


----------



## Jw456 (26. Jun 2021)

Wenn du von einen anderen Rechner kommst hast du nie die localhost IP.


----------



## OnDemand (26. Jun 2021)

Das ist klar, aber wenn ich von localhost auf localhost zugreife schon (App läuft zum test auf lokalhost) aber irgendwie macht meine Fritzbox/Mac einen hostnamen davor / dahinter wie auch immer.


----------



## Jw456 (26. Jun 2021)

Das hat mit deine fritzbox nichts zu tun.
Die ist da rarn nicht  beteiligt.


Wenn du das brauchst willst musst du eine Weiterleitung bridge auf deinem Rechner erstellen.


----------



## OnDemand (26. Jun 2021)

hmm mein rechnername wird mir aber als mbp-fritzbox angezeigt zb in eureka (wo sich die services registrieren) in der hosts steht das auch drin. 
merkwürdig


----------



## mihe7 (27. Jun 2021)

127.0.0.1 ist der lokale Rechner mit der Top-Level-Domain "localhost". Die Pakete laufen durch einen virtuellen Netzwerk-Adapter (Loopback-Adapter) und werden an den Rechner zurückgeschleift. Dein WLAN/LAN-Adapter hat eine andere Adresse z. B. 192.168.172.25 (wird ggf. per DHCP zugewiesen). In diesem Netz ist dann Dein Rechner als z. B. rechner.fritz.box bekannt. Der Host rechner.fritz.box hat die IP 192.168.172.25, während localhost 127.0.0.1 hat. Wenn eine Anwendung derart konfiguriert wird, dass sie nur auf 127.0.0.1 lauscht, dann werden Pakete aus dem FritzBox-Netzwerk nicht beantwortet.


----------



## OnDemand (27. Jun 2021)

danke, ist ein vorkonfugurierter Router.  Danke für die Auflösung!


----------



## mihe7 (27. Jun 2021)

Ja, wobei das nix mit der Namensauflösung zu tun hat. Die ist lokal konfiguriert. Ich weiß nicht, wie das beim Mac ist, unter Linux gibts unter /etc/nsswitch.conf eine Datei, in der die Reihenfolge festgelegt wird, z. B., dass zuerst in den Dateien gesucht, dann erst der DNS verwendet wird (Konfiguration in /etc/resolv.conf). In der Datei /etc/hosts finden sich dann z. B. die Einträge für localhost.


----------



## OnDemand (27. Jun 2021)

Die /etc/nsswitch.conf gibts nicht

hosts sagt folgendes


und die resolv.conf:


----------



## mihe7 (27. Jun 2021)

Jo, sieht doch gut aus, in /etc/hosts steht, dass localhost die Adresse 127.0.0.1 trägt


----------



## OnDemand (20. Sep 2021)

Hallo zusammen,

zum Thema nochmal eine Frage.

Ich speichere mit Hibernate AES verschlüsselt Daten ab. Wo könnte ich den Schlüssel hinterlegen ausser in der Annotation? Das könnte jemand reverseengeneeren vorausgesetzt er hat Zugriff auf die jar datei?


```
ColumnTransformer(
            read = "AES_DECRYPT(data_value, 'secret-......')",
            write = "AES_ENCRYPT (?, 'secret-......')"
    )
    private String dataValue;
```


----------



## Oneixee5 (20. Sep 2021)

NicoDeluxe hat gesagt.:


> Wo könnte ich den Schlüssel hinterlegen ausser in der Annotation?


Der Schlüssel ist auch im GIT-Repo sichtbar, "reverseengeneeren" ist also evtl. gar nicht notwendig. Solange der Schlüssel im Code steht gewinnt man leider keinerlei Sicherheit dazu wenn die Anwendung auf eine nicht gewollte Art und Weise benutzt wird. Ich denke vorteilhafter wäre es den Tablespace zu verschlüsseln oder die DB auf einem verschlüsseltem Storage zu betreiben. Die Berechtigungen zum Datenzugriff kann man z.B.: auf User-, Gruppen-, Rollen- oder API-Key-Ebene vergeben. Bei EE-DB's funktioniert das auch auf Spaltenebene. Es macht imho keinen Sinn für alle Daten den selben Schlüssel zu verwenden. Wenn ein Nutzer einmal Zugang zur Tabelle hat, dann kann er ja alle Daten entschlüsseln, nicht nur die, für die er auch berechtigt ist.


----------



## OnDemand (20. Sep 2021)

Ja stimmt :/ 

Es ist aber schon mal sicherer als die Daten unverschlüsselt zu speichern. Wenn jemand an die DB kommen sollte, kann er die Daten schon mal nicht auslesen.

Zugang wird ein User nicht bekommen, die DB ist von den eigentlichen Usern nicht zugänglich. Möchten es nur vor Datenklau schützen

An die DB kommen ist nur über folgende Wege möglich:
- SSH nur von 2 IP zugelassen
- DB Verbdindung nur von Localhost erlaubt


----------



## OnDemand (21. Sep 2021)

Wie wäre es, wenn man das Passwort verschlüsselt in die properties legt wie auch die dB Zugangsdaten? Das sollte doch dann schon mal etwas sicherer sein?









						How to secure secrets and passwords in Springboot?
					

What?




					medium.com


----------



## Oneixee5 (21. Sep 2021)

NicoDeluxe hat gesagt.:


> Wie wäre es, wenn man das Passwort verschlüsselt in die properties legt wie auch die dB Zugangsdaten? Das sollte doch dann schon mal etwas sicherer sein?


So machen wir das in Entwicklungsumgebungen, dort sind die Sicherheitsanforderungen nicht so hoch. Besser funktioniert das mit Docker-Secrets, insofern man Docker einsetzt.


----------

