Apr 29, 2011

Digitális aláírás PHP használatával

A digitális aláírásról bizonyára már mindenki hallott és talán már a gyakorlatban is találkozott vele - nem összekeverendő az elektronikus aláírással. A digitális aláíráshoz tartozó elméleti résszel (nyilvános kulcsú titkosítás) most nem foglalkozom - érdemes utánaolvasni -, jelenleg kizárólag a digitális aláírásra és annak gyakorlati megvalósítására koncentrálunk PHP alól.

Mi is az a digitális aláírás?

Tfh hogy van egy doksink amit, mint feladó el szeretnénk küldeni egy címzettnek. Eddig könnyűnek is tűnik a feladat. Viszont mi mindezt úgy szeretnénk megtenni, hogy a címzett biztos lehessen abban, hogy a dokumentum tőlünk származik és nem módosította senki más.

Aláírás és ellenőrzés folyamata - Wiki-től kölcsönözve - a következő:



Aláírás:
A doksiból képzünk egy hash-t (pl sha1_file()), melyet aztán titkosítunk a privát kulcsunkkal. A dokumentumhoz valamilyen formában hozzácsapjuk az aláírást (attached/detached) és a tanusítványt, majd küldhetjük is a címzetteknek.

Ellenőrzés:
Megkaptuk a dokumentumot az aláírással és a tanusítvánnyal együtt. Elolvasás előtt meg szeretnénk bizonyosodni arról, hogy valóban a megfelelő feladó készítette a dokumentumot. Szóval a két körös forduló első részében fogjuk az aláírást és feloldjuk a tanusítványban található publikus kulccsal. Ekkor rendelkezésre áll a küldő által biztosított hash. Ezt össze kell hasonlítanunk a dokumentum hash-ével. Így a második körben mi is - akár csak a küldő - hasheljük a dokumentumot és ha megegyezik az aláírásból feloldott hash-el, nyert ügyünk van.

Azt hogy a küldő milyen hashelő algoritmust használt, az aláírásból deríthetjük ki ill. annak egy meta infojából. Tehát az aláírás a titkosított hash-en kívül tartalmazza a hashelő algoritmust és tartalmazhat egyéb információkat is (pl verziószám).

A tanusítványról pedig tudjuk, hogy a publikus kulcson kívül a szabványának megfelelően még sokféle adatot tartalmaz. Az x.509-es tanusítvány felépítése: link.

Ennyit a digitális aláírás elméleti részéről és most nézzük meg mindezt, hogyan ültethetjük át a gyakorlatba. Először privát kulcsot és tanusítványt kell készítenünk, majd PHP-val aláírást készítő és ellenőrző szkriptet. Mindkét esetben az OpenSSL-t fogjuk használni.

Privát kulcs generálás:
openssl genrsa -out private.key 1024



Tanusítvány kérelem:
openssl req -new -nodes -key private.key -out cert_request.csr


Tanusítvány:
openssl x509 -req -days 100 -in cert_request.csr -signkey private.key -out cert.pem



PHP-ban az OpenSSL modult fogjuk használni a digitális aláírás készítéséhez és annak ellenőrzéséhez. Akár magunk is végigjárhatjuk ezt a két folyamatot végighaladva egyesével az alfeladatokon:

Aláírás:
  • privát kulcs kiolvasása
  • file-ról hash készítés
  • hash titkosítása a privát kulccsal
Ellenőrzés:
  • tanusítványból a publikus kulcs kiolvasása
  • az aláírás titkosított részének feloldása a nyilvános kulccsal
  • hash készítése a file-ról
  • a kapott hash ellenőrzése a az aláírásban már feloldottal
Az OpenSSL viszont biztosít számunkra egy-egy függvényt az előbbi két feladatra: sign, verify. Mielőtt azonban a kódolásra térnék találjunk ki egy struktúrát az aláírásnak: Vegyük alapul a PGP inline (attached) aláírási módját (amit egyébként az email-ek aláírásánál is használatos). Ez a módszer plain text-nél megfelelő de binárisnál már jobban járunk ha külön file-t (detached signature file) készítünk az aláírásnak.

-----BEGIN SIGNED MESSAGE----- 
Hash: -Algoritmus- (pl md5, sha1)
-Tartalom-
-----BEGIN SIGNATURE----- 
Version: -Verziószám-
-Titkosított hash-
-----END SIGNATURE-----

Kész a struktúránk, nézzük az aláíró kódot:



Lefuttatva az aláírást az alábbi eredményhez hasonlót kapunk:
-----BEGIN SIGNED MESSAGE----- 
Hash: sha1
This is a simple document, digitally signed with PHP[OpenSSL] by b3ha
-----BEGIN SIGNATURE----- 
Version: 1.0
G1qngHs3HJmkZLyNz8AkatvCdvx00Svf+bhWCKUwauL6af/bxlh/xrxBiOCG0bFee/Iv6VG
F+L1gWd74f8HCccnQ64lGpfsCCKlyfV4g3iqAJndp4a7KG3ieZd0Qa4UjIkajUpSLXRPocJ
dx4InDTIFhYHEvZu0NzBraQmkePEU=
-----END SIGNATURE-----


Majd az ellenőrzést végző szkript:


Hasznos, érdekes linkek:

http://stackoverflow.com/questions/589834/what-rsa-key-length-should-i-use-for-my-ssl-certificates
http://www.sslshopper.com/csr-decoder.html
http://www.sslshopper.com/certificate-decoder.html
http://www.w3.org/TR/xmldsig-core/

2 comments: