enkrypting, dekrypting, sajning, walidejting i chaszing

Uważni czytelnicy zapewne przerobili już poprzedni temat i wiedzą jak nie pozwolić nie powołanym osobom wykonać kodu, który nie jest dla nich przeznaczony. Ale może się zdarzyć, że zostaniemy przechytrzeni i ktoś nas perfidnie podsiądzie i skorzysta z sytuacji, gdy akurat zapomnimy zablokować swojego kompa. Ojej, co możemy wtedy zrobić? Nie peniajcie, albowiem z pomocą przychodzi technologia i geniusz matematyki. Nasze poufne dane możemy zaszyfrować i w ten sposób poczuć się jeszcze bardziej bezpieczni. Oprócz tego, można wygenerować sumę kontrolną, która będzie poprawna tylko dla jednej pliku. To na wypadek, gdyby ktoś chciał coś dopisać do listy zakupów. Nawet po najmniejszej zmianie jednego znaczka, hasz suma będzie całkowicie inna. Jeżeli nam tego mało, możemy wygenerować cyfrowy podpis dla pliku – tak wiem szaleństwo.

Jak tego wszystkiego dokonać?
Wystarczy skorzystać z jednego z gotowych rozwiązań, które oferuje nam Microsoft i C# (lub skorzystać z tego Truecrypt ale jakimi bylibyśmy programistami, gdyby nie skusiło nas napisanie własnej aplikacji, która też potrafi takie rzeczy lub przynajmniej podobne).


SZYFROWANIE
Aktualnie dostępne są dwa gotowe rodzaje szyfrowania symetryczne (szybsze) i asymetryczne (bezpieczniejsze, wolniejsze). zaimplementowane w C#. Symetryczne podejście do problemu możemy rozwiązać przy pomocy jednej z pięciu gotowych klas:

Jeżeli chcemy być bardziej pro i mamy więcej czasu,  można skorzystać z Asymetrycznego rozwiązania przy pomocy klasy:

O ile dla ludzi prostszym (czytelniejszym) jest symetryczny, podajemy hasło i sól (za wiki: losowa wartość (ang. salt) modulująca wynik tak, by użycie tego samego hasła dawało w wyniku inny klucz), można korzystać z dowolnych rozmiarów bloków danych, jest naprawdę szybciej, ale jest tylko jedno hasło, które służy do obu operacji szyfrowania i odszyfrowania.
O tyle asymetryczne korzystają z automagicznie (nawet nie wiedziałem, że znajdzie się do tego wiki) generowanych kluczy, które nie należą do najbardziej czytelnych (oczywiście dla ludzi), mają ograniczone rozmiary bloków szyfrowania, co za tym idzie dla większej porcji danych należy stworzyć większy klucz, co trwa naprawdę długo, a najgorsze jest to (naprawdę jest to złe i nie dobre) to nawet nie można używać własnego hasła. Bezpieczeństwo kosztuje.

Dobrze, po krótkim wstępie chciałbym zapisać jak korzystać z poszczególnych rozwiązań, kod jest do pobrania jak zwykle z xp-dev, także tutaj nie będę przyklejać kodu, żeby nie powiększać i tak długiego wpisu. Można to potraktować jako swojego rodzaju ściągawkę.
SYMETRYCZNIE

  • Tworzymy instancje klasy, która ma zaszyfrować nasze dane. Jedna z wymienionych powyżej.
  • Korzystając z klasy Rfc2898DeriveBytes zapodajemy hasło i sól od użytkownika, oraz pobieramy losowe bajty wygenerowane dla nas. Tylko w przypadku szyfrowania symetrycznego.
  • Należy pamiętać o poprawnej inicjalizacji KeySize, BlockSize, Key oraz IV (initialize vector)
  • Otwieramy strumień z danymi, które chcemy zaszyfrować i zaczytujemy porcję danych
  • Pobieramy interfejs do ICryptoTransform z klasy szyfrującej, tworzymy strumień wyjściowy szyfrujący, oraz otwieramy strumień do pliku wyjściowego
  • Piszemy do strumienia szyfrującego, korzystając z pobranego wcześniej interfejsu, strumienia wyjściowego i zaczytanych wcześniej danych, powtarzamy dla kolejnej porcji danych
  • Następnie trzeba już tylko wszytko pozamykać i powinno działać
  • Jeżeli użyty został algorytm asymetryczny, warto wyeksportować klucz publiczny i prywatny, aby nie utracić możliwość ponownego odczytania zaszyfrowanych danych. W przypadku symetrycznego “wystarczy”, że zapamiętamy hasło i sól.

ASYMETRYCZNIE

  • Stwórz klasę RSACryptoServiceProvider z rozmiarem klucza, z którego chcesz skorzystać. Tutaj trzeba uważać, jeżeli poda się za mały klucz, poleci wyjątek BadLength podczas próby szyfrowania
  • Zaczytaj dane do bufora bajtów (lub strumień)
  • Zaszyfruj dane
  • Zapamiętaj klucz prywatny i publiczny. Dla tych, którzy nie wiedzą co to, na początku wpisu jest link do wiki

Podczas odszyfrowywania (deszyfrowania) postępujemy podobnie tylko, że w drugą stronę, należy także pamiętać o zaimportowaniu odpowiedniego klucza, który pozwoli nam poprawnie odczytać dane.

HASZ SUMY
Generowanie hasz sum to już prosta sprawa. Ciekawa (przynajmniej dla mnie to było ciekawe) sprawa do obliczania sum możemy także skorzystać z pomocy haseł. Suma bez hasła można wyliczyć za pomocą jednej następujących klas:

Jeśli chcemy skorzystać z hasła podczas generowania sumy, powinniśmy skorzystać z jednej z następujących klas:

Sposób działania jest banalnie prosty

  • Stworzyć klasę haszującą, jeżeli korzystamy dodatkowo z hasła – przesłać do klasy w konstruktorze
  • Wysłać do niej porcję danych do obliczenia (lub strumień)
  • Zapytać się o hasz sumę i gdzieś sobie zapisać
  • Posprzątać po sobie

PODPISYWANIE PLIKÓW (PODPIS CYFROWY)
I już ostatni ze sposobów na zabezpieczenie się przed elektronicznymi bandytami to podpisanie pliku, czyli kolejny ciąg bajtów, którym możemy oznaczyć nasz i tylko nasz plik. Także tutaj w cały proces możemy wciągnąć akcję z hasłem.

Cały algorytm działania jest prosty

  • Tworzymy odpowiednią instancje
  • Ładnie prosimy o wygenerowanie podpisu dla zadanych danych (i ew. zaszyfrowanie)
  • Pobieramy wyniczek i coś z nim robimy
  • Zamykamy wszystko co zostało otworzone

W drugą stronę prawie tak samo, należy tylko zaimportować wynik poprzedniej operacji, zapewnić identyczny ciąg bajtów i poprosić o weryfikację.

Mam nadzieję, że to krótkie podsumowanie tematu choć trochę się to komuś przyda. Jeżeli są jakieś pytania, niejasności lub uwagi śmiało pisać.

JS

ps. Strach mnie bierze, gdy miałem kliknąć “publikuj posta” po napisaniu czegoś tak długiego.

autoryzowanie użytkowników

W życiu każdego z nas przychodzi taki moment, kiedy należy pamiętać o odpowiednim zabezpieczeniu się. W końcu nie możemy pozwalać wszystkim na wszystko – rajt?
Pisząc w C# mamy do dyspozycji pewien mechanizm, który może nam pomóc w udostępnianiu części kodu wybranym użytkownikom. Znajduje się on w:

using System.Security.Principal;
using System.Security.Permissions;

Możemy korzystać ze sprawdzania kodu w sposób deklaratywny, poprzez atrybuty przy funkcjach, gdy chcemy odciąć całą metodę dla wybranej grupy użytkowników.

