Mi venuta un'idea ieri sera.
Dopo qualche mese passato su un progetto Windows Form, ho pensato che fosse ora di riprendere un po' la parte Web.
Dopo che ho sviluppato il tutto, considerando le cose interessanti che ho scoperto e capito, ho pensato di bloggare il tutto.
Questa è la prima parte della spiegazione, dovrei riuscire a spiegare il tutto in due "puntate".
Obiettivo
Costruire uno "scrittore di password" in grado di evitare i keylogger eventualmente insidiati sul client.
Non è altro che una finestra browser che si apre visualizzando una tastiera. Cliccando con il mouse i vari tasti (ognuno corrispondente ad un carattere) viene riempito un campo che rappresenta quindi la nostra password.
Premendo poi il tasto Ok, la password viene inviata alla finestra browser che la richiede.*
* = Si tratta di una versione base, già alcune migliorie sono nella mia testa, altre sicuramente mi sfuggono e cmq, tanto per citare mio fratello, tutto è migliorabile.
Approccio
Tanto per cominciare ho pensato di suddividere la parte UI dalla parte di logica come meglio potevo.
Per far questo ho pensato di creare una classe Password che contenesse appunto la password, ma anche un metodo per la concatenazione dei caratteri alla stessa (che, in modo originale, ho chiamato Merge...come dite? troppo tempo a scombattere con il DataBinding? si, vero...).
Per la tastiera invece ho creato uno User Control (chissà perchè ho pensato di utilizzarlo in più punti, in realtà non è così ma mi sono comunque tenuto lo User Control, così mi sono esercitato anche su altro).
Poi ho prodotto la pagina ASP.Net che richiede la password e permette di richiamare la tastiera.
Realizzazione
Classe Password
Vediamo quindi la classe Password già accennata.
Ho incluso, oltre al costruttore semplice, anche quello con il passaggio già di un valore per la password, vedremo in seguito perchè.
Il codice della classe è il seguente:
Public Class Password
Private m_Valore As String
Public Sub New()
Valore = String.Empty
End Sub
Public Sub New(ByVal tmpValore As String)
Valore = tmpValore
End Sub
Property Valore() As String
Get
Return m_Valore
End Get
Set(ByVal value As String)
m_Valore = value
End Set
End Property
Public Sub Merge(ByVal val As String)
Me.Valore += val
End Sub
End Class
User Control WebKeyBoard e pagina KeyBoard.aspx
Per quanto riguarda la pagina con la tastiera ho fatto così: ho creato lo User Control (WebKeyBoard) contenuto dalla pagina KeyBoard.aspx.
Il WebKeyBoard è formato da una tabella, con tanti Bottoni (uno per carattere che si vuole mettere, in questo progetto sono previsti i numeri da 0 a 9), una TextBox in cui verrà composta la password e infine un Bottone di Ok (che invierà la password a chi la richiesta) e uno di Annulla (che chiuderà la tastiera).
Il codice (per ora) del controllo WebKeyBoard è il seguente:
Partial Class WebKeyBoard
Inherits System.Web.UI.UserControl
Private MyPWD As Password
Private Sub AggiornaStr(ByVal Valore As String)
MyPWD.Merge(Valore)
Me.txtPassword.Text = MyPWD.Valore
End Sub
Protected Sub btn1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn1.Click
AggiornaStr(sender.Text)
End Sub
Protected Sub btn2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn2.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn3.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn4_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn4.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn5_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn5.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn6_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn6.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn7_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn7.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn8_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn8.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn9_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn9.Click
AggiornaStr(sender.text)
End Sub
Protected Sub btn0_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn0.Click
AggiornaStr(sender.text)
End Sub
End Class
Quindi c'è un oggetto MyPWD (un'istanza della classe Password di cui abbiamo parlato) che contiene il valore della password che viene, di carattere in carattere, costruita.
La funzione AggiornaStr che, oltre a comporre la password, la aggiorna anche nella TextBox.
Poi ci sono i vari gestori d'evento dei Bottoni: qui ho fatto in modo che il Text del Bottone sia proprio il carattere da concatenare (come appunto succede nelle tastiere) quindi il tutto si riduce nel chiamare l'AggiornaStr passando il Text dell'oggetto che ha scatenato l'evento (sender).
Questo User Control verrà poi inserito nella pagina KeyBoard.aspx che non necessiterà di altro codice.
Pagina Default.aspx
La pagina che richiede la password sarà quindi formata da una TextBox (txtPassword) e da un HyperLink che permetterà l'apertura della pagina KeyBoard.aspx in un'altra finestra (target="_blank").
Ecco perchè la WebKeyBoard deve essere inserita in una pagina, altrimenti non è visualizzabile (e quindi utilizzabile) dall'utente.
Prima Conclusione
Fin qua il tutto non è stato difficile, per quello sono andato anche abbastanza veloce. Quando ero a questo punto nello sviluppo ho cominciato a pensare a come passare la password dal WebKeyBoard alla Default.aspx. Fondalmentalmente la difficoltà di questo progetto è tutta qui.
In passato avevo già fatto qualcosa di simile in JS, e volevo capire se fosse pienamente fattibile in ASP.Net.
La risposta è ni (con speranze di smentita). Nel senso che ASP.Net non supporta lo scambio di dati in finestre diverse, ma solo in pagine diverse (con la CrossPage Post o Server.Transfer).
Se pensate che ASP.Net rimane giustamente, come il vecchio ASP 3.0, una tecnologia server, effettivamente è abbastanza normale che non possa gestire diverse finestre del browser sul client.
Quindi mi era sempre più chiaro che avrei dovuto utilizzare ancora JS (senza rimorsi, in fondo mi trovo bene).
Il problema rimaneva quindi: come far dialogare dei controlli server con il client (JS)?
Come far in modo che allo scatenarsi di un evento di un web control (ovviamente sul server), quindi in "regime" .Net, possa dialogare con il client (JS)?
Per questa prima parte ho presentato solo quello che serve per impostare il progetto, nel prossimo post scriverò di come ho fatto a sviluppare quello che nell'oggetto ho chiamato (forse impropriamente) CrossWindow Post e che, più in generale, si tratta di far dialogare .Net con JS.
powered by IMHO Omar "Bromarock" Damiani