npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencrypto

v1.5.5

Published

OpenCrypto is a lightweight JavaScript library built on top of WebCryptography API

Readme

OpenCrypto

npm Build Status npm License Become a Patron

OpenCrypto is a lightweight, high performance, standard-compliant JavaScript library built on top of Web Cryptography API. This library makes it easier to implement cryptography in a browser with less code. It can convert and encode ASN.1, PEM and CryptoKey. OpenCrypto is created and maintained by SafeBash.

Import into your web application

<script type="text/javascript" src="OpenCrypto.min.js"></script>

// Initialize new OpenCrypto instance
const crypt = new OpenCrypto()

or

import OpenCrypto from 'opencrypto'

// Initialize new OpenCrypto instance
const crypt = new OpenCrypto()

Conversion of CryptoKey, PEM and Base64

/**
 * Method that converts asymmetric private key from CryptoKey to PEM format
 * @param {CryptoKey} privateKey default: "undefined"
 */
crypt.cryptoPrivateToPem(privateKey).then(privatePem => {
  console.log(privatePem)
})

/**
 * Method that converts asymmetric private key from PEM to CryptoKey format
 * @param {String} pem default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDH: { name: 'ECDH', usages: ['deriveKey', 'deriveBits'], isExtractable: true }
 * -- ECDSA: { name: 'ECDSA', usages: ['sign'], isExtractable: true }
 * -- RSA-OAEP: { name: 'RSA-OAEP', hash: { name: 'SHA-512' }, usages: ['decrypt', 'unwrapKey'], isExtractable: true }
 * -- RSA-PSS: { name: 'RSA-PSS', hash: { name: 'SHA-512' }, usages: ['sign'], isExtractable: true }
 */
crypt.pemPrivateToCrypto(pem, options).then(cryptoPrivate => {
  console.log(cryptoPrivate)
})

/**
 * Method that converts asymmetric public key from CryptoKey to PEM format
 * @param {CryptoKey} publicKey default: "undefined"
 */
crypt.cryptoPublicToPem(publicKey).then(publicPem => {
  console.log(publicPem)
})

/**
 * Method that converts asymmetric public key from PEM to CryptoKey format
 * @param {String} publicKey default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDH: { name: 'ECDH', usages: [], isExtractable: true }
 * -- ECDSA: { name: 'ECDSA', usages: ['verify'], isExtractable: true }
 * -- RSA-OAEP: { name: 'RSA-OAEP', hash: { name: 'SHA-512' }, usages: ['encrypt', 'wrapKey'], isExtractable: true }
 * -- RSA-PSS: { name: 'RSA-PSS', hash: { name: 'SHA-512' }, usages: ['verify'], isExtractable: true }
 */
crypt.pemPublicToCrypto(pem, options).then(cryptoPublic => {
  console.log(cryptoPublic)
})

/**
 * Method that converts CryptoKey to base64
 * @param {CryptoKey} key default: "undefined"
 * @param {String} type default: "secret: 'raw'; private: 'pkcs8'; public: 'spki'"
 */
crypt.cryptoToBase64(key, type).then(base64Key => {
  console.log(base64Key)
})

/**
 * Method that converts base64 encoded key to CryptoKey
 * @param {String} key default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- AES-GCM: { name: 'AES-GCM', length: 256, usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- AES-CBC: { name: 'AES-CBC', length: 256, usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- ECDH: { name: 'ECDH', namedCurve: 'P-256', usages: ['deriveKey', 'deriveBits'], isExtractable: true }
 * -- ECDSA: { name: 'ECDSA', namedCurve: 'P-256', usages: ['sign', 'verify'], isExtractable: true }
 * -- RSA-OAEP: { name: 'RSA-OAEP', hash: { name: 'SHA-512' }, usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- RSA-PSS: { name: 'RSA-PSS', hash: { name: 'SHA-512' }, usages: ['sign', 'verify'], isExtractable: true }
 */
crypt.base64ToCrypto(key, options).then(cryptoKey => {
  console.log(cryptoKey)
})

Asymmetric Encryption

/**
 * Method that generates asymmetric RSA-OAEP key pair
 * @param {Integer} modulusLength default: "2048"
 * @param {String} hash default: "SHA-512"
 * @param {String} paddingScheme default: "RSA-OAEP"
 * @param {Array} usages default: "['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']"
 * @param {Boolean} isExtractable default: "true"
 */
crypt.getRSAKeyPair(modulusLength, hash, paddingScheme, usages, isExtractable).then(keyPair => {
  console.log(keyPair.publicKey)
  console.log(keyPair.privateKey)
})

/**
 * Method that encrypts data using asymmetric encryption
 * @param {CryptoKey} publicKey default: "undefined"
 * @param {ArrayBuffer} data default: "undefined"
 */
