Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

jscrypto

Hinaser155kMIT1.0.3TypeScript support: included

crypto-js enhancement for modern js environment

crypt, crypto, cipher, hash, MD5, SHA1, SHA256, SHA512, HMAC-SHA1, HMAC-SHA256, AES, DES, Triple-DES, OpenSSL, GCM, GMAC, CCM, CBC-MAC

readme

jscrypto

npm version License: MIT Build

crypto-js enhancement for modern js environments.

  • Works in modern browsers and IE9/10/11.
    *IE9/10 uses weak random generator on cipher encryption with string password. Use it at your own risk.
    *If only using decryption or hash/hmac, weak random generator does not cause any trouble.
  • Loadable with ES6/CommonJS/Typescript/Browser runtimes.
  • Support GCM/GMAC/CCM/CBC-MAC :tada::tada::tada:
  • CLI commands available:
    i.e. npx jscrypto sha1 "message", npx jscrypto aes enc "message" "password", etc.
  • Written in Typescript with rich type declarations.
  • When bundling only SHA256 module, the webpack-ed js file can be less than 6kb.
  • Default parameters for Block cipher (AES/DES/Triple-DES) is tuned to be OpenSSL(1.1.1f) compatible.
    Read further here

Breaking changes for version 0.x.x users

There are several breaking changes between version 0.x and 1.x.
Please see detail in CHANGELOG

Install

npm install jscrypto
# or
yarn add jscrypto

If you only want to use CLI commands, you don't even need to install jscrypto.
Just dispatch npx command like npx jscrypto sha256 "message".
Read further here

Usage

CommonJS Environment (Node.js environment like node CLI, AWS Lambda, etc)

// Load whole library modules.
const JsCrypto = require("jscrypto");
console.log(JsCrypto.SHA256.hash("test").toString());

// or load only necessary modules (Recommended for faster loading and reduced size)
const {SHA256} = require("jscrypto/SHA256");
console.log(SHA256.hash("test").toString());

ES6 Environment (i.e. Creating app/library with webpack/react-scripts or some es6-compatible bundlers)

Be sure to load the module from jscrypto/es6.
This can greatly reduce bundle size by bundlers tree-shaking ability. Don't forget to add /es6 following jscrypto `ecmascript 6 // Load whole library modules. import JsCrypto from "jscrypto/es6"; console.log(JsCrypto.SHA256.hash("test").toString()); ... import {SHA256} from "jscrypto/es6/SHA256"; // Recommended console.log(SHA256.hash("test").toString());


