JavaScript DHTML/Security/RC4 Encryption

Материал из Web эксперт
Перейти к: навигация, поиск

RC4 Encryption in JavaScript

   <source lang="html4strict">

<html>

 <head>
   
   <title>RC4 Encryption</title>
 </head>
 <body>
   <script language="JavaScript">

var dg="" function makeArray(n) {

for (var i=1; i<=n; i++) {
 this[i]=0
}
return this

} function rc4(key, text) {

var i, x, y, t, x2;
status("rc4")
s=makeArray(0);
for (i=0; i<256; i++) {
 s[i]=i
}
y=0
for (x=0; x<256; x++) {
 y=(key.charCodeAt(x % key.length) + s[x] + y) % 256
 t=s[x]; s[x]=s[y]; s[y]=t
}
x=0;  y=0;
var z=""
for (x=0; x<text.length; x++) {
 x2=x % 256
 y=( s[x2] + y) % 256
 t=s[x2]; s[x2]=s[y]; s[y]=t
 z+= String.fromCharCode((text.charCodeAt(x) ^ s[(s[x2] + s[y]) % 256]))
}
return z

} function badd(a,b) { // binary add

var r=""
var c=0
while(a || b) {
 c=chop(a)+chop(b)+c
 a=a.slice(0,-1); b=b.slice(0,-1)
 if(c & 1) {
  r="1"+r
 } else {
  r="0"+r
 }
 c>>=1
}
if(c) {r="1"+r}
return r

} function chop(a) {

if(a.length) {
 return parseInt(a.charAt(a.length-1))
} else {
 return 0
}

} function bsub(a,b) { // binary subtract

var r=""
var c=0
while(a) {
 c=chop(a)-chop(b)-c
 a=a.slice(0,-1); b=b.slice(0,-1)
 if(c==0) {
  r="0"+r
 }
 if(c == 1) {
  r="1"+r
  c=0
 }
 if(c == -1) {
  r="1"+r
  c=1
 }
 if(c==-2) {
  r="0"+r
  c=1
 }
}
if(b || c) {return ""}
return bnorm(r)

} function bnorm(r) { // trim off leading 0s

var i=r.indexOf("1")
if(i == -1) {
 return "0"
} else {
 return r.substr(i)
}

} function bmul(a,b) { // binary multiply

var r=""; var p=""
while(a) {
 if(chop(a) == "1") {
  r=badd(r,b+p)
 }
 a=a.slice(0,-1)
 p+="0"
}
return r;

} function bmod(a,m) { // binary modulo

return bdiv(a,m).mod

} function bdiv(a,m) { // binary divide & modulo

// this.q = quotient this.mod=remainder
var lm=m.length, al=a.length
var p="",d
this.q=""
for(n=0; n<al; n++) {
 p=p+a.charAt(n);
 if(p.length<lm || (d=bsub(p,m)) == "") {
  this.q+="0"
 } else {
  if(this.q.charAt(0)=="0") {
   this.q="1"
  } else {
   this.q+="1"
  }
  p=d
 }
}
this.mod=bnorm(p)
return this

} function bmodexp(x,y,m) { // binary modular exponentiation

var r="1"
status("bmodexp "+x+" "+y+" "+m)
while(y) {
 if(chop(y) == 1) {
  r=bmod(bmul(r,x),m)
 }
 y=y.slice(0,y.length-1)
 x=bmod(bmul(x,x),m)
}
return bnorm(r)

} function modexp(x,y,m) { // modular exponentiation

// convert packed bits (text) into strings of 0s and 1s
return b2t(bmodexp(t2b(x),t2b(y),t2b(m)))

} function i2b(i) { // convert integer to binary

var r=""
while(i) {
 if(i & 1) { r="1"+r} else {r="0"+r}
 i>>=1;
}
return r? r:"0"

} function t2b(s) {

var r=""
if(s=="") {return "0"}
while(s.length) {
 var i=s.charCodeAt(0)
 s=s.substr(1)
 for(n=0; n<8; n++) {
  r=((i & 1)? "1":"0") + r
  i>>=1;
 }
}
return bnorm(r)

} function b2t(b) {

var r=""; var v=0; var m=1
while(b.length) {
 v|=chop(b)*m
 b=b.slice(0,-1)
 m<<=1
 if(m==256 || b=="") {
  r+=String.fromCharCode(v)
  v=0; m=1
 }
}
return r

} b64s="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"" function textToBase64(t) {

status("t 2 b64")
var r=""; var m=0; var a=0; var tl=t.length-1; var c
for(n=0; n<=tl; n++) {
 c=t.charCodeAt(n)
 r+=b64s.charAt((c << m | a) & 63)
 a = c >> (6-m)
 m+=2
 if(m==6 || n==tl) {
  r+=b64s.charAt(a)
  if((n%45)==44) {r+="\n"}
  m=0
  a=0
 }
}
return r

} function base64ToText(t) {

status("b64 2 t")
var r=""; var m=0; var a=0; var c
for(n=0; n<t.length; n++) {
 c=b64s.indexOf(t.charAt(n))
 if(c >= 0) {
  if(m) {
   r+=String.fromCharCode((c << (8-m))&255 | a)
  }
  a = c >> m
  m+=2
  if(m==8) { m=0 }
 }
}
return r

} function rand(n) { return Math.floor(Math.random() * n) } function rstring(s,l) {

var r=""
var sl=s.length
while(l-->0) {
 r+=s.charAt(rand(sl))
}
//status("rstring "+r)
return r

} function key2(k) {

var l=k.length
var kl=l
var r=""
while(l--) {
 r+=k.charAt((l*3)%kl)
}
return r

} function rsaEncrypt(keylen,key,mod,text) {

// I read that rc4 with keys larger than 256 bytes doesn"t significantly
// increase the level of rc4 encryption because it"s sbuffer is 256 bytes
// makes sense to me, but what do i know...
status("encrypt")
if(text.length >= keylen) {
 var sessionkey=rc4(rstring(text,keylen),rstring(text,keylen))
 // session key must be less than mod, so mod it
 sessionkey=b2t(bmod(t2b(sessionkey),t2b(mod)))
 alert("sessionkey="+sessionkey)
 // return the rsa encoded key and the encrypted text
 // i"m double encrypting because it would seem to me to
 // lessen known-plaintext attacks, but what do i know
 return modexp(sessionkey,key,mod) +
  rc4(key2(sessionkey),rc4(sessionkey,text))
} else {
 // don"t need a session key
 return modexp(text,key,mod)
}

} function rsaDecrypt(keylen,key,mod,text) {

status("decrypt")
if(text.length <= keylen) {
 return modexp(text,key,mod)
} else {
 // sessionkey is first keylen bytes
 var sessionkey=text.substr(0,keylen)
 text=text.substr(keylen)
 // un-rsa the session key
 sessionkey=modexp(sessionkey,key,mod)
 alert("sessionkey="+sessionkey)
 // double decrypt the text
 return rc4(sessionkey,rc4(key2(sessionkey,text),text))
}

} function trim2(d) { return d.substr(0,d.lastIndexOf("1")+1) } function bgcd(u,v) { // return greatest common divisor

// algorythm from http://algo.inria.fr/banderier/Seminar/Vallee/index.html
var d, t
while(1) {
 d=bsub(v,u)
 //alert(v+" - "+u+" = "+d)
 if(d=="0") {return u}
 if(d) {
  if(d.substr(-1)=="0") {
   v=d.substr(0,d.lastIndexOf("1")+1) // v=(v-u)/2^val2(v-u)
  } else v=d
 } else {
  t=v; v=u; u=t // swap u and v
 }
}

} function isPrime(p) {

var n,p1,p12,t
p1=bsub(p,"1")
t=p1.length-p1.lastIndexOf("1")
p12=trim2(p1)
for(n=0; n<2; n+=mrtest(p,p1,p12,t)) {
 if(n<0) return 0
}
return 1

} function mrtest(p,p1,p12,t) {

// Miller-Rabin test from forum.swathmore.edu/dr.math/
var n,a,u
 a="1"+rstring("01",Math.floor(p.length/2)) // random a
 //alert("mrtest "+p+", "+p1+", "+a+"-"+p12)
 u=bmodexp(a,p12,p)
 if(u=="1") {return 1}
 for(n=0;n<t;n++) {
  u=bmod(bmul(u,u),p)
  //dg+=u+" "
  if(u=="1") return -100
  if(u==p1) return 1
 }
 return -100

} pfactors="11100011001110101111000110001101"

// this number is 3*5*7*11*13*17*19*23*29*31*37

function prime(bits) {

// return a prime number of bits length
var p="1"+rstring("001",bits-2)+"1"
while( ! isPrime(p)) {
 p=badd(p,"10"); // add 2
}
alert("p is "+p)
return p

} function genkey(bits) {

q=prime(bits)
do {
 p=q
 q=prime(bits)
} while(bgcd(p,q)!="1")
p1q1=bmul(bsub(p,"1"),bsub(q,"1"))
// now we need a d, e,  and an n so that:
//  p1q1*n-1=de  -> bmod(bsub(bmul(d,e),"1"),p1q1)="0"
// or more specifically an n so that d & p1q1 are rel prime and factor e
n="1"+rstring("001",Math.floor(bits/3)+2)
alert("n is "+n)
factorMe=badd(bmul(p1q1,n),"1")
alert("factor is "+factorMe)
//e=bgcd(factorMe,p1q1)
//alert("bgcd="+e)
e="1"
// is this always 1?
//r=bdiv(factorMe,e)
//alert("r="+r.q+" "+r.mod)
//if(r.mod != "0") {alert("Mod Error!")}
//factorMe=r.q
d=bgcd(factorMe,"11100011001110101111000110001101")
alert("d="+d)
if(d == "1" && e == "1") {alert("Factoring failed "+factorMe+" p="+p+" q="+q)}
e=bmul(e,d)
r=bdiv(factorMe,d)
d=r.q
if(r.mod != "0") {alert("Mod Error 2!")}
this.mod=b2t(bmul(p,q))
this.pub=b2t(e)
this.priv=b2t(d)

} function status(a) { }//alert(a)}

   </script>
             <script language="JavaScript">
               
             </script>

RC4 Encryption (input text for both field):

   <form method="POST" name="rc4">
             Key:
             <input type="text" size="60" name="key" value="">
             Text:
             <textarea name="text" rows="6" cols="70"></textarea>

<input type="button" name="B1" value="Encrypt" onclick="rc4encrypt()"> <input type="button" name="B2" value="Decrypt" onclick="rc4decrypt()">

   </form>
 </body>

</html>

      </source>