crypt.rsaEncrypt(publicKey, data).then(encryptedData => {
  console.log(encryptedData)
})

/**
 * Method that decrypts data using asymmetric encryption
 * @param {CryptoKey} privateKey default: "undefined"
 * @param {String} encryptedData default: "undefined"
 */
crypt.rsaDecrypt(privateKey, encryptedData).then(decryptedData => {
  console.log(decryptedData)
})

/**
 * Method that generates asymmetric Elliptic Curve Diffie-Hellman key pair
 * @param {String} curve default: "P-256"
 * @param {String} type default: "ECDH"
 * @param {Array} usages default: "['deriveKey', 'deriveBits']"
 * @param {Boolean} isExtractable default: "true"
 */
crypt.getECKeyPair(curve, type, usages, isExtractable).then(keyPair => {
  console.log(keyPair.privateKey)
  console.log(keyPair.publicKey)
})

/**
 * Method that retrieves public key from private key
 * @param {CryptoKey} privateKey default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDH: { usages: ['deriveKey', 'deriveBits'], isExtractable: true }
 * -- ECDSA: { usages: ['sign', 'verify'], isExtractable: true }
 * -- RSA-OAEP: { usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- RSA-PSS: { usages: ['sign', 'verify'], isExtractable: true }
 */
crypt.getPublicKey(privateKey, options).then(publicKey => {
  console.log(publicKey)
})

/**
 * Method that encrypts asymmetric private key using passphrase to enable storage in unsecure environment
 * @param {CryptoKey} privateKey default: "undefined"
 * @param {String} passphrase default: "undefined"
 * @param {Number} iterations default: "64000"
 * @param {String} hash default: "SHA-512"
 * @param {String} cipher default: "AES-GCM"
 * @param {Number} length default: "256"
 */
crypt.encryptPrivateKey(privateKey, passphrase, iterations, hash, cipher, length).then(encryptedPrivateKey => {
  console.log(encryptedPrivateKey)
})

/**
 * Method that decrypts asymmetric private key using passphrase
 * @param {String} encryptedPrivateKey default: "undefined"
 * @param {String} passphrase default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDH: { name: 'ECDH', namedCurve: 'P-256', usages: ['deriveKey', 'deriveBits'], isExtractable: true }
 * -- ECDSA: { name: 'ECDSA', namedCurve: 'P-256', usages: ['sign'], isExtractable: true }
 * -- RSA-OAEP: { name: 'RSA-OAEP', hash: 'SHA-512', usages: ['decrypt', 'unwrapKey'], isExtractable: true }
 * -- RSA-PSS: { name: 'RSA-PSS', hash: 'SHA-512', usages: ['sign'], isExtractable: true }
 */
crypt.decryptPrivateKey(encryptedPrivateKey, passphrase, options).then(decryptedPrivateKey => {
  console.log(decryptedPrivateKey)
})

/**
 * Method that performs ECDH key agreement
 * @param {CryptoKey} privateKey default: "undefined"
 * @param {CryptoKey} publicKey default: "undefined"
 * @param {Object} options default: "{ bitLength: 256, hkdfHash: 'SHA-512', hkdfSalt: "new UInt8Array()", hkdfInfo: "new UInt8Array()", cipher: 'AES-GCM', length: 256, usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }"
 */
crypt.keyAgreement(privateKey, publicKey, options).then(sharedKey => {
  console.log(sharedKey)
})

Symmetric Encryption

/**
 * Method that generates symmetric/shared key for AES encryption
 * @param {Integer} length default: "256"
 * @param {Object} options default: "{ cipher: 'AES-GCM', usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }"
 */
crypt.getSharedKey(length, options).then(sharedKey => {
  console.log(sharedKey)
})

/**
 * Method that encrypts keys
 * @param {CryptoKey} wrappingKey default: "undefined"
 * @param {CryptoKey} key default: "undefined"
 */
crypt.encryptKey(wrappingKey, key).then(encryptedKey => {
  console.log(encryptedKey)
})

/**
 * Method that decrypts keys
 * @param {CryptoKey} unwrappingKey default: "undefined"
 * @param {String} encryptedKey default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- AES-GCM: { type: 'raw', name: 'AES-GCM', length: 256, usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- AES-CBC: { type: 'raw', name: 'AES-CBC', length: 256, usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- ECDH: { type: "'pkcs8' or 'spki'", name: 'ECDH', namedCurve: 'P-256', usages: ['deriveKey', 'deriveBits'], isExtractable: true }
 * -- ECDSA: { type: "'pkcs8' or 'spki'", name: 'ECDSA', namedCurve: 'P-256', usages: ['sign', 'verify'], isExtractable: true }
 * -- RSA-OAEP: { type: "'pkcs8' or 'spki'", name: 'RSA-OAEP', hash: 'SHA-512', usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }
 * -- RSA-PSS: { type: "'pkcs8' or 'spki'", name: 'RSA-PSS', hash: 'SHA-512', usages: ['sign', 'verify'], isExtractable: true }
 */
crypt.decryptKey(unwrappingKey, encryptedKey, options).then(decryptedKey => {
  console.log(decryptedKey)
})

/**
 * Method that generates key signature using ECDSA or RSA-PSS
 * @param {CryptoKey} privateKey default: "undefined"
 * @param {CryptoKey} key default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDSA: { hash: 'SHA-512' }
 * -- RSA-PSS: { saltLength: 128 }
 */
crypt.signKey(privateKey, key, options).then(keySignature => {
  console.log(keySignature)
})

/**
 * Method that verifies key signature using ECDSA or RSA-PSS
 * @param {CryptoKey} publicKey default: "undefined"
 * @param {CryptoKey} key default: "undefined"
 * @param {String} signature default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDSA: { hash: 'SHA-512' }
 * -- RSA-PSS: { saltLength: 128 }
 */
crypt.verifyKey(publicKey, key, signature, options).then(isValid => {
  console.log(isValid)
})

/**
 * Method that generates signature of data using ECDSA or RSA-PSS
 * @param {CryptoKey} privateKey default: "undefined"
 * @param {ArrayBuffer} data default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDSA: { hash: 'SHA-512' }
 * -- RSA-PSS: { saltLength: 128 }
 */
crypt.sign(privateKey, data, options).then(signature => {
  console.log(signature)
})

/**
 * Method that verifies data signature using ECDSA or RSA-PSS
 * @param {CryptoKey} publicKey default: "undefined"
 * @param {ArrayBuffer} data default: "undefined"
 * @param {String} signature default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- ECDSA: { hash: 'SHA-512' }
 * -- RSA-PSS: { saltLength: 128 }
 */
crypt.verify(publicKey, data, signature, options).then(isValid => {
  console.log(isValid)
})

/**
 * Method that encrypts data using symmetric/shared key
 * @param {CryptoKey} sharedKey default: "undefined"
 * @param {ArrayBuffer} data default: "undefined"
 */
crypt.encrypt(sharedKey, data).then(encryptedData => {
  console.log(encryptedData)
})

/**
 * Method that decrypts data using symmetric/shared key
 * @param {CryptoKey} sharedKey default: "undefined"
 * @param {String} encryptedData default: "undefined"
 * @param {Object} options default: depends on algorithm below
 * -- AES-GCM: { cipher: 'AES-GCM' }
 * -- AES-CBC: { cipher: 'AES-CBC' }
 */
crypt.decrypt(sharedKey, encryptedData, options).then(decryptedData => {
  console.log(decryptedData)
})

Passphrase derivation

/**
 * Method that derives shared key from passphrase
 * @param {String} passphrase default: "undefined"
 * @param {ArrayBuffer} salt default: "undefined"
 * @param {Number} iterations default: "64000"
 * @param {Object} options default: "{ hash: 'SHA-512', length: 256, cipher: 'AES-GCM', usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }"
 */
crypt.derivePassphraseKey(passphrase, salt, iterations, options).then(derivedKey => {
  console.log(derivedKey)
})

/**
 * Method that derives hash from passphrase
 * @param {String} passphrase default: "undefined"
 * @param {ArrayBuffer} salt default: "undefined" salt
 * @param {Number} iterations default: "64000"
 * @param {Object} options default: "{ hash: 'SHA-512', length: 256, cipher: 'AES-GCM', usages: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey'], isExtractable: true }"
 */
crypt.hashPassphrase(passphrase, salt, iterations, options).then(hashedPassphrase => {
  console.log(derivedHash)
})

/**
 * Method that generates fingerprint of EC, RSA and AES keys
 * @param {CryptoKey} key default: "undefined"
 * @param {Object} options default: { hash: 'SHA-512', isBuffer: false }
 */
crypt.getFingerprint(key, options).then(fingerprint => {
  console.log(fingerprint)
})

Other

/**
 * Method that generates random bytes using cryptographically secure PRNG
 * @param {Number} size default: "16"
 */
crypt.getRandomBytes(size).then(data => {
  console.log(data)
})

Standards Compliance

RFC 5280 RFC 6090 RFC 5208 RFC 5480 RFC 5915 RFC 8018 RFC 3394 NIST SP 800-38A NIST SP 800-38B NIST SP 800-38D NIST SP 800-56A NIST SP 800-56C NIST FIPS 180-4

Contributors

Peter Bielak Andrew Kozlik, Ph.D.

License

MIT