WebCrypto

How-to

Usage

Encrypt / Decrypt

Signature / Verify

Digest

AES / RSA / DES

MD5 / SHA

RSA / DSA

Base64?!

Node.js

crypto module

import crypto from 'crypto';

const PLAIN_TEXT = 'StanneyPassword'

const hashed = crypto.createHash('sha256')
  .update(PLAIN_TEXT)
  .digest('hex');

Node.js

import crypto from 'crypto';

const PRIVATE_KEY = '...';
const PUBLIC_KEY = '...'

const PLAIN_TEXT = 'Stanney Works';

const encryptedData = crypto.publicEncrypt(PUBLIC_KEY, Buffer.from(PLAIN_TEXT));

console.log('Encrypted', encryptedData.toString('hex'));

const descryptedText = crypto.privateDecrypt({
  key: PRIVATE_KEY,
  passphrase: 'PASSWORD',
}, encryptedData);

console.log('Decrypted', descryptedText.toString());

crypto.generateKeyPair('rsa', {
  modulusLength: 4096,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem',
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
    cipher: 'aes-256-cbc',
    passphrase: 'PASSWORD',
  },
}, (err, publicKey, privateKey) => {
  console.log(publicKey);
});

WebCrypto

(async () => {
  const ORIGIN_TEXT = 'Stanney\'s Password';
  
  const encoder = new TextEncoder();
  
  const hashed = await crypto.subtle.digest({
    name: 'SHA-512',
  }, encoder.encode(ORIGIN_TEXT));
  
  const hashedHex = Array.prototype.map.call(
    new Uint8Array(hashed),
    byte => byte.toString(16).padStart(2, '0')
  ).join('');

  console.log({
    hashed,
    hashedHex,
  });
})();
(async () => {
  const PLAIN_TEXT = 'Stanney\'s Secret';
  
  const keys = await crypto.subtle.generateKey({
    name: 'RSA-OAEP',
    modulusLength: 4096,
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
    hash: {
      name: 'SHA-512',
    }
  }, false, [
    'encrypt',
    'decrypt',
  ]);
  
  const encoder = new TextEncoder();
  const decoder = new TextDecoder('utf-8');
  
  const encrypted = await crypto.subtle.encrypt({
    name: 'RSA-OAEP',
  }, keys.publicKey, encoder.encode(PLAIN_TEXT));
  
  const decrypted = await crypto.subtle.decrypt({
    name: 'RSA-OAEP',
  }, keys.privateKey, encrypted);
  
  console.log({
    encrypted,
    decrypted,
    decryptedText: decoder.decode(decrypted),
  });
})();
(async () => {
  const PLAIN_TEXT = 'Stanney\'s Document';
  
  const keys = await crypto.subtle.generateKey({
    name: 'RSASSA-PKCS1-v1_5',
    modulusLength: 4096,
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
    hash: {
      name: 'SHA-512',
    }
  }, false, [
    'sign',
    'verify',
  ]);
  
  const encoder = new TextEncoder();
  
  const signature = await crypto.subtle.sign({
    name: 'RSASSA-PKCS1-v1_5',
  }, keys.privateKey, encoder.encode(PLAIN_TEXT));
  
  const signatureHex = Array.prototype.map.call(
    new Uint8Array(signature),
    byte => byte.toString(16).padStart(2, '0')
  ).join('');
  
  const isValid = await crypto.subtle.verify({
    name: 'RSASSA-PKCS1-v1_5',
  }, keys.publicKey, signature, encoder.encode(PLAIN_TEXT));
  
  console.log({
    signatureHex,
    isValid,
  });
})();

Key Store

Indexed DB

Indexed DB

(async () => {
  const keys = await crypto.subtle.generateKey({
    name: 'RSA-OAEP',
    modulusLength: 4096,
    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
    hash: {
      name: 'SHA-512',
    }
  }, false, [
    'encrypt',
    'decrypt',
  ]);
  
  const connection = indexedDB.open('KeyStore', 1);
  
  connection.onupgradeneeded = () => {
    try {
      const db = connection.result;
    
      db.createObjectStore('EncryptKeyPair', {
        keyPath: 'id',
      });
    } catch (ex) {
      console.log('Object already created');
    }
  };
  
  connection.onsuccess = () => {
    const db = connection.result;
    
    const transaction = db.transaction('EncryptKeyPair', 'readwrite');
    const putStore = transaction.objectStore('EncryptKeyPair');
    
    const putRequest = putStore.put({ id: 1, keys });
    
    putRequest.onsuccess = () => {
      const getRequest = putStore.get(1);

      getRequest.onsuccess = (data) => {
        console.log('Stored Keys', getRequest.result.keys);
      };
    }
    
    transaction.oncomplete = () => db.close();
  };
})();

Text

WebCrypto

By Chia Yu Pai

WebCrypto

  • 360