Hi,
function decryptXtea(message,md5Key){
/*
Now we asume: a lot.
We asume: eight bits in a byte
We asume: 2s-complement encoding
We asume: message.length % 8 = 0
We asume: the same endianes in encryption and decryption
We asume: nobody reads this comment
*/
var m = new Array(2);
message = decodeBase64(message);
var len = message.length;
var result = "";
for(var i=0; i < len; i = i+8){
/* I could just brag a bit here
and babble sybilline about
"loop unrolling by hand" or sth.
But I don't. I think it's a better
idea to write useless comments
instead of useless loops. */
m[0] ^= 0x00000000;
m[1] ^= 0x00000000;
var sum = 0xC6EF3720;
var delta = 0x9E3779B9;
m[0] = message.charCodeAt(i);
m[0] |= message.charCodeAt(i+1) << 8;
m[0] |= message.charCodeAt(i+2) << 16;
m[0] |= message.charCodeAt(i+3) << 24;
m[1] = message.charCodeAt(i+4);
m[1] |= message.charCodeAt(i+5) << 8;
m[1] |= message.charCodeAt(i+6) << 16;
m[1] |= message.charCodeAt(i+7) << 24;
m[0] = m[0] & 0xFFFFFFFF;
m[1] = m[1] & 0xFFFFFFFF;
for(var j = 0; j < 32; j++){
m[1] -= ( ((m[0]<<4 ^ m[0]>>5) + m[0])
^ (sum + md5Key[sum>>11 & 3])
) & 0xFFFFFFFF;
sum = (sum - delta) & 0xFFFFFFFF;
m[0] -= ( ((m[1]<<4 ^ m[1]>>5) + m[1])
^ (sum + md5Key[sum & 3])
) & 0xFFFFFFFF;
}
result += String.fromCharCode(((m[0]&0x000000FF))&0xFF);
result += String.fromCharCode(((m[0]&0x0000FF00) >> 8)&0xFF);
result += String.fromCharCode(((m[0]&0x00FF0000) >> 16)&0xFF);
result += String.fromCharCode(((m[0]&0xFF000000) >> 24)&0xFF);
result += String.fromCharCode(((m[1]&0x000000FF))&0xFF);
result += String.fromCharCode(((m[1]&0x0000FF00) >> 8)&0xFF);
result += String.fromCharCode(((m[1]&0x00FF0000) >> 16)&0xFF);
result += String.fromCharCode(((m[1]&0xFF000000) >> 24)&0xFF);
}
return result;
}
/*
Converts a string of 8-bit-bytes into
their hexadecimal values.
*/
function toHexString(s){
var ret = "";
var len = s.length;
for (var i = 0;i < len; i++) {
//ret += (i % 8 == 0)?" ":"";
ret += (s.charCodeAt(i)&0xFF).toString(16);
}
return ret;
}
function formSubmit(user, pass, pass2){
var md5Key = new Array(4);
var formO = document.forms[0];
var xteaPadding = 0;
var taOrigO = formO.textareaoriginal;
var md5OrigO = formO.md5sumoriginal;
var taEncO = formO.textareaencrypted;
var md5EncO = formO.md5sumencrypted;
var taDecO = formO.textareadecrypted;
var md5DecO = formO.md5sumdecrypted;
var md5Orig2O = formO.md5sumoriginal2;
var encryptedString = "";
/*
Most little endian machines fullfill the conditions
mentioned in decryptXtea(), a test might be usefull.
*/
var tmpEndian = 1 >>> 1;
if(tmpEndian != 0){
alert( "Hey, it's only me: a poor 'n lonely"
+ "algorithm who can't afford to run on"
+ "better stuff than cheap PC-hardware!" );
}
if(user == "" || pass == "" || pass2 == ""){
alert("Bitte "
+ ((user == "" )?"Benutzername":
(pass == "" )?"Passwort":"Passwort zweimal")
+ " eingeben, danke.");
return;
}
if(taOrigO.value.length < 1){
alert("Bitte auch etwas zum verschlüsseln eingeben, danke.");
return
}
if(pass != pass2){
return;
}
/*
XTEA's keysize is a DWORD. The MD5 hash
conveniently provides that size.
*/
md5Key = MD5(pass);
/*
Padding with spaces (ASCII 0x20)
*/
while(taOrigO.value.length & 0x7){
taOrigO.value = taOrigO.value + " ";
/*
In most cases, a padding with spaces at the end
does not matter at all. A cryptographic signing
should in any case calculate the pure text and
none of the formating at all.
But, as I said above: only in _most_ cases.
*/
xteaPadding = taOrigO.value.length & 0x7;
}
taEncO.value = "";
md5OrigO.value = hex_md5(taOrigO.value);
encryptedString = encryptXtea(taOrigO.value,md5Key);
taEncO.value = javascriptHeader
+ javascriptDecryptionPartOne
+ encryptedString
+ javascriptDecryptionPartTwo;
md5EncO.value = hex_md5(taEncO.value);
taDecO.value = decryptXtea(encryptedString,md5Key);
md5DecO.value = hex_md5(taDecO.value);
md5Orig2O.value = md5OrigO.value;
}
function resetForm(){
document.encryptformular.reset();
}
//resetForm;
</script>
<style type="text/css">
fieldset{
padding: 1em;
margin-top: 1em;
width:25em;
border: 1px solid black;
}
legend {
border: 1px solid black;
}
</style>
</head>
<h1>Verschlüsselung mit Javascript</h1>
<form id="encryptformular"
name="encryptformular"
onsubmit="formSubmit(this.form.username.value,
this.form.password.value,
this.form.password2.value);return false">
<fieldset><legend>Schlüssel</legend>
Benutzername (wird hier nicht benutzt):<br>
<input name="username"
id="username"
type="text"
size="50"
maxlength="50" /><br>
Passwort:<br>
<input name="password"
id="password"
--type="password"--
type="text"
size="50"
maxlength="50" /><br>
Repeat passwort:<br>
<input name="password2"
id="password2"
--type="password"--
type="text"
size="50"
maxlength="50" /><br>
</fieldset>
<fieldset><legend>Originalnachricht</legend>
<textarea name="textareaoriginal" id="textareaoriginal" cols="80" rows="10"></textarea><br>
MD5SUM des Originals:<br>
<input name="md5sumoriginal"
id="md5sumoriginal"
type="text"
size="50"
maxlength="50" /><br>
</fieldset>
<fieldset><legend>Verschlüsselt</legend>
<textarea name="textareaencrypted" id="textareaencrypted"cols="80" rows="10"></textarea><br>
MD5SUM der verschlüsselten Nachricht:<br>
<input name="md5sumencrypted"
id="md5sumencrypted"
type="text"
size="50"
maxlength="50" /><br>
</fieldset>
<fieldset><legend>Entschlüsselt</legend>
<textarea name="textareadecrypted" id="textareadecrypted" cols="80" rows="10"></textarea><br>
MD5SUM der entschlüsselten Nachricht:<br>
<input name="md5sumdecrypted"
id="md5sumdecrypted"
type="text"
size="50"
maxlength="50" /><br>
MD5SUM der originalen Nachricht war:<br>
<input name="md5sumoriginal2"
id="md5sumoriginal2"
type="text"
size="50"
maxlength="50" /><br>
</fieldset>
<input name="searchbutton"
id="searchbutton"
type="button"
value="Fertig!"
onclick="formSubmit(this.form.username.value,
this.form.password.value,
this.form.password2.value);"/>
<input name="resetbutton"
id="resetbutton"
type="button"
value="Reset"
onclick="resetForm();"/><br>
</form>
</html>
so short
Christoph Zurnieden