Advertisement
k98kurz

Sha1StreamCipher.js

Sep 13th, 2019 (edited)
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // for use in future crypto/ctf challenge; probably hilariously insecure, but that's kinda the point
  2. // usage example: var ssc = new Sha1StreamCipher('key_text');
  3. // ssc.encrypt('super secret message').then((ct) => {console.log(ct); ssc.decrypt(ct).then((pt) => console.log(pt))});
  4.  
  5. function Sha1StreamCipher (key) {
  6.     // main stuff
  7.     async function getKeyStream (l) {
  8.         var keyBytes = [], hash;
  9.  
  10.         // get first 20 bytes
  11.         hash = await crypto.subtle.digest('SHA-1', key);
  12.         keyBytes = keyBytes.slice.call(new Uint8Array(hash));
  13.  
  14.         // get more until we have enough
  15.         while (keyBytes.length < l) {
  16.             hash = await crypto.subtle.digest('SHA-1', hash);
  17.             keyBytes = keyBytes.concat(keyBytes.slice.call(new Uint8Array(hash)));
  18.         }
  19.  
  20.         return keyBytes;
  21.     }
  22.  
  23.     this.encrypt = async function (plaintext) {
  24.         var keyBytes, ciphertext;
  25.         plaintext = typeof plaintext == 'string' ? toUint8(plaintext) : plaintext;
  26.         keyBytes = await getKeyStream(plaintext.length);
  27.         ciphertext = new Uint8Array(plaintext.length);
  28.  
  29.         for (var i=0, il=plaintext.length; i<il; ++i) {
  30.             ciphertext[i] = plaintext[i] ^ keyBytes[i];
  31.         }
  32.  
  33.         return toHex(ciphertext);
  34.     };
  35.  
  36.     this.decrypt = async function (ciphertext) {
  37.         var keyBytes, plaintext;
  38.         ciphertext = isHex(ciphertext) ? fromHex(ciphertext) : typeof ciphertext == 'string' ? toUint8(ciphertext) : ciphertext;
  39.         keyBytes = await getKeyStream(ciphertext.length);
  40.         plaintext = new Uint8Array(ciphertext.length);
  41.  
  42.         for (var i=0, il=ciphertext.length; i<il; ++i) {
  43.             plaintext[i] = ciphertext[i] ^ keyBytes[i];
  44.         }
  45.  
  46.         return toText(plaintext);
  47.     };
  48.  
  49.     this.getKeyBytes = async function (length) {
  50.         return await getKeyStream(length | 0);
  51.     };
  52.  
  53.     // other guff
  54.     function toUint8 (text) {
  55.         var arr = new Uint8Array(text.length);
  56.         for (var i=0, il=text.length; i<il; ++i) {
  57.             arr[i] = text.charCodeAt(i);
  58.         }
  59.         return arr;
  60.     }
  61.  
  62.     function toText (arr) {
  63.         var text = '';
  64.         for (var i=0, il=arr.length; i<il; ++i) {
  65.             text += String.fromCharCode(arr[i]);
  66.         }
  67.         return text;
  68.     }
  69.  
  70.     function fromHex (input) {
  71.         input = input.length % 2 ? '0' + input : input;
  72.         var output = new Uint8Array(input.length / 2);
  73.         for (var i=0, l=input.length; i<l; i+=2) {
  74.             output[i / 2] = parseInt(input[i] + input[i+1], 16);
  75.         }
  76.         return output;
  77.     }
  78.  
  79.     function toHex (arr) {
  80.         arr = arr instanceof Uint8Array ? arr : toUint8(arr);
  81.         var text = '', char = '';
  82.         for (var i=0, il=arr.length; i<il; ++i) {
  83.             char = arr[i].toString(16);
  84.             text += char.length == 2 ? char : '0' + char;
  85.         }
  86.         return text;
  87.     }
  88.  
  89.     function isHex (str) {
  90.         return (/^[a-fA-F0-9]+$/).test(str);
  91.     }
  92.  
  93.     // also do this
  94.     key = toUint8(key);
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement