home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 35 Internet
/
35-Internet.zip
/
srev13g.zip
/
enc_form.rsp
< prev
next >
Wrap
Text File
|
1999-04-23
|
20KB
|
531 lines
<!-- This is an includable file that contains several javascript procedures that
can be used to encrypt selected fields in an HTML form, for transmittal
to an SRE-http web server.
You should include this file in the <HEAD> section of the html
document (that contains the FORM you wish to encrypt)
The main procedures are:
comp_md5(astring)
clear_fields(element1,[element])
do_encrypt(avalue,element)
Usage:
To encrypt form elements, the following steps are needed:
i) include this file in the document containing the FORM to be encrytped
ii) specify in the <FORM>: <input type="hidden" name="NONCE" value=0>
and <input type="hidden" name="verify" value=0>
iii) aks for a shared-secret password, and generate the client's
encryption-key using the comp_md5 procedure
iv) specify hidden elements to store encrypted values of variables, and
use the do_encrypt procedure to encrypt values
v) clear unencrypted values by calling clear_elements prior to SUBMIT.
vi) after submission, the server uses sref_form_decrypt to decrypt
The following describes these steps in greater detail:
i) Include this script in the html document that contains the
FORM you wish to encrypt.
The easiest way to do this is to include the following "ssi" statement
< !-- include enc_Form.rsp -- >
in the <HEAD> of the HTML document that contains the form you want
encrypted (more precisely, of the form containing elements you want
to encrypt).
This assume that ENC_FORM.RSP is in the (possibly host-specific) data
directory, and that the HTML document is ssi-enabled (for example, it has
a .SHT extension).
ii) Include the following elements in your FORM
<input type="hidden" name="NONCE" value=0>
<input type="hidden" name="VERIFY" value=0>
To be safe, this should appear immediately after the <FORM> element.
iii) You must ask the client to enter her "shared-secret" password
for this site, and then compute an MD5 hash from this.
The easiest way to do this is by using the comp_md5
javascript procedure (that is included in this file).
For example, include the following in the body of the HTML document:
Please enter your <b>shared-secret</b> password:
<INPUT type="text" name="your_pwd" value=""
size=20 onChange="comp_md5(this.form.your_pwd) ; return true" >
Notes:
a) the shared-secret is case insensitive (it will be capitalized)
a) comp_md5 will also set the value of the "nonce" and "verify" variables.
b) SRE-http will store the client's "shared secret" as one of her
"secret privileges". For example, if her shared-secret is foobar,
the client's USERS.IN entry might ?ENCRYPT:FOOBAR as a secret
privilege.
iv) For each element in the FORM that you want to encrypt, you should:
a) specify a hidden element which will contain it's encrypted value.
b) set this hidden element's value using the do_encrypt procedure
Do_encrypt expects two values:
the string to be encrypted
the form element (as initialized in setp a) used to store this
encrypted value it (the element name, NOT it's value attribute).
For example:
<input type="hidden" name="secretname_enc" value=0>
Enter your secret name:
<input type="text" name="secretname" size=20
onChange="do_encrypt(this.form.secretname.value,this.form.secretname_enc) ;
return true ">
v) Before submitting the FORM, you MUST clear the to-be-encrypted values.
This can be done by including a call to the clear_fields procedure
as an attribute of the SUBMIT element.
For example:
<input type="submit" value="submit now!"
onClick="clear_fields(this.secretname,this.secretaction,this.myvalue);
return true ">
Note that you can specify an unlimited number of fields to clear; using
either the this.field_name, or the formname.field_name specficiation.
You should specify the element name, and NOT it's value field.
THIS STEP IS CRUCIAL -- if you neglect to do this, the
unencrypted input will be sent!
vi) The addon that processes the request generated when this form is
submitted should be aware of which elements are encrypted. The values
for these parameters can then be decrypted with call to the
SREF_FORM_DECRYPT procedure (that's part of the SRE-http macrospace
library).
For example, extending the preceding example, to decrypt "secretname_enc",
the addon should:
a) get the "nonce" parameters (which was set in step iii)
b) get the appropriate "secret privilege" -- this may (or may not)
be the ?ENCRYPT:pwd "secret privilege".
Note that secret privileges are found in the "PRIVSET" argument
sent to addons -- see MK_ADDON.HTM or SREHTTP.HTM for more
details.
c) Compute the encryption key (the same encryption key is used for
all encrypted elements), and compare it against the "verify"
element. If there is a mismatch, ask the client to resubmit.
c) decrypt this value using:
newvalue=sref_decrypt(encvalue,nonce,apwd)
where:
encvalue is the encrypted response
nonce is from step a
apwd is from step b.
-->
<SCRIPT>
<!--
// some variables
var themd5=0
var ix=0 ; var iy=0 ; var iz=0
var ascii="01234567890123456789012345678901" +
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
"[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
/* md5.jvs 1.0b 27/06/96
*
* Javascript implementation of the RSA Data Security, Inc. MD5
* Message-Digest Algorithm.
*
* Copyright (c) 1996 Henri Torgemane. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* Of course, this soft is provided "as is" without express or implied
* warranty of any kind.
*/
function array(n) {
for(i=0;i<n;i++) this[i]=0;
this.length=n; }
/* Some basic logical functions had to be rewritten because of a bug in
* Javascript.. Just try to compute 0xffffffff >> 4 with it..
* Of course, these functions are slower than the original would be, but
* at least, they work!
*/
function integer(n) { return n%(0xffffffff+1); }
function shr(a,b) {
a=integer(a);
b=integer(b);
if (a-0x80000000>=0) {
a=a%0x80000000;
a>>=b;
a+=0x40000000>>(b-1); }
else
a>>=b;
return a; }
function shl1(a) {
a=a%0x80000000;
if (a&0x40000000==0x40000000)
{ a-=0x40000000;
a*=2;
a+=0x80000000; }
else
a*=2;
return a; }
function shl(a,b) {
a=integer(a);
b=integer(b);
for (var i=0;i<b;i++) a=shl1(a);
return a; }
function and(a,b) {
a=integer(a);
b=integer(b);
var t1=(a-0x80000000);
var t2=(b-0x80000000);
if (t1>=0)
if (t2>=0)
return ((t1&t2)+0x80000000);
else
return (t1&b);
else
if (t2>=0)
return (a&t2);
else
return (a&b); }
function or(a,b) {
a=integer(a);
b=integer(b);
var t1=(a-0x80000000);
var t2=(b-0x80000000);
if (t1>=0)
if (t2>=0)
return ((t1|t2)+0x80000000);
else
return ((t1|b)+0x80000000);
else
if (t2>=0)
return ((a|t2)+0x80000000);
else
return (a|b); }
function xor(a,b) {
a=integer(a);
b=integer(b);
var t1=(a-0x80000000);
var t2=(b-0x80000000);
if (t1>=0)
if (t2>=0)
return (t1^t2);
else
return ((t1^b)+0x80000000);
else
if (t2>=0)
return ((a^t2)+0x80000000);
else
return (a^b); }
function not(a) {
a=integer(a);
return (0xffffffff-a); }
/* Here begin the real algorithm */
var state = new array(4);
var count = new array(2);
count[0] = 0;
count[1] = 0;
var buffer = new array(64);
var transformBuffer = new array(16);
var digestBits = new array(16);
var S11 = 7; var S12 = 12; var S13 = 17;
var S14 = 22; var S21 = 5; var S22 = 9;
var S23 = 14; var S24 = 20; var S31 = 4;
var S32 = 11; var S33 = 16; var S34 = 23;
var S41 = 6; var S42 = 10; var S43 = 15;
var S44 = 21;
function F(x,y,z) {return or(and(x,y),and(not(x),z)); }
function G(x,y,z) {return or(and(x,z),and(y,not(z))); }
function H(x,y,z) {return xor(xor(x,y),z); }
function I(x,y,z) {return xor(y ,or(x , not(z))); }
function rotateLeft(a,n) {return or(shl(a, n),(shr(a,(32 - n)))); }
function FF(a,b,c,d,x,s,ac) {
a = a+F(b, c, d) + x + ac;
a = rotateLeft(a, s);
a = a+b;
return a; }
function GG(a,b,c,d,x,s,ac) {
a = a+G(b, c, d) +x + ac;
a = rotateLeft(a, s);
a = a+b;
return a; }
function HH(a,b,c,d,x,s,ac) {
a = a+H(b, c, d) + x + ac;
a = rotateLeft(a, s);
a = a+b;
return a; }
function II(a,b,c,d,x,s,ac) {
a = a+I(b, c, d) + x + ac;
a = rotateLeft(a, s);
a = a+b;
return a; }
function transform(buf,offset) {
var a=0, b=0, c=0, d=0;
var x = transformBuffer;
a = state[0];
b = state[1];
c = state[2];
d = state[3];
for (i = 0; i < 16; i++) {
x[i] = and(buf[i*4+offset],0xff);
for (j = 1; j < 4; j++) {
x[i]+=shl(and(buf[i*4+j+offset] ,0xff), j * 8); } }
/* Round 1 */
a = FF ( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
d = FF ( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
c = FF ( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
b = FF ( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
a = FF ( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
d = FF ( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
c = FF ( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
b = FF ( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
a = FF ( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
d = FF ( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
c = FF ( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
b = FF ( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
a = FF ( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
d = FF ( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
c = FF ( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
b = FF ( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
a = GG ( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
d = GG ( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
c = GG ( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
b = GG ( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
a = GG ( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
d = GG ( d, a, b, c, x[10], S22, 0x2441453); /* 22 */
c = GG ( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
b = GG ( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
a = GG ( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
d = GG ( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
c = GG ( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
b = GG ( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
a = GG ( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
d = GG ( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
c = GG ( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
b = GG ( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
a = HH ( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
d = HH ( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
c = HH ( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
b = HH ( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
a = HH ( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
d = HH ( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
c = HH ( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
b = HH ( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
a = HH ( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
d = HH ( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
c = HH ( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
b = HH ( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
a = HH ( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
d = HH ( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
c = HH ( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
b = HH ( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
a = II ( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
d = II ( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
c = II ( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
b = II ( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
a = II ( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
d = II ( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
c = II ( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
b = II ( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
a = II ( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
d = II ( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
c = II ( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
b = II ( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
a = II ( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
d = II ( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
c = II ( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
b = II ( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] +=a;
state[1] +=b;
state[2] +=c;
state[3] +=d; }
function init() {
count[0]=count[1] = 0;
state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
for (i = 0; i < digestBits.length; i++)
digestBits[i] = 0; }
function update(b) {
var index,i;
index = and(shr(count[0],3) , 0x3f);
if (count[0]<0xffffffff-7)
count[0] += 8;
else {
count[1]++;
count[0]-=0xffffffff+1;
count[0]+=8; }
buffer[index] = and(b,0xff);
if (index >= 63) {
transform(buffer, 0);
} }
function finish() {
var bits = new array(8);
var padding;
var i=0, index=0, padLen=0;
for (i = 0; i < 4; i++) {
bits[i] = and(shr(count[0],(i * 8)), 0xff); }
for (i = 0; i < 4; i++) {
bits[i+4]=and(shr(count[1],(i * 8)), 0xff); }
index = and(shr(count[0], 3) ,0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
padding = new array(64);
padding[0] = 0x80;
for (i=0;i<padLen;i++)
update(padding[i]);
for (i=0;i<8;i++)
update(bits[i]);
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
digestBits[i*4+j] = and(shr(state[i], (j * 8)) , 0xff); }
} }
/* End of the MD5 algorithm */
function hexa(n) {
var hexa_h = "0123456789abcdef"; var hexa_c=""; var hexa_m=n;
for (hexa_i=0;hexa_i<8;hexa_i++) {
hexa_c=hexa_h.charAt(Math.abs(hexa_m)%16)+hexa_c;
hexa_m=Math.floor(hexa_m/16); }
return hexa_c; }
function hextodec(ahex,llen) {
var smm=0
var xlist='0123456789ABCDEF'
var afact=1
for (ir=llen-1; ir>=0;ir--) {
var acc=ahex.charAt(ir)
iind=xlist.indexOf(acc)
smm=smm+(iind*afact)
afact=afact*16
}
return smm
}
function MD5(your_pwd) {
var l,s,k,ka,kb,kc,kd;
init();
for (k=0;k<your_pwd.length;k++) {
l=your_pwd.charAt(k);
update(ascii.lastIndexOf(l)); }
finish();
ka=kb=kc=kd=0;
for (i=0;i<4;i++) ka+=shl(digestBits[15-i], (i*8));
for (i=4;i<8;i++) kb+=shl(digestBits[15-i], ((i-4)*8));
for (i=8;i<12;i++) kc+=shl(digestBits[15-i], ((i-8)*8));
for (i=12;i<16;i++) kd+=shl(digestBits[15-i], ((i-12)*8));
s=hexa(kd)+hexa(kc)+hexa(kb)+hexa(ka);
return s; }
// Given a string, set a nonce, and determine the md5 of nonce+string
function comp_md5(avalue) {
bvalue=avalue.value
avalue.value='Computing encryption-key '
timea=new Date()
nonce=Date.parse(timea)
avalue.form.nonce.value=nonce
aggx=nonce + bvalue
zbb=aggx.toUpperCase()
themd5=MD5(zbb)
themd5=themd5.toUpperCase()
avalue.form.verify.value=themd5.substring(0,16)
avalue.value='Encryption-key has been computed '
return true
}
/* --------------------------- */
// Random number generator
function random3()
{
ix=(171*ix)%30269
iy=(172*iy)%30307
iz=(170*iz)%30323
var arandom=(ix/30269.) + (iy/30307.) + (iz/30323)
return Math.floor((arandom % 1.0)* 255)
}
/* ---------- js 1.0 charcodeat - */
function cvt_it(aa)
{goo=escape(aa)
lk=goo.length
if (lk==1)
{isa=ascii.lastIndexOf(goo); }
else
{ t1=goo.substring(1,lk)
isa=hextodec(t1,lk-1)
}
//alert(aa+' '+isa)
return isa
}
/* ********************************** */
// Encrypt a form element, using md5 hash -- store in saveto.value
function do_encrypt(stuff,saveto) {
// document.askmd5.status.value='Computing MD5 encryption key'
// document.askmd5.status.value='MD5 key computed! '
// themd5=comp_md5(pwd,1)
if (themd5=="0")
{ alert(' You must first enter your shared-secret password! ')
return 0
}
// Note: each element uses the same sequence of random numbers. This
// does mean repetition of the sequence if more then one variable
// is encrypted (which slightly weakens encryption)
var cx=themd5.substring(29,32)
ix=hextodec(cx,3)
var cy=themd5.substring(26,29)
iy=hextodec(cy,3)
var cz=themd5.substring(24,26)
iz=hextodec(cz,2)
//alert('rnds: '+ix+' '+iy+' '+iz)
damessage='' // use a random # stream to decrypt
for (ii=0; ii<stuff.length ;ii++) {
iavar=cvt_it(stuff.charAt(ii))
// iavar=stuff.charCodeAt(ii)
rr=random3()
//alert(ii+' '+rr)
rr2=iavar^rr
newch=hexa(rr2)
newch2=newch.substring(6,8)
damessage=damessage + newch2
}
saveto.value=damessage
return true
}
// clear elements of the form. Typically used to clear an element
// after it's been encrypted. The notion is to save the
// encrypted value to a hidden element, and then clear this "raw, unencrypted
// value" just prior to submitting the form.
function clear_fields() {
for (k=0 ; k<arguments.length ; k++)
{arguments[k].value=0}
return true
}
// -->
</SCRIPT>