### Typescript Environment
**Be sure to load the module from `jscrypto/es6`.**
```ecmascript 6
// Load whole library modules.
import * as JsCrypto from "jscrypto/es6";
console.log(JsCrypto.SHA256.hash("test").toString());
...
import {SHA256} from "jscrypto/es6/SHA256"; // Recommended
console.log(SHA256.hash("test").toString());

Browser

Copy js files/directories under /dist dir into somewhere browser can access.
Then directly load js file into <script> tag.

<script src="dist/index.js"></script> <!-- All modules are loaded into browser -->
<script type="text/javascript">
  // This will output: "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
  console.log(JsCrypto.SHA256.hash("test").toString());
</script>
<!-- OR -->
<script src="dist/SHA256.js"></script> <!-- Single module loading is lightweight and faster. -->
<script type="text/javascript">
  // This will output: "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
  console.log(JsCrypto.SHA256.hash("test").toString());
</script>

CLI

Command Line Interface to try various crypto modules on terminal.

  Usage: npx jscrypto <hash|hmac|cipher> [command options]

  hash: md5, sha1, sha3, sha224, sha256, sha384, sha512, ripemd160
  hmac: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256, hmac-sha384, hmac-sha512
  cipher: aes, des, des3, rc4


  $ npx jscrypto <hash> message [-msg hex|base64|utf8] [-out hex|base64]

    default:
      -msg: utf8 ... recognize message as utf-8 string
      -out: hex ... output hashed binary as hex string
    example:
      #Output of below 3 examples are the same
      npx jscrypto sha1 test
      npx jscrypto sha1 74657374 -msg hex
      npx jscrypto sha1 dGVzdA== -msg base64


  $ npx jscrypto <hmac> message key [msg hex|base64|utf8] [-key hex|base64|utf8] [-out hex|base64]

    default:
      -msg: utf8 ... recognize message as utf-8 string
      -key: utf8 ... recognize key as utf-8 string
      -out: hex ... output hashed binary as hex string
    example:
      #Output of below 3 examples are the same
      npx jscrypto hmac-sha1 test key
      npx jscrypto hmac-sha1 74657374 6b6579 -msg hex -key hex
      npx jscrypto hmac-sha1 dGVzdA== a2V5 -msg base64 -key base64


  $ npx jscrypto <cipher> message key [-msg hex|base64|utf8] [-key hex|base64|utf8] [-out hex|base64|utf8] [-mode cbc|ecb|ofb|cfb] [-pad pkcs7|iso10126|iso97971|ansix923|nopadding] [-kdf pbkdf2|evpkdf]

    default:
      -msg: utf8 ... recognize message as utf-8 string
      -key: utf8 ... recognize key as utf-8 string
      -out: base64|hex ... base64 on encryption, hex on decryption. Note: utf8 cannot be used on encryption.
      -mode: cbc ... Code block chaining as block cipher mode
      -pad: pkcs7 ... Pkcs7 padding as block padding
      -kdf: pbkdf2 ... PBKDF2 as key derivation function
    example:
      #Encrypt (Output would not be the same because of a random salt, but can be decrypted with the same key)
      npx jscrypto aes enc test password
      npx jscrypto aes enc 74657374 70617373776f7264 -msg hex -key hex
      npx jscrypto aes enc dGVzdA== cGFzc3dvcmQ= -msg base64 -key base64
      #Decrypt
      npx jscrypto aes dec U2FsdGVkX19Kf/wItWMuaTrQYV3OljA3Cr9WPMhC6Tk= password -out utf8
      npx jscrypto aes dec A2pYDd/3oeENsRFGA1Y0Mg== 70617373776f7264 -key hex -out utf8
      npx jscrypto aes dec A2pYDd/3oeENsRFGA1Y0Mg== cGFzc3dvcmQ= -key base64 -out utf8

OpenSSL compatibility

Encryption

  encryptedData = JsCrypto.AES.encrypt("message", "secret phrase").toString();

is equivalent in OpenSSL (1.1.1f) to

  echo -n "message" | openssl enc -e -aes-256-cbc -pass pass:"secret phrase" -base64 -pbkdf2
  # Note: Because of a random salt, everytime it produces different base64 string.
  # But it is OK for decryption.

Decryption

Encrypted data can be decrypted by

  JsCrypto.AES.decrypt(encryptedData, "secret phrase").toString(JsCrypto.Utf8); // "message"

or in OpenSSL

  echo "U2FsdGVkX1..." | openssl enc -d -aes-256-cbc -pass pass:"secret phrase" -base64 -pbkdf2
  # U2FsdGVkX1... is the output from either JsCrypto/OpenSSL encryption code/command.

FAQ

Failed to import jscrypto in Typescript environment.

In most cases, your tsconfig.json is configured not to load npm module from node_modules folder.
Check your tsconfig.js to be:

{
  "compilerOptions": {
    "moduleResolution": "Node"
  }
}

API

jscrypto supports crypto modules as well as cryptojs.

Hash MD5, SHA1, SHA3, SHA224, SHA256, SHA384, SHA512, RIPEMD160,
Message/Key Hash HMAC-MD5, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, HMAC-SHA512, GMAC, CBC-MAC
Block Cipher AES, DES, Triple-DES

Basic structure

Word Word32Array, Word64Array
Encoder Base64, Hex, Latin1, Utf8, Utf16

Misc

Stream Cipher Rabbits, RC4, RC4Drop
Key Derive Function OpenSSLKDF, EvpKDF, PBKDF2
Block Cipher mode CBC, CFB, CTR, ECB, OFB, GCM, CCM
Block Padding AnsiX923, ISO10126, ISO97971, NoPadding, Pkcs7, Zero
Formatter OpenSSLFormatter

changelog

Changelog

1.0.3 - 2022-01-12

Fixed

  • Fixed an issue where AES-CCM got wrong MAC while payload padding required

1.0.2 - 2021-07-08

Fixed

  • Fixed an issue where invalid Hex string could be parsed without error.
    For example, invalid Hex string 1g was recognized as 0x01.

1.0.1 - 2021-06-20

Fixed

  • Fixed an issue where building jscrypto with webpack shows warning messages like below:
    Critical dependency: the request of a dependency is an expression

1.0.0 - 2021-04-22

Added

Changed

Small breaking change

  • Pass initializing vector as Word32Array to constructor of BlockCipherMode instead of just a 32bit number array.
    *This may enable developers to use non-32bit-aligned iv value to block cipher mode in future release.
    *This change may not be breaking lib compatibility unless developers directly instantiate BlockCipherMode or
    creating original BlockCipherMode extending old BlockCipherMode class.

    // BEFORE
    const gcm = new GCM({cipher: AES, iv: [0x11223344]});
    
    // AFTER
    const gcm = new GCM({cipher: AES, iv: new Word32Array([0x11223344], 4)});

Breaking change

  • Changed GMAC hash function name from GCM.hash() to GCM.mac().
  • Calculating authTag in GCM now requires developer to manually call authTag function.
    Encryption/Decryption and MAC Generation are now calculated independently.

    //////////////////////
    // AES-GCM
    //////////////////////
    // BEFORE
    const encrypted = AES.encrypt(msg, key, { iv, mode: GCM, padding: NoPadding, authData });
    encrypted.authTag !== undefined; // This returns true. authTag is automatically calculated on encryption.
    
    // AFTER
    const encrypted = AES.encrypt(msg, key, { iv, mode: GCM, padding: NoPadding, authData });
    encrypted.authTag === undefined; // This returns true. authTag must be manually calculated as below.
    const authTag = GCM.mac(AES, key, iv, authData, encrypted.cipherText);

0.2.0 - 2021-04-07

Added

  • Added GCM block cipher mode. (Galois Counter Mode)
  • Added GMAC (Galois Message Authentication Code)

0.1.0 - 2021-03-30

Added

  • Added CLI executable
  • Added HmacSHA1 (jscrypto/HmacSHA1, jscrypto/es6/HmacSHA1)

0.0.2 - 2021-03-28

Changed

  • Removed typescript source file from npm package to reduce package size.
  • Word32Array can be initialized/cloned by new Word32Array(anotherWord32Array).

Fixed

  • Added missing kdf modules(jscrypto/EvpKDF, jscrypto/PBKDF2, jscrypto/OpenSSLKDF).

0.0.1 - 2021-03-23

Fixed

  • Fixed an issue where encoder/kdf modules have the different loading path.

    <!-- BEFORE THIS FIX -->
    <!-- Load from index.js -->
    <script src="dist/index.js"></script>
    var word = JsCrypto.Hex.parse("00112233");
    <!-- Load from individual modules -->
    <script src="dist/encoder/Hex.js"></script>
    var word = JsCrypto.encode.Hex.parse("00112233");
    
    <!-- AFTER THIS FIX -->
    <script src="dist/Hex.js"></script>
    var word = JsCrypto.Hex.parse("00112233");
  • Fixed an issue where loading multiple modules in browser only preserves the last module.
    <script src="dist/AES.js"></script>
    <script src="dist/DES.js"></script>
    // OK
    var word1 = JsCrypto.DES.encrypt("message", "key");
    // ERROR
    var word2 = JsCrypto.AES.encrypt("message", "key");

0.0.0 - 2021-03-21

Initial release.