wtorek, lipca 24, 2007

Dokumentacja podpisu
CAPICOM ma nową wersję z maja - przejrzyj jego dokumentację (poprawki, nowe możliwości)
Może należy zwrócić się do ASP:
  • http://classicasp.aspfaq.com/forms/how-do-i-cause/prevent-enter-being-used-to-submit-a-form.html
  • http://classicasp.aspfaq.com/forms/how-do-i-upload-files-from-the-client-to-the-server.html
  • http://classicasp.aspfaq.com/components/should-i-use-createobject-or-server-createobject.html
  • http://www.aspencrypt.com/
  • http://www.codeproject.com/dotnet/CapicomUTF8.asp - można wymieniać sobie podpisane dokumenty między Java i .NET. Tej ścieżki jeszcze nie przetestowałem - wysyłanie podpisanego w .NET dokumentu do serwera bazującego na Apache z J2EE lub PHP (z biblioteką ssl). Ale artykuł pokazuje, że mogą być kłopoty (na szczęście daje ich rozwiązanie). W portalu wss.pl są ciekawe artykuły m.in. o podpisie dokumetów przy pomocy już bibliotek .NET, ale jak się ma z wymienialnością z np. Javą (openssl). Ten sam autor ma fundamentalny wkład w wyjaśnienie współpracy (nareszcie mam dobre słowona INEROPERABILITY - koperacje też dobre, ale kojarzy się z koperatywem) między światem kody zarządzalnego (managed) w .NET a kodem COM (z Win32) -http://www.codeproject.com/dotnet/cominterop.asp
  • Należy jeszcze raz przetestować przekazywanie plików z podpisem lub samych certyfikatów z MS do Unixa i ich tam obróbka przy pomocy np. biblioteki openssl. Do tej pory stwierdziłem, że udało mi się przenieść i rozpakować pd Unixem certyfikat pobrany z magazynu MS. Należy sprawdzić czy można takie coś zrobić z dokumentem.
  • http://www.codeproject.com/csharp/cryptography.asp?df=100&forumid=9241&exp=0&select=686555
  • http://blogs.msdn.com/johanl/pages/272768.aspx
  • http://www.feed-squirrel.com/index.cfm?evt=viewItem&ID=36269
  • http://developers.chrisranjana.com/javascripts/disabling-form-double-submits.html
  • http://articles.techrepublic.com.com/5100-22-1044655.html#Listing%20A
  • http://articles.techrepublic.com.com/5100-22-5034998.html
  • http://www.mail-archive.com/xul-talk@lists.sourceforge.net/msg00524.html
  • http://perfectionorvanity.com/2006/03/08/sposoby-odnajdywania-elementow-w-dom/
  • http://www.javascriptkit.com/javatutors/dynamiccontent5.shtml
  • http://groups.google.pl/group/comp.lang.javascript/browse_thread/thread/226e8a3839892fdb/45e224bdf8a83cf4?lnk=st&q=js+onkeypress+down+arrow&rnum=7&hl=pl#45e224bdf8a83cf4

Przykłady:
  • podsigillum.prg - podpisuje dowolny ciąg znaków. Podpis jest wykonany przy pomocy biblioteki Sigillum, sprawdzenie przy pomocy standardowej biblioteki CAPICOM. Uwaga, należy dbać o aktualną wersję tego komponentu, szczególnie w przypadku MS Windows Vista
    • LPARAMETERS tresc
      SET SAFETY off
      x = CREATEOBJECT("sigCapix.Crypto")
      SET PROCEDURE TO mcapi
      certyfikat = x.SelectCertificateFromSystemStore(0x10000, 'My') && Wybór certyfikatu
      podpisanaTresc = x.SignDetachedWithInfo(tresc, certyfikat) && Podpis zewnętrzny
      STRTOFILE(tresc,"plik.we")
      ?LEN(podpisanaTresc)
      STRTOFILE(podpisanaTresc,"mdane.txt")
      ?cverify("mdane.txt","plik.we",1) && Weryfikacja przy pomocy MS Windows CAPI
      SET SAFETY on
  • sprawdzpodpiszamow - sprawdza podpis pod dokumentem. Dokument i podpis jest przechowywany w polach (typu blob) w tablicy. W zależności od rodzaju podpisu mamy dwa przypadki
    • podpis wewnętrzny - przechowujemy w polu 'tresc' dokument orginalny, w polu 'podpis' ten sam dokument z hashem
    • podpis zwenetrzny - podobnie, ale w polu 'podpis' jest przchowywany tylko skrót (hash)
    • PARAMETERS klucz
      IF PCOUNT()!=1
      MESSAGEBOX("Brak parametru - klucz do dokumentu")
      RETURN
      ENDIF
      *klucz = "2007002883"
      CLEAR
      ?"Zamowienie = ",klucz
      ?weryf("00",klucz,"tresc.htm") && poczatek, tak wyglada dokument z tresci uformowanej przez Wolniwicza
      wyjscie = UpobDok(klucz,"eb_zam_dokz","zamid","podpis","podpis.txt") && trzeci
      IF AT("-2", wyjscie)=1
      ??", brak dokumentu..."
      RETURN
      ENDIF
      dlug = VAL(STREXTRACT(wyjscie,"dlug=","["))
      SET safety off
      STRTOFILE(CHRTRAN(FILETOSTR("podpis.txt"),' ','+'), "podpisOk.txt") && czwarty
      SET SAFETY on
      IF dlug > 10001
      ??", sprawdzam podpis wbudowany..."
      ?cverify_ext("podpisOk.txt","tresc.htm",0) && piaty
      ELSE
      ??", sprawdzam podpis zewnętrzny..."
      ?cverify_ext("podpisOk.txt","tresc.htm",1) && piaty
      ENDIF
  • Sprwadzenie wybranego certyfikatu z repozytorium MS Windows
  • #DEFINE CAPICOM_CHECK_NONE 0
    #DEFINE CAPICOM_CHECK_TRUSTED_ROOT 1
    #DEFINE CAPICOM_CHECK_TIME_VALIDITY 2
    #DEFINE CAPICOM_CHECK_SIGNATURE_VALIDITY 4
    #DEFINE CAPICOM_CHECK_ONLINE_REVOCATION_STATUS 8
    #DEFINE CAPICOM_CHECK_OFFLINE_REVOCATION_STATUS 16
    #DEFINE CAPICOM_CHECK_COMPLETE_CHAIN 32 && Łańcuch jest kompletny
    #DEFINE CAPICOM_CHECK_NAME_CONSTRAINTS 64
    #DEFINE CAPICOM_CHECK_BASIC_CONSTRAINTS 128
    #DEFINE CAPICOM_CHECK_NESTED_VALIDITY_PERIOD 256
    #DEFINE CAPICOM_CHECK_ONLINE_ALL 495 && NIe chodzi
    #DEFINE CAPICOM_CHECK_OFFLINE_ALL 503
    *
    clear
    Signer = CreateObject("CAPICOM.Signer")
    st = CreateObject("CAPICOM.Store")
    st.Open(2,"My")
    certyfikaty = st.Certificates
    IF certyfikaty.Count>0
    certyfikaty= certyfikaty.Select("Podpis cyfrowy dokumentu", "Proszę wybrać certyfikat do podpisania nim dokumentu ")
    ELSE
    MESSAGEBOX("Brak zainstalowanych kluczy i certyfikatów w systemie operacyjnym",16,"Podpis zamówienia")
    RETURN "-2"
    ENDIF
    cert = certyfikaty.item(1)
    *
    daneCertyfikatu = "Nazwisko = "+cert.GetInfo(6)+CHR(13)+"Dostępny = " + TRANSFORM(cert.PrivateKey.IsAccessible)+ CHR(13)
    daneCertyfikatu = daneCertyfikatu + "Czy można go użyć do badania niezaprzeczalności =" + TRANSFORM(cert.KeyUsage.IsNonRepudiationEnabled )+ CHR(13)
    daneCertyfikatu = daneCertyfikatu + "Data ważności =" + TRANSFORM(cert.ValidToDate)+ CHR(13)
    daneCertyfikatu = daneCertyfikatu + "Czy można sprawdzić listę CRL (zawiera URL) = " + TRANSFORM(cert.KeyUsage.IsCRLSignEnabled)+CHR(13)
    cert.IsValid.CheckFlag = CAPICOM_CHECK_TRUSTED_ROOT + CAPICOM_CHECK_TIME_VALIDITY + CAPICOM_CHECK_SIGNATURE_VALIDITY + ;
    CAPICOM_CHECK_COMPLETE_CHAIN + CAPICOM_CHECK_NAME_CONSTRAINTS + ;
    CAPICOM_CHECK_BASIC_CONSTRAINTS + CAPICOM_CHECK_NESTED_VALIDITY_PERIOD
    * Nowość - obiekt CertificateStatus
    *susp
    IF cert.IsValid.Result
    ?"Walidacja OK"

    ELSE
    ?"Wystąpił jakiś błąd. "
    ENDIF
    daneCertyfikatu = daneCertyfikatu + "Czy certyfikat jest ważny = " + ;
    TRANSFORM(cert.isValid.Result) + CHR(13)
    ?"Kod sprawdzenia łańcucha :"
    * Przed CHAIN musimy ustawić CheckFlag
    Chain = CreateObject("CAPICOM.Chain") && Waznosc calego lancucha
    waznosc = Chain.Build(cert)
    *susp
    kod = Chain.Status()
    DO CASE
    CASE kod=65
    komunikat = "Kod 65(64+1) Certyfikat nieważny (wygasł), status odwołania nieznany (tj. nie jest na liście)"
    CASE kod=64
    komunikat = "Kod 64 Status odwołania nieznany (tj. nie jest na liście)"
    CASE kod=16777280
    komunikat = "Kod 16777280(16777216+64) Status odwołania nieznany (tj. nie jest na liście). Nie ma lokalnej listy CRL w repozytorium"
    OTHERWISE
    komunikat = "Kod :"+ TRANSFORM(kod)
    ENDCASE
    ?komunikat
    ?"Informacja dodatkowa =" + Chain.ExtendedErrorInfo()
    ?"Waznosc calego lancucha =" + TRANSFORM(waznosc)
    messagebox(daneCertyfikatu)
    ?"Lista pośrednich certyfikatów:"
    iloscElem = Chain.Certificates.Count()
    ?"Ilość pośrednich certyfikatów :",iloscElem
    FOR i=1 TO iloscElem
    ?Chain.Certificates.Item(i).SubjectNAme
    ENDFOR
  • ss
  • ss

