Advertisement
k98kurz

Sha1StreamCipher-alt.js

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