0251 / 590 837 15

HTML verschlüsseln: Quelltext schützen mit JavaScript

Jeder, der selbst entwicklet kennt das Problem: Fremde klauen den Code an dem man stundenlang gearbeitet hat und geben ihn als den eigenen aus. Dem kann durch Codierung des Quelltextes abgeholfen werden.

Techniken

Bei der Verschlüsselung von Quelltext gibt es mehrere Techniken die von sehr einfach (und ebenso einfach zu entschlüsseln) bis sehr kompliziert reichen. Im folgenden sollen einige vorgestellt werden, wobei zwischen Verschlüsselung des JavaScript-Quelltextes und verschlüsselung des gesamten (HTML, CSS, JavaScript ...) Quellcodes unterschieden werden sollte. Je nach dem ist eine Variante eher für das eine bzw. das andere geeignet. Allgemein genommen funktionieren aber alle Techniken nach dem gleichen Prinzip: Der Code ist verschlüsselt in der Datei gespeichert, wird beim Aufruf der Seite entschlüsselt und in das Dokument geschrieben. Sieht man sich den Quelltext an, wird nur der orginal (verschlüsselte) Quelltext und nicht der (entschlüsselte) Code der angezeigt wird.

Einschränkungen

Da bei jeder Codierung bzw. Decodierung letztlich ein für den Browser darstellbares Ergebnis entstehen muss, ist es im Grunde unmöglich den Code so zu verschlüsseln, dass ihn niemand knacken kann. Vielmehr ist es für relativ erfahrene Programmierer meist ein leichtes den Code zu enttarnen. Dennoch sollte bedacht werden, dass die meisten Code-Diebe schon allein beim Anblick von scheinbar wirren Schriftfetzen schnell die Lust am kopieren verlieren werden.

Die Leere-Zeilen-Variante

Die einfachste aller Varianten ist das bloße Einfügen von Leerzeilen vor dem gesamten Quelltext. Schaut ein Code-Dieb nach dem Quelltext wird er mit einer leeren Seite überrascht. Die meisten übersehen dabei die Scrollbars, die den weiter unten gelegenen Text verbergen.

Verhinderungs-Variante

Diese Möglichkeit ist ebenfalls eine sehr einfache Angelegenheit. Das Ganze basiert darauf, dass dem Dieb der Zugriff auf den Quelltext verwehrt wird. Dazu müssen folgende Dinge getan werden:

  • rechte Maustaste ausschalten (Kontexmenü)
  • Menüleiste ausblenden bzw. nicht für die eigentliche Datei verwendbar machen
  • STRG-Taste verhindern (Short-Cuts)
Die rechte Maustaste wird mit folgendem Script blockiert:

<script language="JavaScript">
<!--
function DoFalse(){alert('Nicht möglich!'); return(false)}

if(document.layers)
{
 document.captureEvents(Event.MOUSEDOWN);
 document.onmousedown=DoFalse();
}
//-->
</script>
...
<body onMouseDown="return DoFalse();"> 

Die Menüleiste wird am besten dadurch ausgeschaltet bzw. unschädlich gemacht, dass entweder ein neues Fenster geöffnet wird, welches diese nicht enthält (window.open(... , ..., 'menubar=false')), oder dass die Seite nur innerhalb eines Frames angezeigt werden kann:

if(self == top){window.location.href = 'frameset.htm';}; 

Das Ausschalten der STRG-Taste kann mit folgendem Script hervorgerufen werden:

<script language="JavaScript">
<!--
function DoFalse(e)
{
 if((window.event && window.event.ctrlKey == true) || 
    (e && e.modifiers == 2))
 {
  alert('Nicht möglich!'); return false;
 }
}

if(document.layers)
{
 document.captureEvents(Event.KEYPRESS);
 document.onKeyPress = DoFalse;
}
//-->
</script>
...
<body onMouseDown="return DoFalse();" onKeyPress="return DoFalse();"> 



Bitte beachten Sie, dass es zwar recht einfach umzusetzen und sicher auch recht hilfreich ist, diese Variante zu verwenden - in Programmiererkreisen gilt diese Methode jedoch als sehr unbeliebt (von den meisten wird sie sogar gehasst, dass sie den Zugriff auf andere wichtige Funktionen versperrt). Sie sollten diese Variante also mit Bedacht einsetzen.

Escape-Variante

Ein etwas bessere Variante ist das Verschlüsseln der Sonderzeichen mit Hilfe der escape-Methode. Diese ersetzt sämtliche Sonderzeichen (>, :, ", &, ...) eines Strings durch deren Unicode-Zeichenfolgen. Z.B. wird aus &= %&!§%<> so %26%3D%20%25%26%21%A7%25%3C%3E.

Der Quelltext wird zuvor mit dieser Methode verschlüsselt und in einer Variablen gespeichert. Codieren:

alterText = 'abcdefg';
neuerText = escape(alterText); 



Die Ausgabe wird wie folgt (ohne weitere darzustellende Elemente) in die Seite eingebunden. Mit der unescape-Methode wird der Code wieder entschlüsselt. Die Variable versch enthält im Beispiel den codierten Quelltext:

<script language="JavaScript">
<!--
var versch = ' .... quelltext ... ';
document.open();
document.write(unescape(versch));
document.close();
//-->
</script> 

Zeichenliste-Variante

Eine weitere Variante ist die Verschlüsselung aller Zeichen mit Hilfe einer Zeichenliste. Dazu wird zuvor ein String angelegt, der alle Zeichen in einer (beliebigen) Reihenfolge enthält. Ausserdem müssen die Sonderzeichen (!, §, $, %, &, /, (, ), =, ?, ...) und Steuerzeichen (n, t, r, b, f, ...) enthalten sein Das Prinzip ist dann wie folgt: Der zu codierende bzw. decodierende String wird von vorn bis hinten durchlaufen. Dabei wird zu jedem Zeichen die Stelle gesucht, an der dieses in der Zeichenliste enthalten ist. Durch eine eingegebene oder vorher gespeicherte Zahl wird die Stelle erhöht und statt dem orginal Zeichen das Zeichen ausgegeben, dass der neuen (erhöhten) Stelle in der Zeichenliste entspricht. Zusätzlich kommt noch das Codieren durch die escape-Variante hinzu. Diese ist unbedingt notwendig, da sonst Fehler auftreten können. Codieren:

var liste = '1234567890ß´`qwertzuiopü+#äölkjhgfds'ayxcvbnm'+
            ',.>-<*~_:;|µ!"§$%&/()=?QWERTZUIOPÜÄÖLKJHGFDS'+
            'AYXCVBNM@ntrbf';
var x = 122;
function codieren(s)
{
 res = '';
 for(i=0; i<s.length; i++)
 {
 a = s.substr(i,1);
 b = liste.indexOf(a)+x;
 while(b > liste.length){b = b-liste.length;}
 res += liste.substr(b,1);
 }
 return(escape(res));



Zur Ausgabe wird statt dem Erhöhen des Stellenzahl, diese einfach subtrahiert. Der zuvor codierte Quelltext wird wiederum in einer Variablen eingebunden. Ausserdem wird eine Geheimzahl abgefragt. Diese bestimmte den Wert, um wieviele Stellen ein Zeichen subtrahiert werden soll:

<script language="JavaScript">
<!--
var versch = ' .... quelltext ... ';
var liste = '1234567890ß´`qwertzuiopü+#äölkjhgfds'ayx'+
            'cvbnm,.>-<*~_:;|µ!"§$%&/()=?QWERTZUIOPÜ'+
            'ÄÖLKJHGFDSAYXCVBNM@ntrbf';

function decodieren(s)
{
 s = unescape(s);
 x = prompt('Bitte Geheimzahl eingeben!'); // = 122
 res = '';
 for(i=0; i<s.length; i++)
 {
  a = s.substr(i,1);
  b = liste.indexOf(a)-x;
  while(b < 0){b = b+liste.length;}
  res += liste.substr(b,1);
 }
 return(res);
}

document.open();
document.write(decodieren(versch));
document.close();
//-->
</script> 



Neben dem vertauschen der Buchstaben durch einfaches Addieren bzw. Subtrahieren gibt es eine Reihe weiterer Möglichkeiten. Fast alle mathematischen oder bitweisen Operatoren können hier zum Einsatz kommen.

Base64-Variante

Eines der bekanntesten Verfahren zum Ver- und Entschlüsseln ist Base64. Es wird unter anderem z.B. bei HTTP-Passwörtern verwendet. Das Grundprinzip ist ähnlich der oben beschriebenen Variante mit Zeichenliste: Mit Hilfe Zeichensatzes werden die Buchstaben so verdreht dass ein neuer String entsteht. Der Vorteil dabei ist, dass die Resultierenden Strings meist kürzer als die orginal (unverschlüsselten) sind. Wie folgt wird codiert:

var base64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcd'+
              'efghijklmnopqrstuvwxyz0123456789+/';

function encode(decStr)
{
 var bits;
 var dual;
 var i = 0;
 var encOut = '';
 while(decStr.length >= i + 3)
 {
 bits = (decStr.charCodeAt(i++) & 0xff) <<16 |
 (decStr.charCodeAt(i++) & 0xff) <<8 |
 decStr.charCodeAt(i++) & 0xff;
 encOut += base64s.charAt((bits & 0x00fc0000) >>18) +
 base64s.charAt((bits & 0x0003f000) >>12) +
 base64s.charAt((bits & 0x00000fc0) >> 6) +
 base64s.charAt((bits & 0x0000003f));
 }
 if(decStr.length -i > 0 && decStr.length -i < 3)
 {
 dual = Boolean(decStr.length -i -1);
 bits = ((decStr.charCodeAt(i++) & 0xff) <<16) |
 (dual ? (decStr.charCodeAt(i) & 0xff) <<8 : 0);
 encOut += base64s.charAt((bits & 0x00fc0000) >>18) +
 base64s.charAt((bits & 0x0003f000) >>12) +
 (dual ? base64s.charAt((bits & 0x00000fc0) >>6) : '=') +
 '=';
}
return(encOut);
}



Der codierte String sollte zusätzlich noch mit escape() behandelt werden. Das decodieren wird wie folgt vorgenommen:

var base64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabc'+
              'defghijklmnopqrstuvwxyz0123456789+/';

function decode(encStr)
{
 var bits;
 var decOut = '';
 var i = 0;
 for(; i<encStr.length; i += 4)
 {
 bits = (base64s.indexOf(encStr.charAt(i)) & 0xff) <<18 |
 (base64s.indexOf(encStr.charAt(i +1)) & 0xff) <<12 |
 (base64s.indexOf(encStr.charAt(i +2)) & 0xff) << 6 |
 base64s.indexOf(encStr.charAt(i +3)) & 0xff;
 decOut += String.fromCharCode((bits & 0xff0000) >>16, (bits & 0xff00) >>8, bits & 0xff);
 }
 if(encStr.charCodeAt(i -2) == 61)
 {
 return(decOut.substring(0, decOut.length -2));
 }
 else if(encStr.charCodeAt(i -1) == 61)
 {
 return(decOut.substring(0, decOut.length -1));
 }
 else {return(decOut)};
}

Software-Varianten

Eine sehr sichere Variante der Verschlüsselung ist die Zuhilfenahme von Software die speziell dafür ausgelegt ist. Im besonderen bieten sich dazu zwei Produkte an:

Microsoft Windows Script Encoder

Der Windows Script Encoder von Microsoft ist ein einfaches Befehlszeilen Tool das sämtliche Script-Passagen innerhalb eines Dokuments codiert. Vor dem zu codierenden Text wird eine Markierung (//**Start Encode**) angebracht, dann wird der Encoder mit der Befehlszeile
SCRENC [Parameter] Eingabedatei Ausgabedatei
auf MS-DOS-Ebene aufgerufen. Der Encoder verschlüsselt dann automatisch den JavaScript Quelltext und ändert die Sprachdefinition (aus language="JScript" wird language="JScript.Encode"). Der (Microsoft Internet Explorer) Browser weiß dann, dass er zum ausführen des Quelltextes diesen erst decodieren muss.

Netscape Signing Tool

Beim Signing Tool von Netscape handelt es sich um eine Art Compilierung des Quelltextes. Der Quelltext wird dadurch erstens kleiner und zweitens (worauf wir hinaus wollen) unlesbar. Zur Verwendung dessen wird der Text in eine externe Datei ausgelagert, die mit dem Tool compiliert und in das JAR-Format gebracht wird. Innerhalb des Dokumentes wird die Datei mit Hilfe des archive-Attributes des script-Elements eingebunden. Der (Netscape Navigator) Browser kann diese Dateien dann lesen und ganz normal ausführen.

Nachteil bei diesen Software-Varianten ist, dass jeweils nur der hauseigene Browser der jeweiligen Software-Firma die Technik beherrschen.

Möglichkeiten zur Verbesserung

Um die Verschlüsselung bzw. Sicherheit vor Diebstählen noch weiter zu verbessern bieten sich eine Reihe von weiteren Möglichkeiten an.

  • Verschlüsselung der Entschlüsslungfunktion
    eval(unescape( ... mit escape verschlüsselte Funktion zum Entschlüsseln des Codes ... ))
  • Verwendung anderer (und komplizierterer) mathematischer Operatoren und komplexere Umsetzung der Zeichen
  • Verknüpfung mehrerer (verschiedener) Codierungsmethoden miteinander (Verschlüsseltes verschlüsseln, Quelltext verhindern, ...)