martedì 27 gennaio 2015

Cifratura a chiave asimmetrica

Nel post precedente abbiamo visto come cifrare utilizzando un sistema a chiave simmetrica, oggi vedremo come cifrare utilizzando un sistema a chiave asimmetrica.
Prima di vedere gli strumenti che livecode ci mette a disposizione, preferisco fare un'introduzione a questo nuovo tipo di cifratura. Questo sistema è di tipo molto recente, e basa la sua affidabilità sulla lentezza dei computer moderni. Quando si vuole offuscare un testo con questo sistema, si generano una coppia di chiavi: una pubblica e una privata. Chi vuole inviarvi un testo deve cifrarlo utilizzando la vostra chiave pubblica, mentre solo voi in possesso della chiave controparte privata sarete in grado di decifrarlo.
Quindi lo scambio di informazioni fra due persone si può ottenere solo con 2 coppie di chiave, una coppia per destinatario; ecco uno schema esemplificatore:
Finchè i nostri computer non saranno in grado di risalire velocemente alla chiave pubblica dalla chiave privata, questo sistema sarà sicuro. D'altro canto è sempre matematicamente possibile risalire alla chiave pubblica per tentativi con i computer, ma il tempo attuale è sui 100 anni.
Enti governativi con a disposizione enormi gruppi di calcolatori, possono ridurre questo tempo utilizzando una potenza di calcolo molto elevata, e la cifratura di tipo simmetrico allora diviene più sicura. Altri sostenitori della cifratura asimmetrica preferiscono allungare in numero di bit di cui è formata la chiave, poichè questo allunga il tempo di elaborazione per scovare la chiave privata della chiave pubblica; ma questo stratagemma allunga anche il tempo per decifrare un messaggio, anche avendo la chiave privata.
A titolo di esempio generiamo una coppia di chiavi RSA a 512 bit. Quella pubblica sarà:

-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALaULMjivN2L2xGBnUTqyGAwFY9AJE6b
8bT0CZPA9XMt+M0DULRzE5lL6JkstBAqep3iopd0/285lFnoSyVYQkkCAwEAAQ==
-----END PUBLIC KEY-----


Notate che è obbligatorio mettere anche i trattini e le scritte BEGIN/END public key.
Quella privata sarà:

-----BEGIN RSA PRIVATE KEY-----
MIIBPAIBAAJBALaULMjivN2L2xGBnUTqyGAwFY9AJE6b8bT0CZPA9XMt+M0DULRz
E5lL6JkstBAqep3iopd0/285lFnoSyVYQkkCAwEAAQJAcRn9XDxJLxzyCjg2ynh+
xEdFM8ZSN3gXFTePrz37TuuBZJquvi3d5LtfS8yLX0Ucy6PcndlsDY5TCJjdBAN+
uQIhAOMeEfwF2PHzhs/Q8eE6h4X8l2++UtN01QUURywxM483AiEAzcwgCP7IKa1h
FneEd5RErzywIGMG5NFtrIzL5sOcen8CIQDSZJ3WcPhLEwTU6UPZGKZJCfijjJUf
zEA151YTazTPOwIhAIaxyW3ZxAxzLA5WX18cre+72tL3vXVaFVxQMsxwzyPlAiEA
4xaelAVHHsClDuCw6i3NkoYTD7wg9ysNx1d/1nbMB98=
-----END RSA PRIVATE KEY-----


Facciamo uno stack contenente  sia il messaggio che vogliamo cifrare, sia le chiavi (le potete generare anche on line dal sito: http://travistidwell.com/jsencrypt/demo/).

Ora dobbiamo considerare che il sistema RSA prevede che il messaggio sia un multiplo di 52 lettere, quindi bisogna fare un controllo sul testo e aggiungere tanti spazi vuoti, quanti necessitiamo per ottenere un testo lungo un multiplo di 52 lettere. Nel pulsante cifra possiamo mettere il seguente codice:

on mouseUp
   put the text of field "testo" into testo
   put the number of chars of testo into lungtesto
   put round(lungtesto / 52) into cicli
   if (( lungtesto mod 52) is not 0 ) then
      put cicli + 1 into cicli
      put lungtesto mod 52 into temp
      #aggiungiamo gli spazi necessari
      repeat for temp times
         put " " after testo
      end repeat
   end if
   put the text of field "publickey" into passw
   put the text of field "privatekey" into passw2
   repeat with i=1 to cicli
      put char (52 * (i-1) + 1) to (i * 52) of testo into temp
      encrypt temp using rsa with public key passw      
      if the result is not empty then
         answer the result #c'è un errore, vediamo qual è
      else
         put it after tutto         
      end if
   end repeat
   set the text of field "cifrato" to tutto   
end mouseUp


e otteniamo per ogni gruppo di 52 lettere, 64 lettere cifrate. Nel campo cifrato apparirà il testo cifrato e incomprensibile.
Notate che il sistema RSA aggiunge delle variabili casuali, quindi, nonostante il messaggio originale sia sempre lo stesso, il risultato cifrato è sempre diverso.
Nel codice rsa non  è virgolettato.
Ora per recuperare il testo originale dobbiamo fare il procedimento inverso, 64 lettere alla volta; per questo nel pulsante decifra possiamo mettere il seguente codice:

on mouseUp
   put the text of field "cifrato" into testo
   put the text of field "privatekey" into passw   
   put the number of chars of testo into lungtesto   
   if (lungtesto mod 64) is not 0 then
      answer "non è un messaggio cifrato con RSA"
      exit mouseup
   end if
   put lungtesto / 64 into cicli
   repeat with i=1 to cicli
      put char (64 * (i-1) + 1) to (i * 64) of testo into temp
      decrypt temp using rsa with private key passw
      put it after tutto
   end repeat   
   answer tutto
end mouseUp


Se in decrypt usate la parola public invece di private, state solo verificando se è stato cifrato con la chiave pubblica corretta.
Ora sapete come inviare un messaggio utilizzando solo una cifratura asimmetrica.
Siccome ogni forma di dato può essere trasformato in testo con la funzione base64encode, potrete inviare anche musiche, immagini, filmati o qualsiasi altro tipo di file in maniera cifrata.