poniedziałek, lipca 23, 2007

Biblioteka AJAX w PHP - http://scriptex.tan-com.com/jPOP/index.php oparta o bibliotekę SimpleJS (http://simplejs.bleebot.com/)
Portal ZDNET w Anglii - http://www.zdnet.co.uk/

Bezpieczeństwo aplikacji w PHP (na podstawie - http://www.peachpit.com/articles/article.asp?p=711187&seqNum=4)
  1. Wprowadzone dane z formularza oczyść ze szkodliwych kodów (stosuj strip_tags) przed stosowaniem w apliakcji.
  2. Używaj odpowiednika mysqli_real_escape_data()czyszczenia danych z formularza przed zapisem do bazy.
  3. Nie używaj ustawień globlnych, ktoś może je zmienić i sam nie bedziesz wiedział kto i kiedy, inicjuj zmienne.
  4. Stosuj niejawne ustawienia w konfiguracji
  5. Przechowuj sesje w bazie
  6. Stosowanie wyrażeń regularnych jest efektywne ale mało wydajne i obciąża procesor
  7. Do sprawdzenia jawnego typów danych otrzymanych z formularza stosuj całą gamę funkcji ctype_.
  8. O ile to możliwe stosuje metodę POST (szczególnie gdy przesyłasz hasła) - nie widać w adresie URL argumentów (wada: n ie można strony zapamietać w zakładkach ulubione).
  9. Stosowanie zachowania stanu między stronami -sesje, ciasteczka, pola ukryte (type='hidden'). Te ostatnie sa bardzo skuteczne i łatwe w obsłudze, ale nie są bezpieczne (ktoś może podglądnąć zawartość strony). Wygoda kosztem bezpieczeństwa.
  10. To samo się tyczy nadmiernego polegania na zapamietaniu stanu poprzez przekazyanie danych między stronami w URL np. ?type=3, bardzo łatwo moża wywyłać stronę z innymi wartościami (już poza logiką aplikacji).
  11. Stosowanie CAPTCHA (completely automated public Turing test to tell computers and humans apart - pakiet PEAR Text_Captcha) jako obrona przed bot'ami.
  12. Stosuj filtry PECL do kontroli typów i wartości danych. Są dwa typy tych filtrów:
    1. Dane z formularza - źródłem może być: INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, INPUT_ENV, INPUT_SESSION, and INPUT_REQUEST:
      $id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, array('options'=>array('min_range'=>1)));
      if ($id) { ...
    2. Dane programowe - do kontroli danych w zmienych aplikacji:
      $id = filter_var(
    3. Sprawdzenie czy jest zmienna :
      if (filter_has_var(INPUT_POST, 'submitted')) {
    4. Tak możemy sprawdzić, czy formularz był wysłany.
  13. Filtry są wbudowane w PHP 5.2, dla wersji niższych trzeba doinstalować bibliotekę.
  14. Do logowania zastosować pakiet PECL Auth - zapewnia on standardową autentykację (stwierdzenie kto się chce dostać do portalu), lub można wykorzystać platformę rozwojową ZEND Framework.