[PrincipalPermission(SecurityAction.Demand, Role = "user")]
void foo(){}
Lub w imperatywny sposób (nie do końca wiem, jak to przetłumaczyć). Zasadnicza różnica polega na możliwości wyłączenie części kodu.
try
{
PrincipalPermission pp = new PrincipalPermission(null, @"BUILTINAdministrators", true);
pp.Demand();
MessageBox.Show("This message box should be only to admins", "Info");
}
catch (System.Security.SecurityException sec_ex)
{
MessageBox.Show(sec_ex.Message, sec_ex.GetType().Name);
}

Oczywiście są już gotowe klasy do tego wszystkiego PrincipalPermission.
Ale wiadomo że trzeba czasem zrobić coś inaczej/lepiej, wtedy trzeba wykorzystać dwa proste interfejsy

IIdentity
IPrincipal

Prosta implementacja i wszystko gotowe.

Jednak! Czasem nie ma potrzeby implementacji tego wszystkiego (jak się jest niezdecydowanym jak wiadomo kto), a wystarczy najprostsza implementacja, wtedy nie ma potrzeby implementacja tych interfejsów, a skorzystać można z gotowego rozwiązania

GenericIdentity
GenericPrincipal

Wszystko można obejrzeć i sprawdzić szczegóły korzystając z tego przygotowanego kodu, który jest dostępny jak zawsze na xp-dev.
Pisane późno w nocy, enyłej mam nadzieję że komuś się przyda.

Pomoc w WPF

Jak już się napisze aplikację, to czasem trzeba pomóc użytkownikowi odnaleźć się w gąszczu guzików, opcji, ustawień i innych zmiennych. Czas zagubiona dusza naciśnie F1 w nadziei na uzyskanie odrobiny więcej informacji na temat magicznego pola DevCtrlNo które przyjmuję tylko cyfry. Na przykład co ma tam wpisać i czy nie zepsuje się po wpisaniu złych wartości. Żeby tego dokonać, trzeba zaimplementować jakąś pomóc dla usera, np. poprzez F1. Można to zrobić także na inne sposoby, tooltip, dołączyć, html, czy inaczej. Ja góglując znalazłem taki jeden, który mi odpowiada i chce się tym sposobem podzielić.

Przykładowy kod jak zwykle na xp-dev. Tak jak poprzednio nie jest to mój wkład w wiedzę dotyczącą WPF, a jedynie opracowanie posta. Oryginalny wpis znaleźć można tutaj, a dodatkowe fikuśne bajery tutaj. Drugi link zawiera ciekawe artykuły dotyczące WPF – polecam przejrzenie.

Co trzeba zrobić by pięknie obsługiwać helpa?
– Nowy projekt
– Prze(pisz|kopiuj) klasę HelpProvider
– Dodaj brakujące namespace w xaml okna
– Rozszerz kontrolki o helpa
– Przejrzyj kod klasy, aby wyklikać ciekawsze efekty helpa niż tylko messagebox.

Oczywiście taki kod wspiera różne wersje językowe, ale o tym już pisałem wcześniej.

To tyle. Dla mnie taki help jest na wypasie, a dla was?

WPF w wielu językach

Jeżeli będziecie kiedyś w potrzebie zaimplementowania obsługi kilku języków w aplikacji opartej na WPF, to możecie skorzystać z tego wpisu. Nie jest to moje rozwiązanie, a raczej opracowanie artykułu znalezionego na codeproject. Jeżeli coś nie będzie działa, nie będzie jasne, czy w ogóle nie będzie to pytania kierujcie do mnie lub bezpośrednio do autora artykułu na codeproject. To co tutaj zamierzam umieścić, to tylko kilka kroków, które podsumowują całą pracę potrzebną do implementacji interesującej nas funkcjonalności. To tyle tytułem wyjaśnienia i wprowadzenia.
Nazwy klas odpowiadają tym, które zostały użyte w kodzie dostępnym pod tym adresem. Kod w przykładzie z codeproject używa innych nazw.

Kroki potrzebne do zaimplementowania funkcjonalności:
1) Utwórz projekt
2) Utwórz katalog w projekcie. W katalogu będziesz trzymać zasoby. Oraz implementacje klasy, zwracającej instancje zasobów, oraz obsługującej zmianę aktualnego języka
3) Dodaj zasoby do projektu
3a) Ustaw custom namespace na wpfMUI.Properties (wpfMUI to nazwa mojego projektu)
3b) Usuń domyślne zasoby z Properties
4) Utwórz klasę LocalResources
4a) Prze(pisz|kopiuj) kod klasy
5) Dodaj do projektu ResourceDictionary
5a)Prze(pisz|kopiuj) kod
6) W app.xaml dodaj ResourceDictionary do zasobów aplikacji, prze(pisz|kopiuj)
7) W Properties.Settings ustaw domyślną wartość dla CultureInfo, w przykładnie “en” jest domyślny
8) W inicjalizacji głównego okna skorzystaj z tej wartości, przeczytaj komentarz w projekcie.
9) Podepnij obsługę comboboxa, pamiętaj to tylko przykład. W normalnym projekcie, kto inny będzie informować klasę LocalResources o zmianach.
10) W zasobach ustaw dostęp na publiczny
10a) Stwórz kopie zasobów, zmień nazwę na Resources.en.resx
10b) Zrób kopie i zmień nazwę na Resources.pl.resx
10c) Ustaw odpowiednie wartości dla poszczególnych wersji językowych
11) Ustaw właściwy content dla kontrolek, np dla guzika:

Content="{Binding Path=buttonText, Source={StaticResource Resources}}"

Dla combobox:

ItemsSource="{Binding Mode=OneTime, Path=SupportedCultures,Source={StaticResource SuppCultures}}

Możesz też użyć ustawiania właściwości dla kontrolek, ale zauważyłem że Path i tak należy ustawić ręcznie.

Po tym wszystkim, możesz próbować kompilować projekt i odpalać. Potem tylko drobne poprawki i wszystko powinno działać. Projekt jak często można pobrać z xp-dev

Cieszysz się?

Porządek musi być

Pracuję mozolnie nad tajnym projektem i nawet jeżeli nie przyniesie potrzebnych milionów to przynajmniej zajmie trochę czasu, a może nauczę się czegoś. Ale nie o tym miałem pisać. Chodzi o porządki. Do tej pory pisałem sobie o wszystkim co miałem zrobić zgrabnie w kajeciku. Zapisywałem w zasadzie wszystko związane z projektem i wykorzystywaną technologią: co do zrobienia, jak zrobić to i tamto, jakieś sprawy o których miałem pomyśleć. Nawet dawało rade – nawet. Z czasem natłok zapisków zaczął powodować pewien brak czytelności, dla rozróżnienia wpisów dodawałem sobie “checkbox” przy rzeczach które wymagały zrobienia, wykrzykniki przy cennych 😉 uwagach, czy znaki zapytania przy sprawach wymagających przemyślenia. Działało nawet lepiej, ale nadal mieszało się z ogólnymi notatkami. Dzisiaj przesiadłem na się na góglowego eksela, a przynajmniej częściowo. Listę zadań do zrobienia i przemyślenia całkowicie przeniosłem w chmurę, dodałem status, priorytet, opis i kolory. Jak szaleć to szaleć. Mam nadzieję, że w ten sposób uda mi się trzymać listę rzeczy do zrobienia bardziej przejrzystą. Myślałem przez chwilę o zainstalowaniu jakiegoś wypasionego toola, ale uznałem to za przerost treści nad formą.

Tak tylko chciałem się tym z wami (moi wierni ninja czytelnicy) podzielić. Jak macie jakieś inne, może lepsze sposoby na prowadzenie swoich projektów to pisać.