{
  "_args": [
    [
      {
        "raw": "node-forge@https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
        "scope": null,
        "escapedName": "node-forge",
        "name": "node-forge",
        "rawSpec": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
        "spec": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
        "type": "remote"
      },
      "E:\\MissionXJC\\XJC\\functions\\node_modules\\firebase-admin"
    ]
  ],
  "_from": "node-forge@0.7.1",
  "_id": "node-forge@0.7.1",
  "_inCache": true,
  "_location": "/firebase-admin/node-forge",
  "_phantomChildren": {},
  "_requested": {
    "raw": "node-forge@https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
    "scope": null,
    "escapedName": "node-forge",
    "name": "node-forge",
    "rawSpec": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
    "spec": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
    "type": "remote"
  },
  "_requiredBy": [
    "/firebase-admin",
    "/firebase-admin/google-p12-pem"
  ],
  "_resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
  "_shasum": "9da611ea08982f4b94206b3beb4cc9665f20c300",
  "_shrinkwrap": null,
  "_spec": "node-forge@https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz",
  "_where": "E:\\MissionXJC\\XJC\\functions\\node_modules\\firebase-admin",
  "author": {
    "name": "Digital Bazaar, Inc.",
    "email": "support@digitalbazaar.com",
    "url": "http://digitalbazaar.com/"
  },
  "browser": {
    "buffer": false,
    "crypto": false,
    "process": false
  },
  "bugs": {
    "url": "https://github.com/digitalbazaar/forge/issues",
    "email": "support@digitalbazaar.com"
  },
  "contributors": [
    {
      "name": "Dave Longley",
      "email": "dlongley@digitalbazaar.com"
    },
    {
      "name": "David I. Lehn",
      "email": "dlehn@digitalbazaar.com"
    },
    {
      "name": "Stefan Siegl",
      "email": "stesie@brokenpipe.de"
    },
    {
      "name": "Christoph Dorn",
      "email": "christoph@christophdorn.com"
    }
  ],
  "dependencies": {},
  "description": "JavaScript implementations of network transports, cryptography, ciphers, PKI, message digests, and various utilities.",
  "devDependencies": {
    "browserify": "^13.1.1",
    "commander": "^2.9.0",
    "express": "^4.14.1",
    "istanbul": "^0.4.5",
    "jscs": "^3.0.7",
    "jshint": "^2.9.4",
    "karma": "^1.4.1",
    "karma-browserify": "^5.1.1",
    "karma-chrome-launcher": "^2.0.0",
    "karma-edge-launcher": "^0.2.0",
    "karma-firefox-launcher": "^1.0.0",
    "karma-ie-launcher": "^1.0.0",
    "karma-mocha": "^1.3.0",
    "karma-mocha-reporter": "^2.2.2",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-safari-launcher": "^1.0.0",
    "karma-sauce-launcher": "^1.1.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-tap-reporter": "0.0.6",
    "karma-webpack": "^2.0.2",
    "mocha": "^3.2.0",
    "mocha-lcov-reporter": "^1.2.0",
    "nodejs-websocket": "^1.7.1",
    "opts": "^1.2.2",
    "webpack": "^2.2.0"
  },
  "engines": {
    "node": "*"
  },
  "files": [
    "lib/*.js",
    "flash/swf/*.swf",
    "dist/*.min.js",
    "dist/*.min.js.map"
  ],
  "homepage": "https://github.com/digitalbazaar/forge",
  "jspm": {
    "format": "amd"
  },
  "keywords": [
    "aes",
    "asn",
    "asn.1",
    "cbc",
    "crypto",
    "cryptography",
    "csr",
    "des",
    "gcm",
    "hmac",
    "http",
    "https",
    "md5",
    "network",
    "pkcs",
    "pki",
    "prng",
    "rc2",
    "rsa",
    "sha1",
    "sha256",
    "sha384",
    "sha512",
    "ssh",
    "tls",
    "x.509",
    "x509"
  ],
  "license": "(BSD-3-Clause OR GPL-2.0)",
  "main": "lib/index.js",
  "name": "node-forge",
  "optionalDependencies": {},
  "readme": "# Forge\n\n[![npm package](https://nodei.co/npm/node-forge.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/node-forge/)\n\n[![Build status](https://img.shields.io/travis/digitalbazaar/forge.svg?branch=master)](https://travis-ci.org/digitalbazaar/forge)\n\nA native implementation of [TLS][] (and various other cryptographic tools) in\n[JavaScript][].\n\nIntroduction\n------------\n\nThe Forge software is a fully native implementation of the [TLS][] protocol\nin JavaScript, a set of cryptography utilities, and a set of tools for\ndeveloping Web Apps that utilize many network resources.\n\nPerformance\n------------\n\nForge is fast. Benchmarks against other popular JavaScript cryptography\nlibraries can be found here:\n\n* http://dominictarr.github.io/crypto-bench/\n* http://cryptojs.altervista.org/test/simulate-threading-speed_test.html\n\nDocumentation\n-------------\n\n* [Introduction](#introduction)\n* [Performance](#performance)\n* [Installation](#installation)\n* [Testing](#testing)\n* [Contributing](#contributing)\n\n### API\n\n* [Options](#options)\n\n### Transports\n\n* [TLS](#tls)\n* [HTTP](#http)\n* [SSH](#ssh)\n* [XHR](#xhr)\n* [Sockets](#socket)\n\n### Ciphers\n\n* [CIPHER](#cipher)\n* [AES](#aes)\n* [DES](#des)\n* [RC2](#rc2)\n\n### PKI\n\n* [RSA](#rsa)\n* [RSA-KEM](#rsakem)\n* [X.509](#x509)\n* [PKCS#5](#pkcs5)\n* [PKCS#7](#pkcs7)\n* [PKCS#8](#pkcs8)\n* [PKCS#10](#pkcs10)\n* [PKCS#12](#pkcs12)\n* [ASN.1](#asn)\n\n### Message Digests\n\n* [SHA1](#sha1)\n* [SHA256](#sha256)\n* [SHA384](#sha384)\n* [SHA512](#sha512)\n* [MD5](#md5)\n* [HMAC](#hmac)\n\n### Utilities\n\n* [Prime](#prime)\n* [PRNG](#prng)\n* [Tasks](#task)\n* [Utilities](#util)\n* [Logging](#log)\n* [Debugging](#debug)\n* [Flash Networking Support](#flash)\n\n### Other\n\n* [Security Considerations](#security-considerations)\n* [Library Background](#library-background)\n* [Contact](#contact)\n* [Donations](#donations)\n\n---------------------------------------\n\nInstallation\n------------\n\n**Note**: Please see the [Security Considerations](#security-considerations)\nsection before using packaging systems and pre-built files.\n\nForge uses a [CommonJS][] module structure with a build process for browser\nbundles. The older [0.6.x][] branch with standalone files is available but will\nnot be regularly updated.\n\n### Node.js\n\nIf you want to use forge with [Node.js][], it is available through `npm`:\n\nhttps://npmjs.org/package/node-forge\n\nInstallation:\n\n    npm install node-forge\n\nYou can then use forge as a regular module:\n\n```js\nvar forge = require('node-forge');\n```\n\nThe npm package includes pre-built `forge.min.js`, `forge.all.min.js`, and\n`prime.worker.min.js` using the [UMD][] format.\n\n### Bundle / Bower\n\nEach release is published in a separate repository as pre-built and minimized\nbasic forge bundles using the [UMD][] format.\n\nhttps://github.com/digitalbazaar/forge-dist\n\nThis bundle can be used in many environments. In particular it can be installed\nwith [Bower][]:\n\n    bower install forge\n\n### unpkg\n\n[unpkg][] provides a CDN that can serve files from npm packages directly.\n\nhttps://unpkg.com/node-forge@0.7.0/dist/forge.min.js\n\n### Development Requirements\n\nThe core JavaScript has the following requirements to build and test:\n\n* Building a browser bundle:\n  * Node.js\n  * npm\n* Testing\n  * Node.js\n  * npm\n  * Chrome, Firefox, Safari (optional)\n\nSome special networking features can optionally use a Flash component.  See the\n[Flash README](./flash/README.md) for details.\n\n### Building for a web browser\n\nTo create single file bundles for use with browsers run the following:\n\n    npm install\n    npm run build\n\nThis will create single non-minimized and minimized files that can be\nincluded in the browser:\n\n    dist/forge.js\n    dist/forge.min.js\n\nA bundle that adds some utilities and networking support is also available:\n\n    dist/forge.all.js\n    dist/forge.all.min.js\n\nInclude the file via:\n\n```html\n<script src=\"YOUR_SCRIPT_PATH/forge.js\"></script>\n```\nor\n```html\n<script src=\"YOUR_SCRIPT_PATH/forge.min.js\"></script>\n```\n\nThe above bundles will synchronously create a global 'forge' object.\n\n**Note**: These bundles will not include any WebWorker scripts (eg:\n`dist/prime.worker.js`), so these will need to be accessible from the browser\nif any WebWorkers are used.\n\n### Building a custom browser bundle\n\nThe build process uses [webpack][] and the [config](./webpack.config.js) file\ncan be modified to generate a file or files that only contain the parts of\nforge you need.\n\n[Browserify][] override support is also present in `package.json`.\n\nTesting\n-------\n\nSee the [testing README](./tests/README.md) for full details.\n\n### Prepare to run tests\n\n    npm install\n\n### Running automated tests with Node.js\n\nForge natively runs in a [Node.js][] environment:\n\n    npm test\n\n### Running automated tests with PhantomJS\n\nAutomated testing is done via [Karma][]. By default it will run the tests in a\nheadless manner with PhantomJS.\n\n    npm run test-karma\n\nIs 'mocha' reporter output too verbose? Other reporters are available. Try\n'dots', 'progress', or 'tap'.\n\n    npm run test-karma -- --reporters progress\n\nBy default [webpack][] is used. [Browserify][] can also be used.\n\n    BUNDLER=browserify npm run test-karma\n\n### Running automated tests with one or more browsers\n\nYou can also specify one or more browsers to use.\n\n    npm run test-karma -- --browsers Chrome,Firefox,Safari,PhantomJS\n\nThe reporter option and `BUNDLER` environment variable can also be used.\n\n### Running manual tests in a browser\n\nTesting in a browser uses [webpack][] to combine forge and all tests and then\nloading the result in a browser. A simple web server is provided that will\noutput the HTTP or HTTPS URLs to load. It also will start a simple Flash Policy\nServer. Unit tests and older legacy tests are provided. Custom ports can be\nused by running `node tests/server.js` manually.\n\nTo run the unit tests in a browser a special forge build is required:\n\n    npm run test-build\n\nTo run legacy browser based tests the main forge build is required:\n\n    npm run build\n\nThe tests are run with a custom server that prints out the URLs to use:\n\n    npm run test-server\n\n### Running other tests\n\nThere are some other random tests and benchmarks available in the tests\ndirectory.\n\n### Coverage testing\n\nTo perform coverage testing of the unit tests, run the following. The results\nwill be put in the `coverage/` directory. Note that coverage testing can slow\ndown some tests considerably.\n\n    npm install\n    npm run coverage\n\nContributing\n------------\n\nAny contributions (eg: PRs) that are accepted will be brought under the same\nlicense used by the rest of the Forge project. This license allows Forge to\nbe used under the terms of either the BSD License or the GNU General Public\nLicense (GPL) Version 2.\n\nSee: [LICENSE](https://github.com/digitalbazaar/forge/blob/cbebca3780658703d925b61b2caffb1d263a6c1d/LICENSE)\n\nIf a contribution contains 3rd party source code with its own license, it\nmay retain it, so long as that license is compatible with the Forge license.\n\nAPI\n---\n\n<a name=\"options\" />\n### Options\n\nIf at any time you wish to disable the use of native code, where available,\nfor particular forge features like its secure random number generator, you\nmay set the ```forge.options.usePureJavaScript``` flag to ```true```. It is\nnot recommended that you set this flag as native code is typically more\nperformant and may have stronger security properties. It may be useful to\nset this flag to test certain features that you plan to run in environments\nthat are different from your testing environment.\n\nTo disable native code when including forge in the browser:\n\n```js\n// run this *after* including the forge script\nforge.options.usePureJavaScript = true;\n```\n\nTo disable native code when using Node.js:\n\n```js\nvar forge = require('node-forge');\nforge.options.usePureJavaScript = true;\n```\n\nTransports\n----------\n\n<a name=\"tls\" />\n### TLS\n\nProvides a native javascript client and server-side [TLS][] implementation.\n\n__Examples__\n\n```js\n// create TLS client\nvar client = forge.tls.createConnection({\n  server: false,\n  caStore: /* Array of PEM-formatted certs or a CA store object */,\n  sessionCache: {},\n  // supported cipher suites in order of preference\n  cipherSuites: [\n    forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,\n    forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],\n  virtualHost: 'example.com',\n  verify: function(connection, verified, depth, certs) {\n    if(depth === 0) {\n      var cn = certs[0].subject.getField('CN').value;\n      if(cn !== 'example.com') {\n        verified = {\n          alert: forge.tls.Alert.Description.bad_certificate,\n          message: 'Certificate common name does not match hostname.'\n        };\n      }\n    }\n    return verified;\n  },\n  connected: function(connection) {\n    console.log('connected');\n    // send message to server\n    connection.prepare(forge.util.encodeUtf8('Hi server!'));\n    /* NOTE: experimental, start heartbeat retransmission timer\n    myHeartbeatTimer = setInterval(function() {\n      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));\n    }, 5*60*1000);*/\n  },\n  /* provide a client-side cert if you want\n  getCertificate: function(connection, hint) {\n    return myClientCertificate;\n  },\n  /* the private key for the client-side cert if provided */\n  getPrivateKey: function(connection, cert) {\n    return myClientPrivateKey;\n  },\n  tlsDataReady: function(connection) {\n    // TLS data (encrypted) is ready to be sent to the server\n    sendToServerSomehow(connection.tlsData.getBytes());\n    // if you were communicating with the server below, you'd do:\n    // server.process(connection.tlsData.getBytes());\n  },\n  dataReady: function(connection) {\n    // clear data from the server is ready\n    console.log('the server sent: ' +\n      forge.util.decodeUtf8(connection.data.getBytes()));\n    // close connection\n    connection.close();\n  },\n  /* NOTE: experimental\n  heartbeatReceived: function(connection, payload) {\n    // restart retransmission timer, look at payload\n    clearInterval(myHeartbeatTimer);\n    myHeartbeatTimer = setInterval(function() {\n      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));\n    }, 5*60*1000);\n    payload.getBytes();\n  },*/\n  closed: function(connection) {\n    console.log('disconnected');\n  },\n  error: function(connection, error) {\n    console.log('uh oh', error);\n  }\n});\n\n// start the handshake process\nclient.handshake();\n\n// when encrypted TLS data is received from the server, process it\nclient.process(encryptedBytesFromServer);\n\n// create TLS server\nvar server = forge.tls.createConnection({\n  server: true,\n  caStore: /* Array of PEM-formatted certs or a CA store object */,\n  sessionCache: {},\n  // supported cipher suites in order of preference\n  cipherSuites: [\n    forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,\n    forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],\n  // require a client-side certificate if you want\n  verifyClient: true,\n  verify: function(connection, verified, depth, certs) {\n    if(depth === 0) {\n      var cn = certs[0].subject.getField('CN').value;\n      if(cn !== 'the-client') {\n        verified = {\n          alert: forge.tls.Alert.Description.bad_certificate,\n          message: 'Certificate common name does not match expected client.'\n        };\n      }\n    }\n    return verified;\n  },\n  connected: function(connection) {\n    console.log('connected');\n    // send message to client\n    connection.prepare(forge.util.encodeUtf8('Hi client!'));\n    /* NOTE: experimental, start heartbeat retransmission timer\n    myHeartbeatTimer = setInterval(function() {\n      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));\n    }, 5*60*1000);*/\n  },\n  getCertificate: function(connection, hint) {\n    return myServerCertificate;\n  },\n  getPrivateKey: function(connection, cert) {\n    return myServerPrivateKey;\n  },\n  tlsDataReady: function(connection) {\n    // TLS data (encrypted) is ready to be sent to the client\n    sendToClientSomehow(connection.tlsData.getBytes());\n    // if you were communicating with the client above you'd do:\n    // client.process(connection.tlsData.getBytes());\n  },\n  dataReady: function(connection) {\n    // clear data from the client is ready\n    console.log('the client sent: ' +\n      forge.util.decodeUtf8(connection.data.getBytes()));\n    // close connection\n    connection.close();\n  },\n  /* NOTE: experimental\n  heartbeatReceived: function(connection, payload) {\n    // restart retransmission timer, look at payload\n    clearInterval(myHeartbeatTimer);\n    myHeartbeatTimer = setInterval(function() {\n      connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));\n    }, 5*60*1000);\n    payload.getBytes();\n  },*/\n  closed: function(connection) {\n    console.log('disconnected');\n  },\n  error: function(connection, error) {\n    console.log('uh oh', error);\n  }\n});\n\n// when encrypted TLS data is received from the client, process it\nserver.process(encryptedBytesFromClient);\n```\n\nConnect to a TLS server using node's net.Socket:\n\n```js\nvar socket = new net.Socket();\n\nvar client = forge.tls.createConnection({\n  server: false,\n  verify: function(connection, verified, depth, certs) {\n    // skip verification for testing\n    console.log('[tls] server certificate verified');\n    return true;\n  },\n  connected: function(connection) {\n    console.log('[tls] connected');\n    // prepare some data to send (note that the string is interpreted as\n    // 'binary' encoded, which works for HTTP which only uses ASCII, use\n    // forge.util.encodeUtf8(str) otherwise\n    client.prepare('GET / HTTP/1.0\\r\\n\\r\\n');\n  },\n  tlsDataReady: function(connection) {\n    // encrypted data is ready to be sent to the server\n    var data = connection.tlsData.getBytes();\n    socket.write(data, 'binary'); // encoding should be 'binary'\n  },\n  dataReady: function(connection) {\n    // clear data from the server is ready\n    var data = connection.data.getBytes();\n    console.log('[tls] data received from the server: ' + data);\n  },\n  closed: function() {\n    console.log('[tls] disconnected');\n  },\n  error: function(connection, error) {\n    console.log('[tls] error', error);\n  }\n});\n\nsocket.on('connect', function() {\n  console.log('[socket] connected');\n  client.handshake();\n});\nsocket.on('data', function(data) {\n  client.process(data.toString('binary')); // encoding should be 'binary'\n});\nsocket.on('end', function() {\n  console.log('[socket] disconnected');\n});\n\n// connect to google.com\nsocket.connect(443, 'google.com');\n\n// or connect to gmail's imap server (but don't send the HTTP header above)\n//socket.connect(993, 'imap.gmail.com');\n```\n\n<a name=\"http\" />\n### HTTP\n\nProvides a native [JavaScript][] mini-implementation of an http client that\nuses pooled sockets.\n\n__Examples__\n\n```js\n// create an HTTP GET request\nvar request = forge.http.createRequest({method: 'GET', path: url.path});\n\n// send the request somewhere\nsendSomehow(request.toString());\n\n// receive response\nvar buffer = forge.util.createBuffer();\nvar response = forge.http.createResponse();\nvar someAsyncDataHandler = function(bytes) {\n  if(!response.bodyReceived) {\n    buffer.putBytes(bytes);\n    if(!response.headerReceived) {\n      if(response.readHeader(buffer)) {\n        console.log('HTTP response header: ' + response.toString());\n      }\n    }\n    if(response.headerReceived && !response.bodyReceived) {\n      if(response.readBody(buffer)) {\n        console.log('HTTP response body: ' + response.body);\n      }\n    }\n  }\n};\n```\n\n<a name=\"ssh\" />\n### SSH\n\nProvides some SSH utility functions.\n\n__Examples__\n\n```js\n// encodes (and optionally encrypts) a private RSA key as a Putty PPK file\nforge.ssh.privateKeyToPutty(privateKey, passphrase, comment);\n\n// encodes a public RSA key as an OpenSSH file\nforge.ssh.publicKeyToOpenSSH(key, comment);\n\n// encodes a private RSA key as an OpenSSH file\nforge.ssh.privateKeyToOpenSSH(privateKey, passphrase);\n\n// gets the SSH public key fingerprint in a byte buffer\nforge.ssh.getPublicKeyFingerprint(key);\n\n// gets a hex-encoded, colon-delimited SSH public key fingerprint\nforge.ssh.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'});\n```\n\n<a name=\"xhr\" />\n### XHR\n\nProvides an XmlHttpRequest implementation using forge.http as a backend.\n\n__Examples__\n\n```js\n// TODO\n```\n\n<a name=\"socket\" />\n### Sockets\n\nProvides an interface to create and use raw sockets provided via Flash.\n\n__Examples__\n\n```js\n// TODO\n```\n\nCiphers\n-------\n\n<a name=\"cipher\" />\n### CIPHER\n\nProvides a basic API for block encryption and decryption. There is built-in\nsupport for the ciphers: [AES][], [3DES][], and [DES][], and for the modes\nof operation: [ECB][], [CBC][], [CFB][], [OFB][], [CTR][], and [GCM][].\n\nThese algorithms are currently supported:\n\n* AES-ECB\n* AES-CBC\n* AES-CFB\n* AES-OFB\n* AES-CTR\n* AES-GCM\n* 3DES-ECB\n* 3DES-CBC\n* DES-ECB\n* DES-CBC\n\nWhen using an [AES][] algorithm, the key size will determine whether\nAES-128, AES-192, or AES-256 is used (all are supported). When a [DES][]\nalgorithm is used, the key size will determine whether [3DES][] or regular\n[DES][] is used. Use a [3DES][] algorithm to enforce Triple-DES.\n\n__Examples__\n\n```js\n// generate a random key and IV\n// Note: a key size of 16 bytes will use AES-128, 24 => AES-192, 32 => AES-256\nvar key = forge.random.getBytesSync(16);\nvar iv = forge.random.getBytesSync(16);\n\n/* alternatively, generate a password-based 16-byte key\nvar salt = forge.random.getBytesSync(128);\nvar key = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);\n*/\n\n// encrypt some bytes using CBC mode\n// (other modes include: ECB, CFB, OFB, CTR, and GCM)\n// Note: CBC and ECB modes use PKCS#7 padding as default\nvar cipher = forge.cipher.createCipher('AES-CBC', key);\ncipher.start({iv: iv});\ncipher.update(forge.util.createBuffer(someBytes));\ncipher.finish();\nvar encrypted = cipher.output;\n// outputs encrypted hex\nconsole.log(encrypted.toHex());\n\n// decrypt some bytes using CBC mode\n// (other modes include: CFB, OFB, CTR, and GCM)\nvar decipher = forge.cipher.createDecipher('AES-CBC', key);\ndecipher.start({iv: iv});\ndecipher.update(encrypted);\ndecipher.finish();\n// outputs decrypted hex\nconsole.log(decipher.output.toHex());\n\n// encrypt some bytes using GCM mode\nvar cipher = forge.cipher.createCipher('AES-GCM', key);\ncipher.start({\n  iv: iv, // should be a 12-byte binary-encoded string or byte buffer\n  additionalData: 'binary-encoded string', // optional\n  tagLength: 128 // optional, defaults to 128 bits\n});\ncipher.update(forge.util.createBuffer(someBytes));\ncipher.finish();\nvar encrypted = cipher.output;\nvar tag = cipher.mode.tag;\n// outputs encrypted hex\nconsole.log(encrypted.toHex());\n// outputs authentication tag\nconsole.log(tag.toHex());\n\n// decrypt some bytes using GCM mode\nvar decipher = forge.cipher.createDecipher('AES-GCM', key);\ndecipher.start({\n  iv: iv,\n  additionalData: 'binary-encoded string', // optional\n  tagLength: 128, // optional, defaults to 128 bits\n  tag: tag // authentication tag from encryption\n});\ndecipher.update(encrypted);\nvar pass = decipher.finish();\n// pass is false if there was a failure (eg: authentication tag didn't match)\nif(pass) {\n  // outputs decrypted hex\n  console.log(decipher.output.toHex());\n}\n```\n\nUsing forge in Node.js to match openssl's \"enc\" command line tool (**Note**: OpenSSL \"enc\" uses a non-standard file format with a custom key derivation function and a fixed iteration count of 1, which some consider less secure than alternatives such as [OpenPGP](https://tools.ietf.org/html/rfc4880)/[GnuPG](https://www.gnupg.org/)):\n\n```js\nvar forge = require('node-forge');\nvar fs = require('fs');\n\n// openssl enc -des3 -in input.txt -out input.enc\nfunction encrypt(password) {\n  var input = fs.readFileSync('input.txt', {encoding: 'binary'});\n\n  // 3DES key and IV sizes\n  var keySize = 24;\n  var ivSize = 8;\n\n  // get derived bytes\n  // Notes:\n  // 1. If using an alternative hash (eg: \"-md sha1\") pass\n  //   \"forge.md.sha1.create()\" as the final parameter.\n  // 2. If using \"-nosalt\", set salt to null.\n  var salt = forge.random.getBytesSync(8);\n  // var md = forge.md.sha1.create(); // \"-md sha1\"\n  var derivedBytes = forge.pbe.opensslDeriveBytes(\n    password, salt, keySize + ivSize/*, md*/);\n  var buffer = forge.util.createBuffer(derivedBytes);\n  var key = buffer.getBytes(keySize);\n  var iv = buffer.getBytes(ivSize);\n\n  var cipher = forge.cipher.createCipher('3DES-CBC', key);\n  cipher.start({iv: iv});\n  cipher.update(forge.util.createBuffer(input, 'binary'));\n  cipher.finish();\n\n  var output = forge.util.createBuffer();\n\n  // if using a salt, prepend this to the output:\n  if(salt !== null) {\n    output.putBytes('Salted__'); // (add to match openssl tool output)\n    output.putBytes(salt);\n  }\n  output.putBuffer(cipher.output);\n\n  fs.writeFileSync('input.enc', output.getBytes(), {encoding: 'binary'});\n}\n\n// openssl enc -d -des3 -in input.enc -out input.dec.txt\nfunction decrypt(password) {\n  var input = fs.readFileSync('input.enc', {encoding: 'binary'});\n\n  // parse salt from input\n  input = forge.util.createBuffer(input, 'binary');\n  // skip \"Salted__\" (if known to be present)\n  input.getBytes('Salted__'.length);\n  // read 8-byte salt\n  var salt = input.getBytes(8);\n\n  // Note: if using \"-nosalt\", skip above parsing and use\n  // var salt = null;\n\n  // 3DES key and IV sizes\n  var keySize = 24;\n  var ivSize = 8;\n\n  var derivedBytes = forge.pbe.opensslDeriveBytes(\n    password, salt, keySize + ivSize);\n  var buffer = forge.util.createBuffer(derivedBytes);\n  var key = buffer.getBytes(keySize);\n  var iv = buffer.getBytes(ivSize);\n\n  var decipher = forge.cipher.createDecipher('3DES-CBC', key);\n  decipher.start({iv: iv});\n  decipher.update(input);\n  var result = decipher.finish(); // check 'result' for true/false\n\n  fs.writeFileSync(\n    'input.dec.txt', decipher.output.getBytes(), {encoding: 'binary'});\n}\n```\n\n<a name=\"aes\" />\n### AES\n\nProvides [AES][] encryption and decryption in [CBC][], [CFB][], [OFB][],\n[CTR][], and [GCM][] modes. See [CIPHER](#cipher) for examples.\n\n<a name=\"des\" />\n### DES\n\nProvides [3DES][] and [DES][] encryption and decryption in [ECB][] and\n[CBC][] modes. See [CIPHER](#cipher) for examples.\n\n<a name=\"rc2\" />\n### RC2\n\n__Examples__\n\n```js\n// generate a random key and IV\nvar key = forge.random.getBytesSync(16);\nvar iv = forge.random.getBytesSync(8);\n\n// encrypt some bytes\nvar cipher = forge.rc2.createEncryptionCipher(key);\ncipher.start(iv);\ncipher.update(forge.util.createBuffer(someBytes));\ncipher.finish();\nvar encrypted = cipher.output;\n// outputs encrypted hex\nconsole.log(encrypted.toHex());\n\n// decrypt some bytes\nvar cipher = forge.rc2.createDecryptionCipher(key);\ncipher.start(iv);\ncipher.update(encrypted);\ncipher.finish();\n// outputs decrypted hex\nconsole.log(cipher.output.toHex());\n```\n\nPKI\n---\n\nProvides [X.509][] certificate and RSA public and private key encoding,\ndecoding, encryption/decryption, and signing/verifying.\n\n<a name=\"rsa\" />\n### RSA\n\n__Examples__\n\n```js\nvar rsa = forge.pki.rsa;\n\n// generate an RSA key pair synchronously\n// *NOT RECOMMENDED* -- can be significantly slower than async and will not\n// use native APIs if available.\nvar keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001});\n\n// generate an RSA key pair asynchronously (uses web workers if available)\n// use workers: -1 to run a fast core estimator to optimize # of workers\n// *RECOMMENDED* - can be significantly faster than sync -- and will use\n// native APIs if available.\nrsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) {\n  // keypair.privateKey, keypair.publicKey\n});\n\n// generate an RSA key pair in steps that attempt to run for a specified period\n// of time on the main JS thread\nvar state = rsa.createKeyPairGenerationState(2048, 0x10001);\nvar step = function() {\n  // run for 100 ms\n  if(!rsa.stepKeyPairGenerationState(state, 100)) {\n    setTimeout(step, 1);\n  }\n  else {\n    // done, turn off progress indicator, use state.keys\n  }\n};\n// turn on progress indicator, schedule generation to run\nsetTimeout(step);\n\n// sign data with a private key and output DigestInfo DER-encoded bytes\n// (defaults to RSASSA PKCS#1 v1.5)\nvar md = forge.md.sha1.create();\nmd.update('sign this', 'utf8');\nvar signature = privateKey.sign(md);\n\n// verify data with a public key\n// (defaults to RSASSA PKCS#1 v1.5)\nvar verified = publicKey.verify(md.digest().bytes(), signature);\n\n// sign data using RSASSA-PSS where PSS uses a SHA-1 hash, a SHA-1 based\n// masking function MGF1, and a 20 byte salt\nvar md = forge.md.sha1.create();\nmd.update('sign this', 'utf8');\nvar pss = forge.pss.create({\n  md: forge.md.sha1.create(),\n  mgf: forge.mgf.mgf1.create(forge.md.sha1.create()),\n  saltLength: 20\n  // optionally pass 'prng' with a custom PRNG implementation\n  // optionalls pass 'salt' with a forge.util.ByteBuffer w/custom salt\n});\nvar signature = privateKey.sign(md, pss);\n\n// verify RSASSA-PSS signature\nvar pss = forge.pss.create({\n  md: forge.md.sha1.create(),\n  mgf: forge.mgf.mgf1.create(forge.md.sha1.create()),\n  saltLength: 20\n  // optionally pass 'prng' with a custom PRNG implementation\n});\nvar md = forge.md.sha1.create();\nmd.update('sign this', 'utf8');\npublicKey.verify(md.digest().getBytes(), signature, pss);\n\n// encrypt data with a public key (defaults to RSAES PKCS#1 v1.5)\nvar encrypted = publicKey.encrypt(bytes);\n\n// decrypt data with a private key (defaults to RSAES PKCS#1 v1.5)\nvar decrypted = privateKey.decrypt(encrypted);\n\n// encrypt data with a public key using RSAES PKCS#1 v1.5\nvar encrypted = publicKey.encrypt(bytes, 'RSAES-PKCS1-V1_5');\n\n// decrypt data with a private key using RSAES PKCS#1 v1.5\nvar decrypted = privateKey.decrypt(encrypted, 'RSAES-PKCS1-V1_5');\n\n// encrypt data with a public key using RSAES-OAEP\nvar encrypted = publicKey.encrypt(bytes, 'RSA-OAEP');\n\n// decrypt data with a private key using RSAES-OAEP\nvar decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP');\n\n// encrypt data with a public key using RSAES-OAEP/SHA-256\nvar encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', {\n  md: forge.md.sha256.create()\n});\n\n// decrypt data with a private key using RSAES-OAEP/SHA-256\nvar decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', {\n  md: forge.md.sha256.create()\n});\n\n// encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1\n// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding\nvar encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', {\n  md: forge.md.sha256.create(),\n  mgf1: {\n    md: forge.md.sha1.create()\n  }\n});\n\n// decrypt data with a private key using RSAES-OAEP/SHA-256/MGF1-SHA-1\n// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding\nvar decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', {\n  md: forge.md.sha256.create(),\n  mgf1: {\n    md: forge.md.sha1.create()\n  }\n});\n\n```\n\n<a name=\"rsakem\" />\n### RSA-KEM\n\n__Examples__\n\n```js\n// generate an RSA key pair asynchronously (uses web workers if available)\n// use workers: -1 to run a fast core estimator to optimize # of workers\nforge.rsa.generateKeyPair({bits: 2048, workers: -1}, function(err, keypair) {\n  // keypair.privateKey, keypair.publicKey\n});\n\n// generate and encapsulate a 16-byte secret key\nvar kdf1 = new forge.kem.kdf1(forge.md.sha1.create());\nvar kem = forge.kem.rsa.create(kdf1);\nvar result = kem.encrypt(keypair.publicKey, 16);\n// result has 'encapsulation' and 'key'\n\n// encrypt some bytes\nvar iv = forge.random.getBytesSync(12);\nvar someBytes = 'hello world!';\nvar cipher = forge.cipher.createCipher('AES-GCM', result.key);\ncipher.start({iv: iv});\ncipher.update(forge.util.createBuffer(someBytes));\ncipher.finish();\nvar encrypted = cipher.output.getBytes();\nvar tag = cipher.mode.tag.getBytes();\n\n// send 'encrypted', 'iv', 'tag', and result.encapsulation to recipient\n\n// decrypt encapsulated 16-byte secret key\nvar kdf1 = new forge.kem.kdf1(forge.md.sha1.create());\nvar kem = forge.kem.rsa.create(kdf1);\nvar key = kem.decrypt(keypair.privateKey, result.encapsulation, 16);\n\n// decrypt some bytes\nvar decipher = forge.cipher.createDecipher('AES-GCM', key);\ndecipher.start({iv: iv, tag: tag});\ndecipher.update(forge.util.createBuffer(encrypted));\nvar pass = decipher.finish();\n// pass is false if there was a failure (eg: authentication tag didn't match)\nif(pass) {\n  // outputs 'hello world!'\n  console.log(decipher.output.getBytes());\n}\n\n```\n\n<a name=\"x509\" />\n### X.509\n\n__Examples__\n\n```js\nvar pki = forge.pki;\n\n// convert a PEM-formatted public key to a Forge public key\nvar publicKey = pki.publicKeyFromPem(pem);\n\n// convert a Forge public key to PEM-format\nvar pem = pki.publicKeyToPem(publicKey);\n\n// convert an ASN.1 SubjectPublicKeyInfo to a Forge public key\nvar publicKey = pki.publicKeyFromAsn1(subjectPublicKeyInfo);\n\n// convert a Forge public key to an ASN.1 SubjectPublicKeyInfo\nvar subjectPublicKeyInfo = pki.publicKeyToAsn1(publicKey);\n\n// gets a SHA-1 RSAPublicKey fingerprint a byte buffer\npki.getPublicKeyFingerprint(key);\n\n// gets a SHA-1 SubjectPublicKeyInfo fingerprint a byte buffer\npki.getPublicKeyFingerprint(key, {type: 'SubjectPublicKeyInfo'});\n\n// gets a hex-encoded, colon-delimited SHA-1 RSAPublicKey public key fingerprint\npki.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'});\n\n// gets a hex-encoded, colon-delimited SHA-1 SubjectPublicKeyInfo public key fingerprint\npki.getPublicKeyFingerprint(key, {\n  type: 'SubjectPublicKeyInfo',\n  encoding: 'hex',\n  delimiter: ':'\n});\n\n// gets a hex-encoded, colon-delimited MD5 RSAPublicKey public key fingerprint\npki.getPublicKeyFingerprint(key, {\n  md: forge.md.md5.create(),\n  encoding: 'hex',\n  delimiter: ':'\n});\n\n// creates a CA store\nvar caStore = pki.createCaStore([/* PEM-encoded cert */, ...]);\n\n// add a certificate to the CA store\ncaStore.addCertificate(certObjectOrPemString);\n\n// gets the issuer (its certificate) for the given certificate\nvar issuerCert = caStore.getIssuer(subjectCert);\n\n// verifies a certificate chain against a CA store\npki.verifyCertificateChain(caStore, chain, customVerifyCallback);\n\n// signs a certificate using the given private key\ncert.sign(privateKey);\n\n// signs a certificate using SHA-256 instead of SHA-1\ncert.sign(privateKey, forge.md.sha256.create());\n\n// verifies an issued certificate using the certificates public key\nvar verified = issuer.verify(issued);\n\n// generate a keypair and create an X.509v3 certificate\nvar keys = pki.rsa.generateKeyPair(2048);\nvar cert = pki.createCertificate();\ncert.publicKey = keys.publicKey;\n// alternatively set public key from a csr\n//cert.publicKey = csr.publicKey;\ncert.serialNumber = '01';\ncert.validity.notBefore = new Date();\ncert.validity.notAfter = new Date();\ncert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);\nvar attrs = [{\n  name: 'commonName',\n  value: 'example.org'\n}, {\n  name: 'countryName',\n  value: 'US'\n}, {\n  shortName: 'ST',\n  value: 'Virginia'\n}, {\n  name: 'localityName',\n  value: 'Blacksburg'\n}, {\n  name: 'organizationName',\n  value: 'Test'\n}, {\n  shortName: 'OU',\n  value: 'Test'\n}];\ncert.setSubject(attrs);\n// alternatively set subject from a csr\n//cert.setSubject(csr.subject.attributes);\ncert.setIssuer(attrs);\ncert.setExtensions([{\n  name: 'basicConstraints',\n  cA: true\n}, {\n  name: 'keyUsage',\n  keyCertSign: true,\n  digitalSignature: true,\n  nonRepudiation: true,\n  keyEncipherment: true,\n  dataEncipherment: true\n}, {\n  name: 'extKeyUsage',\n  serverAuth: true,\n  clientAuth: true,\n  codeSigning: true,\n  emailProtection: true,\n  timeStamping: true\n}, {\n  name: 'nsCertType',\n  client: true,\n  server: true,\n  email: true,\n  objsign: true,\n  sslCA: true,\n  emailCA: true,\n  objCA: true\n}, {\n  name: 'subjectAltName',\n  altNames: [{\n    type: 6, // URI\n    value: 'http://example.org/webid#me'\n  }, {\n    type: 7, // IP\n    ip: '127.0.0.1'\n  }]\n}, {\n  name: 'subjectKeyIdentifier'\n}]);\n/* alternatively set extensions from a csr\nvar extensions = csr.getAttribute({name: 'extensionRequest'}).extensions;\n// optionally add more extensions\nextensions.push.apply(extensions, [{\n  name: 'basicConstraints',\n  cA: true\n}, {\n  name: 'keyUsage',\n  keyCertSign: true,\n  digitalSignature: true,\n  nonRepudiation: true,\n  keyEncipherment: true,\n  dataEncipherment: true\n}]);\ncert.setExtensions(extensions);\n*/\n// self-sign certificate\ncert.sign(keys.privateKey);\n\n// convert a Forge certificate to PEM\nvar pem = pki.certificateToPem(cert);\n\n// convert a Forge certificate from PEM\nvar cert = pki.certificateFromPem(pem);\n\n// convert an ASN.1 X.509x3 object to a Forge certificate\nvar cert = pki.certificateFromAsn1(obj);\n\n// convert a Forge certificate to an ASN.1 X.509v3 object\nvar asn1Cert = pki.certificateToAsn1(cert);\n```\n\n<a name=\"pkcs5\" />\n### PKCS#5\n\nProvides the password-based key-derivation function from [PKCS#5][].\n\n__Examples__\n\n```js\n// generate a password-based 16-byte key\n// note an optional message digest can be passed as the final parameter\nvar salt = forge.random.getBytesSync(128);\nvar derivedKey = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);\n\n// generate key asynchronously\n// note an optional message digest can be passed before the callback\nforge.pkcs5.pbkdf2('password', salt, numIterations, 16, function(err, derivedKey) {\n  // do something w/derivedKey\n});\n```\n\n<a name=\"pkcs7\" />\n### PKCS#7\n\nProvides cryptographically protected messages from [PKCS#7][].\n\n__Examples__\n\n```js\n// convert a message from PEM\nvar p7 = forge.pkcs7.messageFromPem(pem);\n// look at p7.recipients\n\n// find a recipient by the issuer of a certificate\nvar recipient = p7.findRecipient(cert);\n\n// decrypt\np7.decrypt(p7.recipients[0], privateKey);\n\n// create a p7 enveloped message\nvar p7 = forge.pkcs7.createEnvelopedData();\n\n// add a recipient\nvar cert = forge.pki.certificateFromPem(certPem);\np7.addRecipient(cert);\n\n// set content\np7.content = forge.util.createBuffer('Hello');\n\n// encrypt\np7.encrypt();\n\n// convert message to PEM\nvar pem = forge.pkcs7.messageToPem(p7);\n\n// create a degenerate PKCS#7 certificate container\n// (CRLs not currently supported, only certificates)\nvar p7 = forge.pkcs7.createSignedData();\np7.addCertificate(certOrCertPem1);\np7.addCertificate(certOrCertPem2);\nvar pem = forge.pkcs7.messageToPem(p7);\n\n// create PKCS#7 signed data with authenticatedAttributes\n// attributes include: PKCS#9 content-type, message-digest, and signing-time\nvar p7 = forge.pkcs7.createSignedData();\np7.content = forge.util.createBuffer('Some content to be signed.', 'utf8');\np7.addCertificate(certOrCertPem);\np7.addSigner({\n  key: privateKeyAssociatedWithCert,\n  certificate: certOrCertPem,\n  digestAlgorithm: forge.pki.oids.sha256,\n  authenticatedAttributes: [{\n    type: forge.pki.oids.contentType,\n    value: forge.pki.oids.data\n  }, {\n    type: forge.pki.oids.messageDigest\n    // value will be auto-populated at signing time\n  }, {\n    type: forge.pki.oids.signingTime,\n    // value can also be auto-populated at signing time\n    value: new Date()\n  }]\n});\np7.sign();\nvar pem = forge.pkcs7.messageToPem(p7);\n\n```\n\n<a name=\"pkcs8\" />\n### PKCS#8\n\n__Examples__\n\n```js\nvar pki = forge.pki;\n\n// convert a PEM-formatted private key to a Forge private key\nvar privateKey = pki.privateKeyFromPem(pem);\n\n// convert a Forge private key to PEM-format\nvar pem = pki.privateKeyToPem(privateKey);\n\n// convert an ASN.1 PrivateKeyInfo or RSAPrivateKey to a Forge private key\nvar privateKey = pki.privateKeyFromAsn1(rsaPrivateKey);\n\n// convert a Forge private key to an ASN.1 RSAPrivateKey\nvar rsaPrivateKey = pki.privateKeyToAsn1(privateKey);\n\n// wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo\nvar privateKeyInfo = pki.wrapRsaPrivateKey(rsaPrivateKey);\n\n// convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM\nvar pem = pki.privateKeyInfoToPem(privateKeyInfo);\n\n// encrypts a PrivateKeyInfo and outputs an EncryptedPrivateKeyInfo\nvar encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo(\n  privateKeyInfo, 'password', {\n    algorithm: 'aes256', // 'aes128', 'aes192', 'aes256', '3des'\n  });\n\n// decrypts an ASN.1 EncryptedPrivateKeyInfo\nvar privateKeyInfo = pki.decryptPrivateKeyInfo(\n  encryptedPrivateKeyInfo, 'password');\n\n// converts an EncryptedPrivateKeyInfo to PEM\nvar pem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo);\n\n// converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format\nvar encryptedPrivateKeyInfo = pki.encryptedPrivateKeyFromPem(pem);\n\n// wraps and encrypts a Forge private key and outputs it in PEM format\nvar pem = pki.encryptRsaPrivateKey(privateKey, 'password');\n\n// encrypts a Forge private key and outputs it in PEM format using OpenSSL's\n// proprietary legacy format + encapsulated PEM headers (DEK-Info)\nvar pem = pki.encryptRsaPrivateKey(privateKey, 'password', {legacy: true});\n\n// decrypts a PEM-formatted, encrypted private key\nvar privateKey = pki.decryptRsaPrivateKey(pem, 'password');\n\n// sets an RSA public key from a private key\nvar publicKey = pki.setRsaPublicKey(privateKey.n, privateKey.e);\n```\n\n<a name=\"pkcs10\" />\n### PKCS#10\n\nProvides certification requests or certificate signing requests (CSR) from\n[PKCS#10][].\n\n__Examples__\n\n```js\n// generate a key pair\nvar keys = forge.pki.rsa.generateKeyPair(1024);\n\n// create a certification request (CSR)\nvar csr = forge.pki.createCertificationRequest();\ncsr.publicKey = keys.publicKey;\ncsr.setSubject([{\n  name: 'commonName',\n  value: 'example.org'\n}, {\n  name: 'countryName',\n  value: 'US'\n}, {\n  shortName: 'ST',\n  value: 'Virginia'\n}, {\n  name: 'localityName',\n  value: 'Blacksburg'\n}, {\n  name: 'organizationName',\n  value: 'Test'\n}, {\n  shortName: 'OU',\n  value: 'Test'\n}]);\n// set (optional) attributes\ncsr.setAttributes([{\n  name: 'challengePassword',\n  value: 'password'\n}, {\n  name: 'unstructuredName',\n  value: 'My Company, Inc.'\n}, {\n  name: 'extensionRequest',\n  extensions: [{\n    name: 'subjectAltName',\n    altNames: [{\n      // 2 is DNS type\n      type: 2,\n      value: 'test.domain.com'\n    }, {\n      type: 2,\n      value: 'other.domain.com',\n    }, {\n      type: 2,\n      value: 'www.domain.net'\n    }]\n  }]\n}]);\n\n// sign certification request\ncsr.sign(keys.privateKey);\n\n// verify certification request\nvar verified = csr.verify();\n\n// convert certification request to PEM-format\nvar pem = forge.pki.certificationRequestToPem(csr);\n\n// convert a Forge certification request from PEM-format\nvar csr = forge.pki.certificationRequestFromPem(pem);\n\n// get an attribute\ncsr.getAttribute({name: 'challengePassword'});\n\n// get extensions array\ncsr.getAttribute({name: 'extensionRequest'}).extensions;\n\n```\n\n<a name=\"pkcs12\" />\n### PKCS#12\n\nProvides the cryptographic archive file format from [PKCS#12][].\n\n**Note for Chrome/Firefox/iOS/similar users**: If you have trouble importing\na PKCS#12 container, try using the TripleDES algorithm. It can be passed\nto `forge.pkcs12.toPkcs12Asn1` using the `{algorithm: '3des'}` option.\n\n__Examples__\n\n```js\n// decode p12 from base64\nvar p12Der = forge.util.decode64(p12b64);\n// get p12 as ASN.1 object\nvar p12Asn1 = forge.asn1.fromDer(p12Der);\n// decrypt p12 using the password 'password'\nvar p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password');\n// decrypt p12 using non-strict parsing mode (resolves some ASN.1 parse errors)\nvar p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, 'password');\n// decrypt p12 using literally no password (eg: Mac OS X/apple push)\nvar p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1);\n// decrypt p12 using an \"empty\" password (eg: OpenSSL with no password input)\nvar p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, '');\n// p12.safeContents is an array of safe contents, each of\n// which contains an array of safeBags\n\n// get bags by friendlyName\nvar bags = p12.getBags({friendlyName: 'test'});\n// bags are key'd by attribute type (here \"friendlyName\")\n// and the key values are an array of matching objects\nvar cert = bags.friendlyName[0];\n\n// get bags by localKeyId\nvar bags = p12.getBags({localKeyId: buffer});\n// bags are key'd by attribute type (here \"localKeyId\")\n// and the key values are an array of matching objects\nvar cert = bags.localKeyId[0];\n\n// get bags by localKeyId (input in hex)\nvar bags = p12.getBags({localKeyIdHex: '7b59377ff142d0be4565e9ac3d396c01401cd879'});\n// bags are key'd by attribute type (here \"localKeyId\", *not* \"localKeyIdHex\")\n// and the key values are an array of matching objects\nvar cert = bags.localKeyId[0];\n\n// get bags by type\nvar bags = p12.getBags({bagType: forge.pki.oids.certBag});\n// bags are key'd by bagType and each bagType key's value\n// is an array of matches (in this case, certificate objects)\nvar cert = bags[forge.pki.oids.certBag][0];\n\n// get bags by friendlyName and filter on bag type\nvar bags = p12.getBags({\n  friendlyName: 'test',\n  bagType: forge.pki.oids.certBag\n});\n\n// get key bags\nvar bags = p12.getBags({bagType: forge.pki.oids.keyBag});\n// get key\nvar bag = bags[forge.pki.oids.keyBag][0];\nvar key = bag.key;\n// if the key is in a format unrecognized by forge then\n// bag.key will be `null`, use bag.asn1 to get the ASN.1\n// representation of the key\nif(bag.key === null) {\n  var keyAsn1 = bag.asn1;\n  // can now convert back to DER/PEM/etc for export\n}\n\n// generate a p12 using AES (default)\nvar p12Asn1 = forge.pkcs12.toPkcs12Asn1(\n  privateKey, certificateChain, 'password');\n\n// generate a p12 that can be imported by Chrome/Firefox/iOS\n// (requires the use of Triple DES instead of AES)\nvar p12Asn1 = forge.pkcs12.toPkcs12Asn1(\n  privateKey, certificateChain, 'password',\n  {algorithm: '3des'});\n\n// base64-encode p12\nvar p12Der = forge.asn1.toDer(p12Asn1).getBytes();\nvar p12b64 = forge.util.encode64(p12Der);\n\n// create download link for p12\nvar a = document.createElement('a');\na.download = 'example.p12';\na.setAttribute('href', 'data:application/x-pkcs12;base64,' + p12b64);\na.appendChild(document.createTextNode('Download'));\n```\n\n<a name=\"asn\" />\n### ASN.1\n\nProvides [ASN.1][] DER encoding and decoding.\n\n__Examples__\n\n```js\nvar asn1 = forge.asn1;\n\n// create a SubjectPublicKeyInfo\nvar subjectPublicKeyInfo =\n  asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [\n    // AlgorithmIdentifier\n    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [\n      // algorithm\n      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,\n        asn1.oidToDer(pki.oids['rsaEncryption']).getBytes()),\n      // parameters (null)\n      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')\n    ]),\n    // subjectPublicKey\n    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [\n      // RSAPublicKey\n      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [\n        // modulus (n)\n        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,\n          _bnToBytes(key.n)),\n        // publicExponent (e)\n        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,\n          _bnToBytes(key.e))\n      ])\n    ])\n  ]);\n\n// serialize an ASN.1 object to DER format\nvar derBuffer = asn1.toDer(subjectPublicKeyInfo);\n\n// deserialize to an ASN.1 object from a byte buffer filled with DER data\nvar object = asn1.fromDer(derBuffer);\n\n// convert an OID dot-separated string to a byte buffer\nvar derOidBuffer = asn1.oidToDer('1.2.840.113549.1.1.5');\n\n// convert a byte buffer with a DER-encoded OID to a dot-separated string\nconsole.log(asn1.derToOid(derOidBuffer));\n// output: 1.2.840.113549.1.1.5\n\n// validates that an ASN.1 object matches a particular ASN.1 structure and\n// captures data of interest from that structure for easy access\nvar publicKeyValidator = {\n  name: 'SubjectPublicKeyInfo',\n  tagClass: asn1.Class.UNIVERSAL,\n  type: asn1.Type.SEQUENCE,\n  constructed: true,\n  captureAsn1: 'subjectPublicKeyInfo',\n  value: [{\n    name: 'SubjectPublicKeyInfo.AlgorithmIdentifier',\n    tagClass: asn1.Class.UNIVERSAL,\n    type: asn1.Type.SEQUENCE,\n    constructed: true,\n    value: [{\n      name: 'AlgorithmIdentifier.algorithm',\n      tagClass: asn1.Class.UNIVERSAL,\n      type: asn1.Type.OID,\n      constructed: false,\n      capture: 'publicKeyOid'\n    }]\n  }, {\n    // subjectPublicKey\n    name: 'SubjectPublicKeyInfo.subjectPublicKey',\n    tagClass: asn1.Class.UNIVERSAL,\n    type: asn1.Type.BITSTRING,\n    constructed: false,\n    value: [{\n      // RSAPublicKey\n      name: 'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey',\n      tagClass: asn1.Class.UNIVERSAL,\n      type: asn1.Type.SEQUENCE,\n      constructed: true,\n      optional: true,\n      captureAsn1: 'rsaPublicKey'\n    }]\n  }]\n};\n\nvar capture = {};\nvar errors = [];\nif(!asn1.validate(\n  publicKeyValidator, subjectPublicKeyInfo, validator, capture, errors)) {\n  throw 'ASN.1 object is not a SubjectPublicKeyInfo.';\n}\n// capture.subjectPublicKeyInfo contains the full ASN.1 object\n// capture.rsaPublicKey contains the full ASN.1 object for the RSA public key\n// capture.publicKeyOid only contains the value for the OID\nvar oid = asn1.derToOid(capture.publicKeyOid);\nif(oid !== pki.oids['rsaEncryption']) {\n  throw 'Unsupported OID.';\n}\n\n// pretty print an ASN.1 object to a string for debugging purposes\nasn1.prettyPrint(object);\n```\n\nMessage Digests\n----------------\n\n<a name=\"sha1\" />\n### SHA1\n\nProvides [SHA-1][] message digests.\n\n__Examples__\n\n```js\nvar md = forge.md.sha1.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12\n```\n\n<a name=\"sha256\" />\n### SHA256\n\nProvides [SHA-256][] message digests.\n\n__Examples__\n\n```js\nvar md = forge.md.sha256.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592\n```\n\n<a name=\"sha384\" />\n### SHA384\n\nProvides [SHA-384][] message digests.\n\n__Examples__\n\n```js\nvar md = forge.md.sha384.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1\n```\n\n<a name=\"sha512\" />\n### SHA512\n\nProvides [SHA-512][] message digests.\n\n__Examples__\n\n```js\n// SHA-512\nvar md = forge.md.sha512.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6\n\n// SHA-512/224\nvar md = forge.md.sha512.sha224.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: 944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37\n\n// SHA-512/256\nvar md = forge.md.sha512.sha256.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d\n```\n\n<a name=\"md5\" />\n### MD5\n\nProvides [MD5][] message digests.\n\n__Examples__\n\n```js\nvar md = forge.md.md5.create();\nmd.update('The quick brown fox jumps over the lazy dog');\nconsole.log(md.digest().toHex());\n// output: 9e107d9d372bb6826bd81d3542a419d6\n```\n\n<a name=\"hmac\" />\n### HMAC\n\nProvides [HMAC][] w/any supported message digest algorithm.\n\n__Examples__\n\n```js\nvar hmac = forge.hmac.create();\nhmac.start('sha1', 'Jefe');\nhmac.update('what do ya want for nothing?');\nconsole.log(hmac.digest().toHex());\n// output: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79\n```\n\nUtilities\n---------\n\n<a name=\"prime\" />\n### Prime\n\nProvides an API for generating large, random, probable primes.\n\n__Examples__\n\n```js\n// generate a random prime on the main JS thread\nvar bits = 1024;\nforge.prime.generateProbablePrime(bits, function(err, num) {\n  console.log('random prime', num.toString(16));\n});\n\n// generate a random prime using Web Workers (if available, otherwise\n// falls back to the main thread)\nvar bits = 1024;\nvar options = {\n  algorithm: {\n    name: 'PRIMEINC',\n    workers: -1 // auto-optimize # of workers\n  }\n};\nforge.prime.generateProbablePrime(bits, options, function(err, num) {\n  console.log('random prime', num.toString(16));\n});\n```\n\n<a name=\"prng\" />\n### PRNG\n\nProvides a [Fortuna][]-based cryptographically-secure pseudo-random number\ngenerator, to be used with a cryptographic function backend, e.g. [AES][]. An\nimplementation using [AES][] as a backend is provided. An API for collecting\nentropy is given, though if window.crypto.getRandomValues is available, it will\nbe used automatically.\n\n__Examples__\n\n```js\n// get some random bytes synchronously\nvar bytes = forge.random.getBytesSync(32);\nconsole.log(forge.util.bytesToHex(bytes));\n\n// get some random bytes asynchronously\nforge.random.getBytes(32, function(err, bytes) {\n  console.log(forge.util.bytesToHex(bytes));\n});\n\n// collect some entropy if you'd like\nforge.random.collect(someRandomBytes);\njQuery().mousemove(function(e) {\n  forge.random.collectInt(e.clientX, 16);\n  forge.random.collectInt(e.clientY, 16);\n});\n\n// specify a seed file for use with the synchronous API if you'd like\nforge.random.seedFileSync = function(needed) {\n  // get 'needed' number of random bytes from somewhere\n  return fetchedRandomBytes;\n};\n\n// specify a seed file for use with the asynchronous API if you'd like\nforge.random.seedFile = function(needed, callback) {\n  // get the 'needed' number of random bytes from somewhere\n  callback(null, fetchedRandomBytes);\n});\n\n// register the main thread to send entropy or a Web Worker to receive\n// entropy on demand from the main thread\nforge.random.registerWorker(self);\n\n// generate a new instance of a PRNG with no collected entropy\nvar myPrng = forge.random.createInstance();\n```\n\n<a name=\"task\" />\n### Tasks\n\nProvides queuing and synchronizing tasks in a web application.\n\n__Examples__\n\n```js\n// TODO\n```\n\n<a name=\"util\" />\n### Utilities\n\nProvides utility functions, including byte buffer support, base64,\nbytes to/from hex, zlib inflate/deflate, etc.\n\n__Examples__\n\n```js\n// encode/decode base64\nvar encoded = forge.util.encode64(str);\nvar str = forge.util.decode64(encoded);\n\n// encode/decode UTF-8\nvar encoded = forge.util.encodeUtf8(str);\nvar str = forge.util.decodeUtf8(encoded);\n\n// bytes to/from hex\nvar bytes = forge.util.hexToBytes(hex);\nvar hex = forge.util.bytesToHex(bytes);\n\n// create an empty byte buffer\nvar buffer = forge.util.createBuffer();\n// create a byte buffer from raw binary bytes\nvar buffer = forge.util.createBuffer(input, 'raw');\n// create a byte buffer from utf8 bytes\nvar buffer = forge.util.createBuffer(input, 'utf8');\n\n// get the length of the buffer in bytes\nbuffer.length();\n// put bytes into the buffer\nbuffer.putBytes(bytes);\n// put a 32-bit integer into the buffer\nbuffer.putInt32(10);\n// buffer to hex\nbuffer.toHex();\n// get a copy of the bytes in the buffer\nbytes.bytes(/* count */);\n// empty this buffer and get its contents\nbytes.getBytes(/* count */);\n\n// convert a forge buffer into a Node.js Buffer\n// make sure you specify the encoding as 'binary'\nvar forgeBuffer = forge.util.createBuffer();\nvar nodeBuffer = new Buffer(forgeBuffer.getBytes(), 'binary');\n\n// convert a Node.js Buffer into a forge buffer\n// make sure you specify the encoding as 'binary'\nvar nodeBuffer = new Buffer();\nvar forgeBuffer = forge.util.createBuffer(nodeBuffer.toString('binary'));\n\n// parse a URL\nvar parsed = forge.util.parseUrl('http://example.com/foo?bar=baz');\n// parsed.scheme, parsed.host, parsed.port, parsed.path, parsed.fullHost\n```\n\n<a name=\"log\" />\n### Logging\n\nProvides logging to a javascript console using various categories and\nlevels of verbosity.\n\n__Examples__\n\n```js\n// TODO\n```\n\n<a name=\"debug\" />\n### Debugging\n\nProvides storage of debugging information normally inaccessible in\nclosures for viewing/investigation.\n\n__Examples__\n\n```js\n// TODO\n```\n\n<a name=\"flash\" />\n### Flash Networking Support\n\nThe [flash README](./flash/README.md) provides details on rebuilding the\noptional Flash component used for networking. It also provides details on\nPolicy Server support.\n\nSecurity Considerations\n-----------------------\n\nWhen using this code please keep the following in mind:\n\n- Cryptography is hard. Please review and test this code before depending on it\n  for critical functionality.\n- The nature of JavaScript is that execution of this code depends on trusting a\n  very large set of JavaScript tools and systems. Consider runtime variations,\n  runtime characteristics, runtime optimization, code optimization, code\n  minimization, code obfuscation, bundling tools, possible bugs, the Forge code\n  itself, and so on.\n- If using pre-built bundles from [Bower][] or similar be aware someone else\n  ran the tools to create those files.\n- Use a secure transport channel such as [TLS][] to load scripts and consider\n  using additional security mechanisms such as [Subresource Integrity][] script\n  attributes.\n- Use \"native\" functionality where possible. This can be critical when dealing\n  with performance and random number generation. Note that the JavaScript\n  random number algorithms should perform well if given suitable entropy.\n- Understand possible attacks against cryptographic systems. For instance side\n  channel and timing attacks may be possible due to the difficulty in\n  implementing constant time algorithms in pure JavaScript.\n- Certain features in this library are less susceptible to attacks depending on\n  usage. This primarily includes features that deal with data format\n  manipulation or those that are not involved in communication.\n\nLibrary Background\n------------------\n\n* http://digitalbazaar.com/2010/07/20/javascript-tls-1/\n* http://digitalbazaar.com/2010/07/20/javascript-tls-2/\n\nContact\n-------\n\n* Code: https://github.com/digitalbazaar/forge\n* Bugs: https://github.com/digitalbazaar/forge/issues\n* Email: support@digitalbazaar.com\n* IRC: [#forgejs][] on [freenode][]\n\nDonations\n---------\n\nFinancial support is welcome and helps contribute to futher development:\n\n* For [PayPal][] please send to paypal@digitalbazaar.com.\n* Something else? Please contact support@digitalbazaar.com.\n\n[#forgejs]: https://webchat.freenode.net/?channels=#forgejs\n[0.6.x]: https://github.com/digitalbazaar/forge/tree/0.6.x\n[3DES]: http://en.wikipedia.org/wiki/Triple_DES\n[AES]: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard\n[ASN.1]: http://en.wikipedia.org/wiki/ASN.1\n[Bower]: https://bower.io/\n[Browserify]: http://browserify.org/\n[CBC]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation\n[CFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation\n[CTR]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation\n[CommonJS]: https://en.wikipedia.org/wiki/CommonJS\n[DES]: http://en.wikipedia.org/wiki/Data_Encryption_Standard\n[ECB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation\n[Fortuna]: http://en.wikipedia.org/wiki/Fortuna_(PRNG)\n[GCM]: http://en.wikipedia.org/wiki/GCM_mode\n[HMAC]: http://en.wikipedia.org/wiki/HMAC\n[JavaScript]: http://en.wikipedia.org/wiki/JavaScript\n[Karma]: https://karma-runner.github.io/\n[MD5]: http://en.wikipedia.org/wiki/MD5\n[Node.js]: http://nodejs.org/\n[OFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation\n[PKCS#10]: http://en.wikipedia.org/wiki/Certificate_signing_request\n[PKCS#12]: http://en.wikipedia.org/wiki/PKCS_%E2%99%AF12\n[PKCS#5]: http://en.wikipedia.org/wiki/PKCS\n[PKCS#7]: http://en.wikipedia.org/wiki/Cryptographic_Message_Syntax\n[PayPal]: https://www.paypal.com/\n[RC2]: http://en.wikipedia.org/wiki/RC2\n[SHA-1]: http://en.wikipedia.org/wiki/SHA-1\n[SHA-256]: http://en.wikipedia.org/wiki/SHA-256\n[SHA-384]: http://en.wikipedia.org/wiki/SHA-384\n[SHA-512]: http://en.wikipedia.org/wiki/SHA-512\n[Subresource Integrity]: https://www.w3.org/TR/SRI/\n[TLS]: http://en.wikipedia.org/wiki/Transport_Layer_Security\n[UMD]: https://github.com/umdjs/umd\n[X.509]: http://en.wikipedia.org/wiki/X.509\n[freenode]: https://freenode.net/\n[unpkg]: https://unpkg.com/\n[webpack]: https://webpack.github.io/\n",
  "readmeFilename": "README.md",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/digitalbazaar/forge.git"
  },
  "scripts": {
    "_jscs": "jscs *.js lib/*.js tests/*.js tests/unit/*.js tests/legacy/*.js tests/issues/*.js tests/websockets/*.js",
    "_jshint": "jshint *.js lib/*.js tests/*.js tests/unit/*.js tests/legacy/*.js tests/issues/*.js tests/websockets/*.js",
    "build": "webpack",
    "coverage": "rm -rf coverage && ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- -u exports -t 30000 -R spec tests/unit/index.js",
    "coverage-lcov": "rm -rf coverage && ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha --report lcovonly -- -u exports -t 30000 -R spec tests/unit/index.js",
    "coverage-report": "istanbul report",
    "jscs": "jscs *.js lib/*.js tests/*.js tests/unit/*.js tests/legacy/*.js tests/issues/*.js tests/websockets/*.js",
    "jshint": "jshint *.js lib/*.js tests/unit/*.js tests/legacy/*.js tests/issues/*.js tests/websockets/*.js",
    "prepublish": "npm run build",
    "test": "mocha -t 30000 -R spec tests/unit/index.js",
    "test-build": "webpack --config webpack-tests.config.js",
    "test-karma": "karma start",
    "test-karma-sauce": "karma start karma-sauce.conf",
    "test-server": "node tests/server.js",
    "test-server-webid": "node tests/websockets/server-webid.js",
    "test-server-ws": "node tests/websockets/server-ws.js"
  },
  "version": "0.7.1"
}
