In un precedente post ho parlato di come cifrare una stringa in javascript con RSA ora è arrivato il momento di mostrare un utilizzo pratico di questa tecnica. Il controllo login standard di asp.net 2.0 è infatti poco sicuro perché spedisce la password dell'utente in chiaro e quindi dovrebbe essere sempre utilizzato in contesto https. Purtroppo per hosting a "poco prezzo" ma in generale se non si ha a disposizione https, sarebbe comunque doveroso non far girare per la rete le credenziali dell'utente in chiaro. Per fare questo si procede in questo modo, ecco come si presenta la pagina di login.
<script language="javascript" src="RSA/BigInt.js" type="text/javascript"></script>
<script language="javascript" src="RSA/Barrett.js" type="text/javascript"></script>
<script language="javascript" src="RSA/RSA.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function EncryptPassword() {
var EncExponent = document.getElementById("encryptionExponent").value;
var DecExponent = "";
var EncModulus= document.getElementById("modulus").value;
setMaxDigits(130);
key = new RSAKeyPair(EncExponent, DecExponent, EncModulus);
document.getElementById("EncryptedPassword").value =
encryptedString(key, document.getElementById("Login1$Password").value);
document.getElementById("Login1$Password").value = "*********";
}
</script>
...
<asp:Login ID="Login1" runat="server" OnAuthenticate="OnLoggingIn" OnLoggedIn="OnLoggedIn">
</asp:Login>
<asp:HiddenField ID="encryptionExponent" runat="server" />
<asp:HiddenField ID="modulus" runat="server" />
<asp:HiddenField ID="EncryptedPassword" runat="server" />
Come si può vedere si importano i file js che implementano l'algoritmo RSA, poi si crea una semplice funzione che genera una nuova chiave crittografica dalla chiave pubblica mantenuta negli hiddenfield encryptionExponent e modulus, con questa chiave pubblica si può cifrare il contenuto della textbox password, e sostituire al suo contenuto una bella serie di asterischi, la password cifrata viene invece messa in un hiddenfield chiamato EncryptedPassword. Il code behind è altrettanto semplice e può essere consultato nell'esempio accluso. Nell'evento load viene generato un nuovo RsaCryptoServiceProvider, esportata la sua parte pubblica, inserita negli appositi ridde field ed infine messo in sessione
if (!IsPostBack) {
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
RSAParameters publicKey = provider.ExportParameters(true);
encryptionExponent.Value = BitConverter.ToString(publicKey.Exponent).Replace("-", "");
modulus.Value = BitConverter.ToString(publicKey.Modulus).Replace("-", "");
Session["key"] = provider;
}
L'altro evento degno di nota è invece l'OnLoggingIn del controllo login, dove bisogna fare la decrittazione della password e l'autenticazione.
public void OnLoggingIn(Object sender, AuthenticateEventArgs e) {
TextBox userTextBox = (TextBox) Login1.FindControl("UserName");
String password = DecryptPassword();
e.Authenticated = Membership.ValidateUser(userTextBox.Text, password);
}
Come si può vedere non si fa altro che decrittare e delegare il tutto alla ValidateUser della membership, il gioco è cosi fatto.
Alk. (Scarica l'esempio)