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.
<script type="text/javascript" src="OpenCrypto.min.js"></script>
or
import OpenCrypto from 'opencrypto'
// Initialize new OpenCrypto instance
const crypt = new OpenCrypto()
// Asymmetric Encryption (RSA)
// Generate RSA key pair
/*
* bits: 1024 or 2048 or 4096 | default: 2048
* usage:
* for OAEP = ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']
* for PSS = ['sign', 'verify']
* default: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']
* alg: 'SHA1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
* paddingScheme: 'RSA-OAEP' or 'RSA-PSS' | default: 'RSA-OAEP'
* extractable: true or false | default: true
*/
crypt.getRSAKeyPair(bits, usage, alg, paddingScheme, extractable).then(function (keyPair) {
console.log(keyPair.publicKey)
console.log(keyPair.privateKey)
})
// Generate EC key pair
/*
* curve: P-256 or P-384 or P-521 | default: P-256
* usage: default: ['deriveKey', 'deriveBits']
* type: 'ECDH' or 'ECDSA' | default: 'ECDH'
* extractable: true or false | default: true
*/
crypt.getECKeyPair(curve, usage, type, extractable).then(function (keyPair) {
console.log(keyPair.privateKey)
console.log(keyPair.publicKey)
})
// Convert CryptoKey of type private to PEM
/*
* privateKey: CryptoKey | default: undefined
*/
crypt.cryptoPrivateToPem(privateKey).then(function (privatePem) {
console.log(privatePem)
})
// Convert PEM private key to CryptoKey
/*
* pem: PEM RSA Private Key (String) | default: undefined
* isSignature: true of false | default: false
* hash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
*/
crypt.pemPrivateToCrypto(pem, isSignature, hash).then(function (cryptoPrivate) {
console.log(cryptoPrivate)
})
// Convert CryptoKey of type public to PEM
/*
* publicKey: CryptoKey | default: undefined
*/
crypt.cryptoPublicToPem(publicKey).then(function (publicPem) {
console.log(publicPem)
})
// Convert PEM public key to CryptoKey
/*
* pem: PEM RSA Public Key (String) | default: undefined
* isSignature: true or false | default: false
* hash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
*/
crypt.pemPublicToCrypto(pem, isSignature, hash).then(function (cryptoPublic) {
console.log(cryptoPublic)
})
// Encrypt CryptoKey of type private into PEM Encrypted Private Key
/*
* privateKey: CryptoKey | default: undefined
* passphrase: String | default: undefined
* iterations: Integer | default: 64000
* hash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
* cipher: 'AES-CBC' or 'AES-GCM' or 'AES-CFB' | default: 'AES-CBC'
* keyLength: default: 256
*/
crypt.encryptPrivateKey(privateKey, passphrase, iterations, hash, cipher, keyLength).then(function (encryptedPrivateKey) {
// This PEM Encrypted Private Key is fully compatiable with OpenSSL
console.log(encryptedPrivateKey)
})
// Decrypt PEM Encrypted Private Key
/*
* encryptedPrivateKey: PEM PKCS #8 | default: undefined
* passphrase: String | default: undefined
* options:
* for OAEP: { name: 'RSA-OAEP', hash: { name: 'SHA-512' } }
* for PSS: { name: 'RSA-PSS', hash: { name: 'SHA-512' } }
* for ECDH: { name: 'ECDH', namedCurve: 'P-256' }
* for ECDSA: { name: 'ECDSA', namedCurve: 'P-256' }
* default: { name: 'RSA-OAEP', hash: { name: 'SHA-512' } }
* usage:
* for OAEP: ['decrypt', 'unwrapKey']
* for PSS: ['sign']
* for ECDH: ['deriveKey', 'deriveBits']
* for ECDSA: ['sign']
* default: ['decrypt', 'unwrapKey']
*/
crypt.decryptPrivateKey(encryptedPrivateKey, passphrase, options, usage).then(function (decryptedPrivateKey) {
console.log(decryptedPrivateKey)
})
// Encrypt data using public key
/*
* publicKey: CryptoKey | default: undefined
* data: ArrayBuffer | default: undefined
*/
crypt.rsaEncrypt(publicKey, data).then(function (encryptedDataAsymmetric) {
console.log(encryptedDataAsymmetric)
})
// Decrypt data using private key
/*
* privateKey: CryptoKey | default: undefined
* encryptedData: base64 String | default: undefined
*/
crypt.rsaDecrypt(privateKey, encryptedData).then(function (decryptedDataAsymmetric) {
console.log(decryptedDataAsymmetric)
})
// Encrypt shared key
/*
* publicKey: CryptoKey | default: undefined
* sharedKey: CryptoKey | default: undefined
* publicKeyHash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
*/
crypt.encryptKey(publicKey, sharedKey, publicKeyHash).then(function (encryptedSharedKey) {
console.log(encryptedSharedKey)
})
// Decrypt shared key
/*
* privateKey: CryptoKey | default: undefined
* encryptedSharedKey: CryptoKey | default: undefined
* cipher: AES-GCM or 'AES-CBC' or 'AES-CFB' | default: 'AES-GCM'
* keyLength: default: 256
* privateKeyLength: 1024 or 2048 or 4096 default: 2048
* privateKeyHash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
*/
crypt.decryptKey(privateKey, encryptedSharedKey, cipher, keyLength, privateKeyLength, privateKeyHash).then(function (decryptedSharedKey) {
console.log(decryptedSharedKey)
})
// Sign data
/*
* privateKey: CryptoKey | default: undefined
* data: ArrayBuffer | default: undefined
*/
crypt.sign(privateKey, data).then(function (signature) {
console.log(signature)
})
// Verify signature
/*
* publicKey: CryptoKey | default: undefined
* signature: base64 String | default: undefined
* data: ArrayBuffer | default: undefined
*/
crypt.verify(publicKey, signature, data).then(function (isValid) {
console.log(isValid)
})
// Symmetric Encryption (AES)
// Generate new symmetric key
/*
* bits: 128 or 256 | default: 256
* usage: default: ['encrypt', 'decrypt', 'wrapKey', 'unwrapKey']
* extractable: true or false | default: true
* cipherMode: 'AES-GCM' or 'AES-CBC' or 'AES-CFB' | default: 'AES-GCM'
*/
crypt.getSharedKey(bits, usage, extractable, cipherMode).then(function (sharedKey) {
console.log(sharedKey)
})
// Encrypt data using shared key
/*
* sharedKey: CryptoKey | default: undefined
* data: ArrayBuffer | default: undefined
*/
crypt.encrypt(sharedKey, data).then(function (encryptedData) {
console.log(encryptedData)
})
// Decrypt data using shared key
/*
* sharedKey: CryptoKey | default: undefined
* encryptedData: base64 String | default: undefined
*/
crypt.decrypt(sharedKey, encryptedData).then(function (decryptedData) {
console.log(decryptedData)
})
// Other Crypto Features
// Derive key from passphrase
/*
* passphrase: String | default: undefined
* salt: String | default: undefined
* iterations: Integer | default: 64000
* hash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
*/
crypt.keyFromPassphrase(passphrase, salt, iterations, hash).then(function (derivedKey) {
console.log(derivedKey)
})
// Get key fingerprint
/*
* key: CryptoKey | default: undefined
* hash: 'SHA-1' or 'SHA-256' or 'SHA-384' or 'SHA-512' | default: 'SHA-512'
*/
crypt.cryptoKeyToFingerprint(key, hash).then(function (fingerprint) {
console.log(fingerprint)
})
// Generate random salt
/*
* size: Integer | default: 16
*/
crypt.getRandomSalt(size).then(function (salt) {
console.log(salt)
})
RFC 5958
RFC 8018
RFC 3394
RFC 5480
RFC 5915
RFC 6090
NIST SP 800-38D
NIST SP 800-38A
Peter Bielak
Andrew Kozlik, Ph.D.
MIT