Szyfrowanie atrybutów

Mam pewną zagwozdkę: chcę aby niektóre atrybuty obiektu były zapisywane w bazie w postaci zaszyfrowanej, a przy odczycie deszyfrowane.

Nie za bardzo mam pomysł jak to efektywnie rozwiązać. Najbliższe memu ideałowi rozwiązanie to gem attr_encrypted (https://github.com/shuber/attr_encrypted), ale jest tak wolne, że dzięki…

Myślałem, o użyciu AES_ENCRYPT i AES_DECRYPT z MySQL’a, ale wyzwalanych z poziomu aplikacji, a nie za pomocą triggerów, czy procedur składowanych (ze względów bezpieczeństwa).

Nie za bardzo mam pomysł jak to ugryźć, więc byłbym wdzięczny za jakieś wskazówki, pomysły, etc.

Chciałeś burzę mózgów? Proszę bardzo :wink:

Dlaczego toto jest powolne? Może zbyt często odszyfrowuje atrybuty, kiedy nie są potrzebne? A może użyć innego algorytmu?

Ewentualnie, może gem robi zbyt wiele, więc lepszy wynik uzyskasz pisząc własny, najprostszy z możliwych, akcesor?

def sekret
@sekret ||= decrypt_sekret
end
def decrypt_sekret
czary_mary( self.encrypted_sekret)
end

Ciekawy pomysł, za chwilę będę benchmarkował.

Dotychczas przeprowadziłem takie testy:

AR z ORM, bez szyfrowania
23.544542

AR z ORM, z AES w Railsach (z attr_encrypted)
98.779424

AR bez ORM, bez szfrowania
7.78645

AR bez ORM, z AES w MySQL
7.867954

Stąd kwestia powolności :slight_smile:

pomacaj na szybko jeszcze Strongboxa albo sentry - jak te również będą wolne, polecam rozwiązanie Arsena :wink:

Ok, zaraz obadam, póki co jest duży postęp :slight_smile:

AR z ORM, bez szyfrowania
22.67844

AR z ORM, z AES w Railsach
100.626618

AR z ROM, z accessorami + AESCrypt
27.933192

AR bez ORM, bez szfrowania
6.632387

AR bez ORM, z AES w MySQL
6.011774

czyli “tylko” 5s straty, to o niebo lepiej, niż 4 x tyle czasu…

To, że coś jest 10x wolniejsze nie znaczy iż jest wolne. Kompletnie źle podchodzisz (jak większość programistów) do kwestii wydajności.

Jestem w stanie się zgodzić na: “To, że coś jest 10x wolniejsze, nie znaczy, że nie jest wydajne”. Rozumiem Twoje intencje. :slight_smile: Byłbym wdzięczny jakbyś rozwinął swoje przemyślenia.

Od początku zakładałem, że czas to nie jedyny istotny czynnik, ale w tym przypadku ma dla mnie duży priorytet.

Pozwolisz na mały, praktyczny przykład. Moja droga do pracy wygląda tak:

  • idę do przystanku 3min
  • czekam około 2-4 min na tramwaj
  • jadę tramwajem 25 min
  • idę z przystanku do pracy 30s

Całość zajmuje jak widać niewiele ponad 30min (no chyba, że jakieś nieprzewidywane korki czy coś). Czy w takiej sytuacji byłby sens kupować magiczne buty (zapewne bardzo drogie :)), dzięki którym chodziłbym 10x szybciej? Oczywiście, że nie. Lepiej byłoby jeździć szybszym tramwajem. Podobnie może być w kwestii o której piszesz w topicku. Nieważne jest czy te szyfrowane accessory będą 10, 100 czy 1000 razy wolniejsze od zwykłych. Ważne jest to ile razy w 1 żądaniu będziesz je wywoływać i jaką część procesora zajmą. Oczywiście mogłoby się tak zdarzyć iż faktycznie będzie miało to dla Ciebie znaczenie, ale musisz to po prostu zmierzyć. Samo x razy wolniejsze po prostu nic nie znaczy (tutaj mi się tylko przypominają mega lamerskie, typowe dla phpa, rady w stylu “stosuj echo zamias print bo 1 000 000 wywołań tego pierwszego zajmuje 1s a tego drugiego 2s”).

+1 do tego co napisał Radarek :slight_smile: w aplikacjach znaczenie ma czas bezwzględny w milisekundach, a nie stosunki szybkości algorytmów

-1.

Znaczenie ma stosunek szybkości algorytmów przy tych zagadnieniach, które mają długi czas w milisekundach.

Sharnik, udajesz że nie zrozumiałeś tego co napisałem czy po prostu chcesz poflejmować w listopadowy wieczór? :slight_smile:

(stosunki szybkości algorytmów zaczynają mieć znaczenie WTEDY KIEDY przekładają się na duże czasy w milisekundach – teraz rozumiesz?)

No, bo czas w milisekundach zależy w prostej linii od szybkości algorytmów. Więc twoje dissowanie algorytmów było nie na miejscu.

Zresztą, Twoje powyższe zdanie to prosta trawestacja mojego posta, więc nie wiem o co ci chodzi z tym flejmowaniem, skoro właśnie przyznałeś mi rację…

Nie, czas w milisekundach zależy od ilości danych (elementów) na których algorytm operuje. A w jakiej “linii” rośnie czas w funkcji ilości elementów to już zależy od owego algorytmu złożoności obliczeniowej. Mogę Ci podrzucić literaturę na ten temat jak nie wierzysz :stuck_out_tongue:

@radarek: +1

@fidel: Co to znaczy AR bez ORM ? (wykonujesz może zapytanie SQL przez execute/find_by_sql) ?

Ano

@radarek - zgodzę się z Tobą, ale jeśli ta operacja staje jest tramwajem i mam do wyboru linię, która jedzie 10 minut i taką, która jedzie 25 minut, to wybieram tę pierwszą.

fidel, oczywiście. Tylko musisz to zmierzyć, a nie opierać tego na przypuszczeniach oraz nic nie mówiących “10, 100 razy wolniej” wywołaniach funkcji.

Fidel, po prostu przeczołgaj profilerem swoją aplikację i zobacz jakie to ma znaczenie. Jeśli dekodowanie zajmuje 2-5% całkowitego czasu przetwarzania żądania, to optymalizacja tego po prostu się nie opłaca.

Dzięki wszystkim za zaangażowanie w dyskusję i propozycje rozwiązań.