Muszę przechować w systemie dane o płacach pracowników, tak zaszyfrowane żeby:
a) Pracownik mógł je sobie obejrzeć (ale nie jego koledzy)
b) Kierownik mógł obejrzeć płace swoich pracowników (ale nie pracowników innego kierownika)
c) Dyrektor mógł obejrzeć płace wszystkich którzy u niego pracują
Aplikacja nie może przechowywać kluczy używanych do szyfrowania/odszyfrowania.
Wyobrażam to sobie tak że każdy ma swój prywatny klucz którym szyfruje/deszyfruje dane na poziomie, do którego ma uprawnienia.
Nie tyle problem szyfrowania a dostepu jak dla mnie.
Czemu nie zrobic wspolnego systemu szyfrowania, tylko po to by dane byly zaszyfrowane. A dostep zrobic normlanie poprzez uprawnienia odpowiednie? Wydaje sie to dosc proste, po co kombinowac z osobnym szyfrowaniem? Czemu nie z poziomami dostepu?
Co do poziomu dostepu to np CanCan + Devise i masz z glowy
Jeżeli już koniecznie musisz szyfrować dane, a nie po prostu załatwić sprawę mechanizmem autoryzacji jak zasugerowali koledzy powyżej, to zainteresuj się kryptografią asymetryczną. Dane o płacach pracownika szyfrowane byłyby kluczem symetrycznym, natomiast sam klucz zaszyfrowany asymetrycznie kluczami publicznymi pracownika, kierownika i dyrektora (każdego oddzielnie) i przechowywany razem z rekordem pracownika. Do odszyfrowania można użyć dowolnego z odpowiadających kluczy prywatnych.
Poniewaz od kilku lat zajmuje sie projektem, w ktorym za glowny ‘core-feature’ stoi przechowywanie danych w postaci zaszyfrowanej w bazie, moge podzielic sie paroma spostrzezeniami:
jak astaroth slusznie zauwazyl, kluczem (sic!) jest uzycie szyfrowania z kluczem publicznym/prywatnym. Tworzac rekord poufny (badz pole poufne), tworzysz osobna kopie dla kazdego ‘odbiorcy’, szyfrujac zawartosc jego kluczem publicznym (uzywajac np. RSA). Istotne jest to, ze musisz utworzyc N kopii kazdej danej, bo kazda bedzie roznic sie na poziomie binarnym/bajtowym,
nie bedziesz mogl sortowac / wybierac zaszyfrowanych pol z poziomu SQL (bo sa zaszyfrowane),
poniewaz dane powinny byc odczytywalne przez danego uzytkownika (ktory moze je odszyfrowac swoim kluczem prywatnym), pojawia sie pytanie, w ktorym momencie deszyfrowanie ma nastepowac i gdzie przechowywane sa klucze prywatne (i w jakiej postaci). W przypadku wspomnianego projektu, klucze prywatne sa rowniez trzymane na serwerze, ale kazdy zaszyfrowany jest AES-em (szyfr symetryczny), gdzie kluczem jest haslo uzytkownika. Calosc wowczas jest tak ‘bezpieczna’ jak silne jest haslo uzytkownika (czyli zalezy). W momencie zmiany hasla, zakladajac ze uzytkownik podaje stare haslo i nowe, dokonuje ‘prze-szyfrowania’ klucza prywatnego nowym haslem (czyli klucz prywatny sam w sobie sie nie zmienia, czyli wszystkie dane ktore zostaly utworzone przed zmiana hasla sa nadal odczytywalne),
przy tego typu podejsciu, nalezy upewnic sie, ze przesylane dane (na serwer) nie sa logowane w postaci ‘otwartej’,
super bezpieczne podejscie (prawdopodobnie), wymagaloby przechowywania (i deszyfrowania) kluczy prywatnych w przegladarce - czyli na poziomie javascriptu. Powstal kiedys taki project/serwis pt. http://www.clipperz.com/ ktory poniekad opieral sie na tym podejsciu. Tylko wtedy sie jest uwiazanym do przegladarki. Wtedy administrator nie bedzie miec fizycznie mozliwosci podejrzenia danych.
Jedna uwaga techniczna: RSA nie nadaje sie (nie jest polecany) do szyfrowania dluzszych blokow. Mozna to robic rozbijajac calosc na kawalki (i tak zrobilem), ale polecana metoda, to wygenerowanie losowo klucza AES, zaszyfrowanie nim wiadomosci, zaszyfrowanie samego klucza przy pomocy RSA i doklejenie na koncu/poczatku wiadomosci.
Problem jest ‘ciekawy’, ale to wszystko ma sens glownie wtedy, gdy chcemy uniemozliwic odczytanie danych z poziomu bazy / admina. W przypadku blokowania dostepu na poziomie userow, pewnie wystarczy CanCan