项目原始demo,不改动
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095
  1. # Forge
  2. [![npm package](https://nodei.co/npm/node-forge.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/node-forge/)
  3. [![Build status](https://img.shields.io/travis/digitalbazaar/forge.svg?branch=master)](https://travis-ci.org/digitalbazaar/forge)
  4. A native implementation of [TLS][] (and various other cryptographic tools) in
  5. [JavaScript][].
  6. Introduction
  7. ------------
  8. The Forge software is a fully native implementation of the [TLS][] protocol
  9. in JavaScript, a set of cryptography utilities, and a set of tools for
  10. developing Web Apps that utilize many network resources.
  11. Performance
  12. ------------
  13. Forge is fast. Benchmarks against other popular JavaScript cryptography
  14. libraries can be found here:
  15. * http://dominictarr.github.io/crypto-bench/
  16. * http://cryptojs.altervista.org/test/simulate-threading-speed_test.html
  17. Documentation
  18. -------------
  19. * [Introduction](#introduction)
  20. * [Performance](#performance)
  21. * [Installation](#installation)
  22. * [Testing](#testing)
  23. * [Contributing](#contributing)
  24. ### API
  25. * [Options](#options)
  26. ### Transports
  27. * [TLS](#tls)
  28. * [HTTP](#http)
  29. * [SSH](#ssh)
  30. * [XHR](#xhr)
  31. * [Sockets](#socket)
  32. ### Ciphers
  33. * [CIPHER](#cipher)
  34. * [AES](#aes)
  35. * [DES](#des)
  36. * [RC2](#rc2)
  37. ### PKI
  38. * [ED25519](#ed25519)
  39. * [RSA](#rsa)
  40. * [RSA-KEM](#rsakem)
  41. * [X.509](#x509)
  42. * [PKCS#5](#pkcs5)
  43. * [PKCS#7](#pkcs7)
  44. * [PKCS#8](#pkcs8)
  45. * [PKCS#10](#pkcs10)
  46. * [PKCS#12](#pkcs12)
  47. * [ASN.1](#asn)
  48. ### Message Digests
  49. * [SHA1](#sha1)
  50. * [SHA256](#sha256)
  51. * [SHA384](#sha384)
  52. * [SHA512](#sha512)
  53. * [MD5](#md5)
  54. * [HMAC](#hmac)
  55. ### Utilities
  56. * [Prime](#prime)
  57. * [PRNG](#prng)
  58. * [Tasks](#task)
  59. * [Utilities](#util)
  60. * [Logging](#log)
  61. * [Debugging](#debug)
  62. * [Flash Networking Support](#flash)
  63. ### Other
  64. * [Security Considerations](#security-considerations)
  65. * [Library Background](#library-background)
  66. * [Contact](#contact)
  67. * [Donations](#donations)
  68. ---------------------------------------
  69. Installation
  70. ------------
  71. **Note**: Please see the [Security Considerations](#security-considerations)
  72. section before using packaging systems and pre-built files.
  73. Forge uses a [CommonJS][] module structure with a build process for browser
  74. bundles. The older [0.6.x][] branch with standalone files is available but will
  75. not be regularly updated.
  76. ### Node.js
  77. If you want to use forge with [Node.js][], it is available through `npm`:
  78. https://npmjs.org/package/node-forge
  79. Installation:
  80. npm install node-forge
  81. You can then use forge as a regular module:
  82. ```js
  83. var forge = require('node-forge');
  84. ```
  85. The npm package includes pre-built `forge.min.js`, `forge.all.min.js`, and
  86. `prime.worker.min.js` using the [UMD][] format.
  87. ### Bundle / Bower
  88. Each release is published in a separate repository as pre-built and minimized
  89. basic forge bundles using the [UMD][] format.
  90. https://github.com/digitalbazaar/forge-dist
  91. This bundle can be used in many environments. In particular it can be installed
  92. with [Bower][]:
  93. bower install forge
  94. ### jsDelivr CDN
  95. To use it via [jsDelivr](https://www.jsdelivr.com/package/npm/node-forge) include this in your html:
  96. ```html
  97. <script src="https://cdn.jsdelivr.net/npm/node-forge@0.7.0/dist/forge.min.js"></script>
  98. ```
  99. ### unpkg CDN
  100. To use it via [unpkg](https://unpkg.com/#/) include this in your html:
  101. ```html
  102. <script src="https://unpkg.com/node-forge@0.7.0/dist/forge.min.js"></script>
  103. ```
  104. ### Development Requirements
  105. The core JavaScript has the following requirements to build and test:
  106. * Building a browser bundle:
  107. * Node.js
  108. * npm
  109. * Testing
  110. * Node.js
  111. * npm
  112. * Chrome, Firefox, Safari (optional)
  113. Some special networking features can optionally use a Flash component. See the
  114. [Flash README](./flash/README.md) for details.
  115. ### Building for a web browser
  116. To create single file bundles for use with browsers run the following:
  117. npm install
  118. npm run build
  119. This will create single non-minimized and minimized files that can be
  120. included in the browser:
  121. dist/forge.js
  122. dist/forge.min.js
  123. A bundle that adds some utilities and networking support is also available:
  124. dist/forge.all.js
  125. dist/forge.all.min.js
  126. Include the file via:
  127. ```html
  128. <script src="YOUR_SCRIPT_PATH/forge.js"></script>
  129. ```
  130. or
  131. ```html
  132. <script src="YOUR_SCRIPT_PATH/forge.min.js"></script>
  133. ```
  134. The above bundles will synchronously create a global 'forge' object.
  135. **Note**: These bundles will not include any WebWorker scripts (eg:
  136. `dist/prime.worker.js`), so these will need to be accessible from the browser
  137. if any WebWorkers are used.
  138. ### Building a custom browser bundle
  139. The build process uses [webpack][] and the [config](./webpack.config.js) file
  140. can be modified to generate a file or files that only contain the parts of
  141. forge you need.
  142. [Browserify][] override support is also present in `package.json`.
  143. Testing
  144. -------
  145. See the [testing README](./tests/README.md) for full details.
  146. ### Prepare to run tests
  147. npm install
  148. ### Running automated tests with Node.js
  149. Forge natively runs in a [Node.js][] environment:
  150. npm test
  151. ### Running automated tests with PhantomJS
  152. Automated testing is done via [Karma][]. By default it will run the tests in a
  153. headless manner with PhantomJS.
  154. npm run test-karma
  155. Is 'mocha' reporter output too verbose? Other reporters are available. Try
  156. 'dots', 'progress', or 'tap'.
  157. npm run test-karma -- --reporters progress
  158. By default [webpack][] is used. [Browserify][] can also be used.
  159. BUNDLER=browserify npm run test-karma
  160. ### Running automated tests with one or more browsers
  161. You can also specify one or more browsers to use.
  162. npm run test-karma -- --browsers Chrome,Firefox,Safari,PhantomJS
  163. The reporter option and `BUNDLER` environment variable can also be used.
  164. ### Running manual tests in a browser
  165. Testing in a browser uses [webpack][] to combine forge and all tests and then
  166. loading the result in a browser. A simple web server is provided that will
  167. output the HTTP or HTTPS URLs to load. It also will start a simple Flash Policy
  168. Server. Unit tests and older legacy tests are provided. Custom ports can be
  169. used by running `node tests/server.js` manually.
  170. To run the unit tests in a browser a special forge build is required:
  171. npm run test-build
  172. To run legacy browser based tests the main forge build is required:
  173. npm run build
  174. The tests are run with a custom server that prints out the URLs to use:
  175. npm run test-server
  176. ### Running other tests
  177. There are some other random tests and benchmarks available in the tests
  178. directory.
  179. ### Coverage testing
  180. To perform coverage testing of the unit tests, run the following. The results
  181. will be put in the `coverage/` directory. Note that coverage testing can slow
  182. down some tests considerably.
  183. npm install
  184. npm run coverage
  185. Contributing
  186. ------------
  187. Any contributions (eg: PRs) that are accepted will be brought under the same
  188. license used by the rest of the Forge project. This license allows Forge to
  189. be used under the terms of either the BSD License or the GNU General Public
  190. License (GPL) Version 2.
  191. See: [LICENSE](https://github.com/digitalbazaar/forge/blob/cbebca3780658703d925b61b2caffb1d263a6c1d/LICENSE)
  192. If a contribution contains 3rd party source code with its own license, it
  193. may retain it, so long as that license is compatible with the Forge license.
  194. API
  195. ---
  196. <a name="options" />
  197. ### Options
  198. If at any time you wish to disable the use of native code, where available,
  199. for particular forge features like its secure random number generator, you
  200. may set the ```forge.options.usePureJavaScript``` flag to ```true```. It is
  201. not recommended that you set this flag as native code is typically more
  202. performant and may have stronger security properties. It may be useful to
  203. set this flag to test certain features that you plan to run in environments
  204. that are different from your testing environment.
  205. To disable native code when including forge in the browser:
  206. ```js
  207. // run this *after* including the forge script
  208. forge.options.usePureJavaScript = true;
  209. ```
  210. To disable native code when using Node.js:
  211. ```js
  212. var forge = require('node-forge');
  213. forge.options.usePureJavaScript = true;
  214. ```
  215. Transports
  216. ----------
  217. <a name="tls" />
  218. ### TLS
  219. Provides a native javascript client and server-side [TLS][] implementation.
  220. __Examples__
  221. ```js
  222. // create TLS client
  223. var client = forge.tls.createConnection({
  224. server: false,
  225. caStore: /* Array of PEM-formatted certs or a CA store object */,
  226. sessionCache: {},
  227. // supported cipher suites in order of preference
  228. cipherSuites: [
  229. forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
  230. forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
  231. virtualHost: 'example.com',
  232. verify: function(connection, verified, depth, certs) {
  233. if(depth === 0) {
  234. var cn = certs[0].subject.getField('CN').value;
  235. if(cn !== 'example.com') {
  236. verified = {
  237. alert: forge.tls.Alert.Description.bad_certificate,
  238. message: 'Certificate common name does not match hostname.'
  239. };
  240. }
  241. }
  242. return verified;
  243. },
  244. connected: function(connection) {
  245. console.log('connected');
  246. // send message to server
  247. connection.prepare(forge.util.encodeUtf8('Hi server!'));
  248. /* NOTE: experimental, start heartbeat retransmission timer
  249. myHeartbeatTimer = setInterval(function() {
  250. connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
  251. }, 5*60*1000);*/
  252. },
  253. /* provide a client-side cert if you want
  254. getCertificate: function(connection, hint) {
  255. return myClientCertificate;
  256. },
  257. /* the private key for the client-side cert if provided */
  258. getPrivateKey: function(connection, cert) {
  259. return myClientPrivateKey;
  260. },
  261. tlsDataReady: function(connection) {
  262. // TLS data (encrypted) is ready to be sent to the server
  263. sendToServerSomehow(connection.tlsData.getBytes());
  264. // if you were communicating with the server below, you'd do:
  265. // server.process(connection.tlsData.getBytes());
  266. },
  267. dataReady: function(connection) {
  268. // clear data from the server is ready
  269. console.log('the server sent: ' +
  270. forge.util.decodeUtf8(connection.data.getBytes()));
  271. // close connection
  272. connection.close();
  273. },
  274. /* NOTE: experimental
  275. heartbeatReceived: function(connection, payload) {
  276. // restart retransmission timer, look at payload
  277. clearInterval(myHeartbeatTimer);
  278. myHeartbeatTimer = setInterval(function() {
  279. connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
  280. }, 5*60*1000);
  281. payload.getBytes();
  282. },*/
  283. closed: function(connection) {
  284. console.log('disconnected');
  285. },
  286. error: function(connection, error) {
  287. console.log('uh oh', error);
  288. }
  289. });
  290. // start the handshake process
  291. client.handshake();
  292. // when encrypted TLS data is received from the server, process it
  293. client.process(encryptedBytesFromServer);
  294. // create TLS server
  295. var server = forge.tls.createConnection({
  296. server: true,
  297. caStore: /* Array of PEM-formatted certs or a CA store object */,
  298. sessionCache: {},
  299. // supported cipher suites in order of preference
  300. cipherSuites: [
  301. forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
  302. forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
  303. // require a client-side certificate if you want
  304. verifyClient: true,
  305. verify: function(connection, verified, depth, certs) {
  306. if(depth === 0) {
  307. var cn = certs[0].subject.getField('CN').value;
  308. if(cn !== 'the-client') {
  309. verified = {
  310. alert: forge.tls.Alert.Description.bad_certificate,
  311. message: 'Certificate common name does not match expected client.'
  312. };
  313. }
  314. }
  315. return verified;
  316. },
  317. connected: function(connection) {
  318. console.log('connected');
  319. // send message to client
  320. connection.prepare(forge.util.encodeUtf8('Hi client!'));
  321. /* NOTE: experimental, start heartbeat retransmission timer
  322. myHeartbeatTimer = setInterval(function() {
  323. connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
  324. }, 5*60*1000);*/
  325. },
  326. getCertificate: function(connection, hint) {
  327. return myServerCertificate;
  328. },
  329. getPrivateKey: function(connection, cert) {
  330. return myServerPrivateKey;
  331. },
  332. tlsDataReady: function(connection) {
  333. // TLS data (encrypted) is ready to be sent to the client
  334. sendToClientSomehow(connection.tlsData.getBytes());
  335. // if you were communicating with the client above you'd do:
  336. // client.process(connection.tlsData.getBytes());
  337. },
  338. dataReady: function(connection) {
  339. // clear data from the client is ready
  340. console.log('the client sent: ' +
  341. forge.util.decodeUtf8(connection.data.getBytes()));
  342. // close connection
  343. connection.close();
  344. },
  345. /* NOTE: experimental
  346. heartbeatReceived: function(connection, payload) {
  347. // restart retransmission timer, look at payload
  348. clearInterval(myHeartbeatTimer);
  349. myHeartbeatTimer = setInterval(function() {
  350. connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
  351. }, 5*60*1000);
  352. payload.getBytes();
  353. },*/
  354. closed: function(connection) {
  355. console.log('disconnected');
  356. },
  357. error: function(connection, error) {
  358. console.log('uh oh', error);
  359. }
  360. });
  361. // when encrypted TLS data is received from the client, process it
  362. server.process(encryptedBytesFromClient);
  363. ```
  364. Connect to a TLS server using node's net.Socket:
  365. ```js
  366. var socket = new net.Socket();
  367. var client = forge.tls.createConnection({
  368. server: false,
  369. verify: function(connection, verified, depth, certs) {
  370. // skip verification for testing
  371. console.log('[tls] server certificate verified');
  372. return true;
  373. },
  374. connected: function(connection) {
  375. console.log('[tls] connected');
  376. // prepare some data to send (note that the string is interpreted as
  377. // 'binary' encoded, which works for HTTP which only uses ASCII, use
  378. // forge.util.encodeUtf8(str) otherwise
  379. client.prepare('GET / HTTP/1.0\r\n\r\n');
  380. },
  381. tlsDataReady: function(connection) {
  382. // encrypted data is ready to be sent to the server
  383. var data = connection.tlsData.getBytes();
  384. socket.write(data, 'binary'); // encoding should be 'binary'
  385. },
  386. dataReady: function(connection) {
  387. // clear data from the server is ready
  388. var data = connection.data.getBytes();
  389. console.log('[tls] data received from the server: ' + data);
  390. },
  391. closed: function() {
  392. console.log('[tls] disconnected');
  393. },
  394. error: function(connection, error) {
  395. console.log('[tls] error', error);
  396. }
  397. });
  398. socket.on('connect', function() {
  399. console.log('[socket] connected');
  400. client.handshake();
  401. });
  402. socket.on('data', function(data) {
  403. client.process(data.toString('binary')); // encoding should be 'binary'
  404. });
  405. socket.on('end', function() {
  406. console.log('[socket] disconnected');
  407. });
  408. // connect to google.com
  409. socket.connect(443, 'google.com');
  410. // or connect to gmail's imap server (but don't send the HTTP header above)
  411. //socket.connect(993, 'imap.gmail.com');
  412. ```
  413. <a name="http" />
  414. ### HTTP
  415. Provides a native [JavaScript][] mini-implementation of an http client that
  416. uses pooled sockets.
  417. __Examples__
  418. ```js
  419. // create an HTTP GET request
  420. var request = forge.http.createRequest({method: 'GET', path: url.path});
  421. // send the request somewhere
  422. sendSomehow(request.toString());
  423. // receive response
  424. var buffer = forge.util.createBuffer();
  425. var response = forge.http.createResponse();
  426. var someAsyncDataHandler = function(bytes) {
  427. if(!response.bodyReceived) {
  428. buffer.putBytes(bytes);
  429. if(!response.headerReceived) {
  430. if(response.readHeader(buffer)) {
  431. console.log('HTTP response header: ' + response.toString());
  432. }
  433. }
  434. if(response.headerReceived && !response.bodyReceived) {
  435. if(response.readBody(buffer)) {
  436. console.log('HTTP response body: ' + response.body);
  437. }
  438. }
  439. }
  440. };
  441. ```
  442. <a name="ssh" />
  443. ### SSH
  444. Provides some SSH utility functions.
  445. __Examples__
  446. ```js
  447. // encodes (and optionally encrypts) a private RSA key as a Putty PPK file
  448. forge.ssh.privateKeyToPutty(privateKey, passphrase, comment);
  449. // encodes a public RSA key as an OpenSSH file
  450. forge.ssh.publicKeyToOpenSSH(key, comment);
  451. // encodes a private RSA key as an OpenSSH file
  452. forge.ssh.privateKeyToOpenSSH(privateKey, passphrase);
  453. // gets the SSH public key fingerprint in a byte buffer
  454. forge.ssh.getPublicKeyFingerprint(key);
  455. // gets a hex-encoded, colon-delimited SSH public key fingerprint
  456. forge.ssh.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'});
  457. ```
  458. <a name="xhr" />
  459. ### XHR
  460. Provides an XmlHttpRequest implementation using forge.http as a backend.
  461. __Examples__
  462. ```js
  463. // TODO
  464. ```
  465. <a name="socket" />
  466. ### Sockets
  467. Provides an interface to create and use raw sockets provided via Flash.
  468. __Examples__
  469. ```js
  470. // TODO
  471. ```
  472. Ciphers
  473. -------
  474. <a name="cipher" />
  475. ### CIPHER
  476. Provides a basic API for block encryption and decryption. There is built-in
  477. support for the ciphers: [AES][], [3DES][], and [DES][], and for the modes
  478. of operation: [ECB][], [CBC][], [CFB][], [OFB][], [CTR][], and [GCM][].
  479. These algorithms are currently supported:
  480. * AES-ECB
  481. * AES-CBC
  482. * AES-CFB
  483. * AES-OFB
  484. * AES-CTR
  485. * AES-GCM
  486. * 3DES-ECB
  487. * 3DES-CBC
  488. * DES-ECB
  489. * DES-CBC
  490. When using an [AES][] algorithm, the key size will determine whether
  491. AES-128, AES-192, or AES-256 is used (all are supported). When a [DES][]
  492. algorithm is used, the key size will determine whether [3DES][] or regular
  493. [DES][] is used. Use a [3DES][] algorithm to enforce Triple-DES.
  494. __Examples__
  495. ```js
  496. // generate a random key and IV
  497. // Note: a key size of 16 bytes will use AES-128, 24 => AES-192, 32 => AES-256
  498. var key = forge.random.getBytesSync(16);
  499. var iv = forge.random.getBytesSync(16);
  500. /* alternatively, generate a password-based 16-byte key
  501. var salt = forge.random.getBytesSync(128);
  502. var key = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);
  503. */
  504. // encrypt some bytes using CBC mode
  505. // (other modes include: ECB, CFB, OFB, CTR, and GCM)
  506. // Note: CBC and ECB modes use PKCS#7 padding as default
  507. var cipher = forge.cipher.createCipher('AES-CBC', key);
  508. cipher.start({iv: iv});
  509. cipher.update(forge.util.createBuffer(someBytes));
  510. cipher.finish();
  511. var encrypted = cipher.output;
  512. // outputs encrypted hex
  513. console.log(encrypted.toHex());
  514. // decrypt some bytes using CBC mode
  515. // (other modes include: CFB, OFB, CTR, and GCM)
  516. var decipher = forge.cipher.createDecipher('AES-CBC', key);
  517. decipher.start({iv: iv});
  518. decipher.update(encrypted);
  519. var result = decipher.finish(); // check 'result' for true/false
  520. // outputs decrypted hex
  521. console.log(decipher.output.toHex());
  522. // decrypt bytes using CBC mode and streaming
  523. // Performance can suffer for large multi-MB inputs due to buffer
  524. // manipulations. Stream processing in chunks can offer significant
  525. // improvement. CPU intensive update() calls could also be performed with
  526. // setImmediate/setTimeout to avoid blocking the main browser UI thread (not
  527. // shown here). Optimal block size depends on the JavaScript VM and other
  528. // factors. Encryption can use a simple technique for increased performance.
  529. var encryptedBytes = encrypted.bytes();
  530. var decipher = forge.cipher.createDecipher('AES-CBC', key);
  531. decipher.start({iv: iv});
  532. var length = encryptedBytes.length;
  533. var chunkSize = 1024 * 64;
  534. var index = 0;
  535. var decrypted = '';
  536. do {
  537. decrypted += decipher.output.getBytes();
  538. var buf = forge.util.createBuffer(encryptedBytes.substr(index, chunkSize));
  539. decipher.update(buf);
  540. index += chunkSize;
  541. } while(index < length);
  542. var result = decipher.finish();
  543. assert(result);
  544. decrypted += decipher.output.getBytes();
  545. console.log(forge.util.bytesToHex(decrypted));
  546. // encrypt some bytes using GCM mode
  547. var cipher = forge.cipher.createCipher('AES-GCM', key);
  548. cipher.start({
  549. iv: iv, // should be a 12-byte binary-encoded string or byte buffer
  550. additionalData: 'binary-encoded string', // optional
  551. tagLength: 128 // optional, defaults to 128 bits
  552. });
  553. cipher.update(forge.util.createBuffer(someBytes));
  554. cipher.finish();
  555. var encrypted = cipher.output;
  556. var tag = cipher.mode.tag;
  557. // outputs encrypted hex
  558. console.log(encrypted.toHex());
  559. // outputs authentication tag
  560. console.log(tag.toHex());
  561. // decrypt some bytes using GCM mode
  562. var decipher = forge.cipher.createDecipher('AES-GCM', key);
  563. decipher.start({
  564. iv: iv,
  565. additionalData: 'binary-encoded string', // optional
  566. tagLength: 128, // optional, defaults to 128 bits
  567. tag: tag // authentication tag from encryption
  568. });
  569. decipher.update(encrypted);
  570. var pass = decipher.finish();
  571. // pass is false if there was a failure (eg: authentication tag didn't match)
  572. if(pass) {
  573. // outputs decrypted hex
  574. console.log(decipher.output.toHex());
  575. }
  576. ```
  577. Using 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/)):
  578. ```js
  579. var forge = require('node-forge');
  580. var fs = require('fs');
  581. // openssl enc -des3 -in input.txt -out input.enc
  582. function encrypt(password) {
  583. var input = fs.readFileSync('input.txt', {encoding: 'binary'});
  584. // 3DES key and IV sizes
  585. var keySize = 24;
  586. var ivSize = 8;
  587. // get derived bytes
  588. // Notes:
  589. // 1. If using an alternative hash (eg: "-md sha1") pass
  590. // "forge.md.sha1.create()" as the final parameter.
  591. // 2. If using "-nosalt", set salt to null.
  592. var salt = forge.random.getBytesSync(8);
  593. // var md = forge.md.sha1.create(); // "-md sha1"
  594. var derivedBytes = forge.pbe.opensslDeriveBytes(
  595. password, salt, keySize + ivSize/*, md*/);
  596. var buffer = forge.util.createBuffer(derivedBytes);
  597. var key = buffer.getBytes(keySize);
  598. var iv = buffer.getBytes(ivSize);
  599. var cipher = forge.cipher.createCipher('3DES-CBC', key);
  600. cipher.start({iv: iv});
  601. cipher.update(forge.util.createBuffer(input, 'binary'));
  602. cipher.finish();
  603. var output = forge.util.createBuffer();
  604. // if using a salt, prepend this to the output:
  605. if(salt !== null) {
  606. output.putBytes('Salted__'); // (add to match openssl tool output)
  607. output.putBytes(salt);
  608. }
  609. output.putBuffer(cipher.output);
  610. fs.writeFileSync('input.enc', output.getBytes(), {encoding: 'binary'});
  611. }
  612. // openssl enc -d -des3 -in input.enc -out input.dec.txt
  613. function decrypt(password) {
  614. var input = fs.readFileSync('input.enc', {encoding: 'binary'});
  615. // parse salt from input
  616. input = forge.util.createBuffer(input, 'binary');
  617. // skip "Salted__" (if known to be present)
  618. input.getBytes('Salted__'.length);
  619. // read 8-byte salt
  620. var salt = input.getBytes(8);
  621. // Note: if using "-nosalt", skip above parsing and use
  622. // var salt = null;
  623. // 3DES key and IV sizes
  624. var keySize = 24;
  625. var ivSize = 8;
  626. var derivedBytes = forge.pbe.opensslDeriveBytes(
  627. password, salt, keySize + ivSize);
  628. var buffer = forge.util.createBuffer(derivedBytes);
  629. var key = buffer.getBytes(keySize);
  630. var iv = buffer.getBytes(ivSize);
  631. var decipher = forge.cipher.createDecipher('3DES-CBC', key);
  632. decipher.start({iv: iv});
  633. decipher.update(input);
  634. var result = decipher.finish(); // check 'result' for true/false
  635. fs.writeFileSync(
  636. 'input.dec.txt', decipher.output.getBytes(), {encoding: 'binary'});
  637. }
  638. ```
  639. <a name="aes" />
  640. ### AES
  641. Provides [AES][] encryption and decryption in [CBC][], [CFB][], [OFB][],
  642. [CTR][], and [GCM][] modes. See [CIPHER](#cipher) for examples.
  643. <a name="des" />
  644. ### DES
  645. Provides [3DES][] and [DES][] encryption and decryption in [ECB][] and
  646. [CBC][] modes. See [CIPHER](#cipher) for examples.
  647. <a name="rc2" />
  648. ### RC2
  649. __Examples__
  650. ```js
  651. // generate a random key and IV
  652. var key = forge.random.getBytesSync(16);
  653. var iv = forge.random.getBytesSync(8);
  654. // encrypt some bytes
  655. var cipher = forge.rc2.createEncryptionCipher(key);
  656. cipher.start(iv);
  657. cipher.update(forge.util.createBuffer(someBytes));
  658. cipher.finish();
  659. var encrypted = cipher.output;
  660. // outputs encrypted hex
  661. console.log(encrypted.toHex());
  662. // decrypt some bytes
  663. var cipher = forge.rc2.createDecryptionCipher(key);
  664. cipher.start(iv);
  665. cipher.update(encrypted);
  666. cipher.finish();
  667. // outputs decrypted hex
  668. console.log(cipher.output.toHex());
  669. ```
  670. PKI
  671. ---
  672. Provides [X.509][] certificate support, ED25519 key generation and
  673. signing/verifying, and RSA public and private key encoding, decoding,
  674. encryption/decryption, and signing/verifying.
  675. <a name="ed25519" />
  676. ### ED25519
  677. Special thanks to [TweetNaCl.js][] for providing the bulk of the implementation.
  678. __Examples__
  679. ```js
  680. var ed25519 = forge.pki.ed25519;
  681. // generate a random ED25519 keypair
  682. var keypair = ed25519.generateKeyPair();
  683. // `keypair.publicKey` is a node.js Buffer or Uint8Array
  684. // `keypair.privateKey` is a node.js Buffer or Uint8Array
  685. // generate a random ED25519 keypair based on a random 32-byte seed
  686. var seed = forge.random.getBytesSync(32);
  687. var keypair = ed25519.generateKeyPair({seed: seed});
  688. // generate a random ED25519 keypair based on a "password" 32-byte seed
  689. var password = 'Mai9ohgh6ahxee0jutheew0pungoozil';
  690. var seed = new forge.util.ByteBuffer(password, 'utf8');
  691. var keypair = ed25519.generateKeyPair({seed: seed});
  692. // sign a UTF-8 message
  693. var signature = ED25519.sign({
  694. message: 'test',
  695. // also accepts `binary` if you want to pass a binary string
  696. encoding: 'utf8',
  697. // node.js Buffer, Uint8Array, forge ByteBuffer, binary string
  698. privateKey: privateKey
  699. });
  700. // `signature` is a node.js Buffer or Uint8Array
  701. // sign a message passed as a buffer
  702. var signature = ED25519.sign({
  703. // also accepts a forge ByteBuffer or Uint8Array
  704. message: new Buffer('test', 'utf8'),
  705. privateKey: privateKey
  706. });
  707. // sign a message digest (shorter "message" == better performance)
  708. var md = forge.md.sha256.create();
  709. md.update('test', 'utf8');
  710. var signature = ED25519.sign({
  711. md: md,
  712. privateKey: privateKey
  713. });
  714. // verify a signature on a UTF-8 message
  715. var verified = ED25519.verify({
  716. message: 'test',
  717. encoding: 'utf8',
  718. // node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
  719. signature: signature,
  720. // node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
  721. publicKey: publicKey
  722. });
  723. // `verified` is true/false
  724. // sign a message passed as a buffer
  725. var verified = ED25519.verify({
  726. // also accepts a forge ByteBuffer or Uint8Array
  727. message: new Buffer('test', 'utf8'),
  728. // node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
  729. signature: signature,
  730. // node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
  731. publicKey: publicKey
  732. });
  733. // verify a signature on a message digest
  734. var md = forge.md.sha256.create();
  735. md.update('test', 'utf8');
  736. var verified = ED25519.verify({
  737. md: md,
  738. // node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
  739. signature: signature,
  740. // node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
  741. publicKey: publicKey
  742. });
  743. ```
  744. <a name="rsa" />
  745. ### RSA
  746. __Examples__
  747. ```js
  748. var rsa = forge.pki.rsa;
  749. // generate an RSA key pair synchronously
  750. // *NOT RECOMMENDED* -- can be significantly slower than async and will not
  751. // use native APIs if available.
  752. var keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001});
  753. // generate an RSA key pair asynchronously (uses web workers if available)
  754. // use workers: -1 to run a fast core estimator to optimize # of workers
  755. // *RECOMMENDED* - can be significantly faster than sync -- and will use
  756. // native APIs if available.
  757. rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) {
  758. // keypair.privateKey, keypair.publicKey
  759. });
  760. // generate an RSA key pair in steps that attempt to run for a specified period
  761. // of time on the main JS thread
  762. var state = rsa.createKeyPairGenerationState(2048, 0x10001);
  763. var step = function() {
  764. // run for 100 ms
  765. if(!rsa.stepKeyPairGenerationState(state, 100)) {
  766. setTimeout(step, 1);
  767. }
  768. else {
  769. // done, turn off progress indicator, use state.keys
  770. }
  771. };
  772. // turn on progress indicator, schedule generation to run
  773. setTimeout(step);
  774. // sign data with a private key and output DigestInfo DER-encoded bytes
  775. // (defaults to RSASSA PKCS#1 v1.5)
  776. var md = forge.md.sha1.create();
  777. md.update('sign this', 'utf8');
  778. var signature = privateKey.sign(md);
  779. // verify data with a public key
  780. // (defaults to RSASSA PKCS#1 v1.5)
  781. var verified = publicKey.verify(md.digest().bytes(), signature);
  782. // sign data using RSASSA-PSS where PSS uses a SHA-1 hash, a SHA-1 based
  783. // masking function MGF1, and a 20 byte salt
  784. var md = forge.md.sha1.create();
  785. md.update('sign this', 'utf8');
  786. var pss = forge.pss.create({
  787. md: forge.md.sha1.create(),
  788. mgf: forge.mgf.mgf1.create(forge.md.sha1.create()),
  789. saltLength: 20
  790. // optionally pass 'prng' with a custom PRNG implementation
  791. // optionalls pass 'salt' with a forge.util.ByteBuffer w/custom salt
  792. });
  793. var signature = privateKey.sign(md, pss);
  794. // verify RSASSA-PSS signature
  795. var pss = forge.pss.create({
  796. md: forge.md.sha1.create(),
  797. mgf: forge.mgf.mgf1.create(forge.md.sha1.create()),
  798. saltLength: 20
  799. // optionally pass 'prng' with a custom PRNG implementation
  800. });
  801. var md = forge.md.sha1.create();
  802. md.update('sign this', 'utf8');
  803. publicKey.verify(md.digest().getBytes(), signature, pss);
  804. // encrypt data with a public key (defaults to RSAES PKCS#1 v1.5)
  805. var encrypted = publicKey.encrypt(bytes);
  806. // decrypt data with a private key (defaults to RSAES PKCS#1 v1.5)
  807. var decrypted = privateKey.decrypt(encrypted);
  808. // encrypt data with a public key using RSAES PKCS#1 v1.5
  809. var encrypted = publicKey.encrypt(bytes, 'RSAES-PKCS1-V1_5');
  810. // decrypt data with a private key using RSAES PKCS#1 v1.5
  811. var decrypted = privateKey.decrypt(encrypted, 'RSAES-PKCS1-V1_5');
  812. // encrypt data with a public key using RSAES-OAEP
  813. var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP');
  814. // decrypt data with a private key using RSAES-OAEP
  815. var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP');
  816. // encrypt data with a public key using RSAES-OAEP/SHA-256
  817. var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', {
  818. md: forge.md.sha256.create()
  819. });
  820. // decrypt data with a private key using RSAES-OAEP/SHA-256
  821. var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', {
  822. md: forge.md.sha256.create()
  823. });
  824. // encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1
  825. // compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
  826. var encrypted = publicKey.encrypt(bytes, 'RSA-OAEP', {
  827. md: forge.md.sha256.create(),
  828. mgf1: {
  829. md: forge.md.sha1.create()
  830. }
  831. });
  832. // decrypt data with a private key using RSAES-OAEP/SHA-256/MGF1-SHA-1
  833. // compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
  834. var decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP', {
  835. md: forge.md.sha256.create(),
  836. mgf1: {
  837. md: forge.md.sha1.create()
  838. }
  839. });
  840. ```
  841. <a name="rsakem" />
  842. ### RSA-KEM
  843. __Examples__
  844. ```js
  845. // generate an RSA key pair asynchronously (uses web workers if available)
  846. // use workers: -1 to run a fast core estimator to optimize # of workers
  847. forge.rsa.generateKeyPair({bits: 2048, workers: -1}, function(err, keypair) {
  848. // keypair.privateKey, keypair.publicKey
  849. });
  850. // generate and encapsulate a 16-byte secret key
  851. var kdf1 = new forge.kem.kdf1(forge.md.sha1.create());
  852. var kem = forge.kem.rsa.create(kdf1);
  853. var result = kem.encrypt(keypair.publicKey, 16);
  854. // result has 'encapsulation' and 'key'
  855. // encrypt some bytes
  856. var iv = forge.random.getBytesSync(12);
  857. var someBytes = 'hello world!';
  858. var cipher = forge.cipher.createCipher('AES-GCM', result.key);
  859. cipher.start({iv: iv});
  860. cipher.update(forge.util.createBuffer(someBytes));
  861. cipher.finish();
  862. var encrypted = cipher.output.getBytes();
  863. var tag = cipher.mode.tag.getBytes();
  864. // send 'encrypted', 'iv', 'tag', and result.encapsulation to recipient
  865. // decrypt encapsulated 16-byte secret key
  866. var kdf1 = new forge.kem.kdf1(forge.md.sha1.create());
  867. var kem = forge.kem.rsa.create(kdf1);
  868. var key = kem.decrypt(keypair.privateKey, result.encapsulation, 16);
  869. // decrypt some bytes
  870. var decipher = forge.cipher.createDecipher('AES-GCM', key);
  871. decipher.start({iv: iv, tag: tag});
  872. decipher.update(forge.util.createBuffer(encrypted));
  873. var pass = decipher.finish();
  874. // pass is false if there was a failure (eg: authentication tag didn't match)
  875. if(pass) {
  876. // outputs 'hello world!'
  877. console.log(decipher.output.getBytes());
  878. }
  879. ```
  880. <a name="x509" />
  881. ### X.509
  882. __Examples__
  883. ```js
  884. var pki = forge.pki;
  885. // convert a PEM-formatted public key to a Forge public key
  886. var publicKey = pki.publicKeyFromPem(pem);
  887. // convert a Forge public key to PEM-format
  888. var pem = pki.publicKeyToPem(publicKey);
  889. // convert an ASN.1 SubjectPublicKeyInfo to a Forge public key
  890. var publicKey = pki.publicKeyFromAsn1(subjectPublicKeyInfo);
  891. // convert a Forge public key to an ASN.1 SubjectPublicKeyInfo
  892. var subjectPublicKeyInfo = pki.publicKeyToAsn1(publicKey);
  893. // gets a SHA-1 RSAPublicKey fingerprint a byte buffer
  894. pki.getPublicKeyFingerprint(key);
  895. // gets a SHA-1 SubjectPublicKeyInfo fingerprint a byte buffer
  896. pki.getPublicKeyFingerprint(key, {type: 'SubjectPublicKeyInfo'});
  897. // gets a hex-encoded, colon-delimited SHA-1 RSAPublicKey public key fingerprint
  898. pki.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'});
  899. // gets a hex-encoded, colon-delimited SHA-1 SubjectPublicKeyInfo public key fingerprint
  900. pki.getPublicKeyFingerprint(key, {
  901. type: 'SubjectPublicKeyInfo',
  902. encoding: 'hex',
  903. delimiter: ':'
  904. });
  905. // gets a hex-encoded, colon-delimited MD5 RSAPublicKey public key fingerprint
  906. pki.getPublicKeyFingerprint(key, {
  907. md: forge.md.md5.create(),
  908. encoding: 'hex',
  909. delimiter: ':'
  910. });
  911. // creates a CA store
  912. var caStore = pki.createCaStore([/* PEM-encoded cert */, ...]);
  913. // add a certificate to the CA store
  914. caStore.addCertificate(certObjectOrPemString);
  915. // gets the issuer (its certificate) for the given certificate
  916. var issuerCert = caStore.getIssuer(subjectCert);
  917. // verifies a certificate chain against a CA store
  918. pki.verifyCertificateChain(caStore, chain, customVerifyCallback);
  919. // signs a certificate using the given private key
  920. cert.sign(privateKey);
  921. // signs a certificate using SHA-256 instead of SHA-1
  922. cert.sign(privateKey, forge.md.sha256.create());
  923. // verifies an issued certificate using the certificates public key
  924. var verified = issuer.verify(issued);
  925. // generate a keypair and create an X.509v3 certificate
  926. var keys = pki.rsa.generateKeyPair(2048);
  927. var cert = pki.createCertificate();
  928. cert.publicKey = keys.publicKey;
  929. // alternatively set public key from a csr
  930. //cert.publicKey = csr.publicKey;
  931. // NOTE: serialNumber is the hex encoded value of an ASN.1 INTEGER.
  932. // Conforming CAs should ensure serialNumber is:
  933. // - no more than 20 octets
  934. // - non-negative (prefix a '00' if your value starts with a '1' bit)
  935. cert.serialNumber = '01';
  936. cert.validity.notBefore = new Date();
  937. cert.validity.notAfter = new Date();
  938. cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
  939. var attrs = [{
  940. name: 'commonName',
  941. value: 'example.org'
  942. }, {
  943. name: 'countryName',
  944. value: 'US'
  945. }, {
  946. shortName: 'ST',
  947. value: 'Virginia'
  948. }, {
  949. name: 'localityName',
  950. value: 'Blacksburg'
  951. }, {
  952. name: 'organizationName',
  953. value: 'Test'
  954. }, {
  955. shortName: 'OU',
  956. value: 'Test'
  957. }];
  958. cert.setSubject(attrs);
  959. // alternatively set subject from a csr
  960. //cert.setSubject(csr.subject.attributes);
  961. cert.setIssuer(attrs);
  962. cert.setExtensions([{
  963. name: 'basicConstraints',
  964. cA: true
  965. }, {
  966. name: 'keyUsage',
  967. keyCertSign: true,
  968. digitalSignature: true,
  969. nonRepudiation: true,
  970. keyEncipherment: true,
  971. dataEncipherment: true
  972. }, {
  973. name: 'extKeyUsage',
  974. serverAuth: true,
  975. clientAuth: true,
  976. codeSigning: true,
  977. emailProtection: true,
  978. timeStamping: true
  979. }, {
  980. name: 'nsCertType',
  981. client: true,
  982. server: true,
  983. email: true,
  984. objsign: true,
  985. sslCA: true,
  986. emailCA: true,
  987. objCA: true
  988. }, {
  989. name: 'subjectAltName',
  990. altNames: [{
  991. type: 6, // URI
  992. value: 'http://example.org/webid#me'
  993. }, {
  994. type: 7, // IP
  995. ip: '127.0.0.1'
  996. }]
  997. }, {
  998. name: 'subjectKeyIdentifier'
  999. }]);
  1000. /* alternatively set extensions from a csr
  1001. var extensions = csr.getAttribute({name: 'extensionRequest'}).extensions;
  1002. // optionally add more extensions
  1003. extensions.push.apply(extensions, [{
  1004. name: 'basicConstraints',
  1005. cA: true
  1006. }, {
  1007. name: 'keyUsage',
  1008. keyCertSign: true,
  1009. digitalSignature: true,
  1010. nonRepudiation: true,
  1011. keyEncipherment: true,
  1012. dataEncipherment: true
  1013. }]);
  1014. cert.setExtensions(extensions);
  1015. */
  1016. // self-sign certificate
  1017. cert.sign(keys.privateKey);
  1018. // convert a Forge certificate to PEM
  1019. var pem = pki.certificateToPem(cert);
  1020. // convert a Forge certificate from PEM
  1021. var cert = pki.certificateFromPem(pem);
  1022. // convert an ASN.1 X.509x3 object to a Forge certificate
  1023. var cert = pki.certificateFromAsn1(obj);
  1024. // convert a Forge certificate to an ASN.1 X.509v3 object
  1025. var asn1Cert = pki.certificateToAsn1(cert);
  1026. ```
  1027. <a name="pkcs5" />
  1028. ### PKCS#5
  1029. Provides the password-based key-derivation function from [PKCS#5][].
  1030. __Examples__
  1031. ```js
  1032. // generate a password-based 16-byte key
  1033. // note an optional message digest can be passed as the final parameter
  1034. var salt = forge.random.getBytesSync(128);
  1035. var derivedKey = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);
  1036. // generate key asynchronously
  1037. // note an optional message digest can be passed before the callback
  1038. forge.pkcs5.pbkdf2('password', salt, numIterations, 16, function(err, derivedKey) {
  1039. // do something w/derivedKey
  1040. });
  1041. ```
  1042. <a name="pkcs7" />
  1043. ### PKCS#7
  1044. Provides cryptographically protected messages from [PKCS#7][].
  1045. __Examples__
  1046. ```js
  1047. // convert a message from PEM
  1048. var p7 = forge.pkcs7.messageFromPem(pem);
  1049. // look at p7.recipients
  1050. // find a recipient by the issuer of a certificate
  1051. var recipient = p7.findRecipient(cert);
  1052. // decrypt
  1053. p7.decrypt(p7.recipients[0], privateKey);
  1054. // create a p7 enveloped message
  1055. var p7 = forge.pkcs7.createEnvelopedData();
  1056. // add a recipient
  1057. var cert = forge.pki.certificateFromPem(certPem);
  1058. p7.addRecipient(cert);
  1059. // set content
  1060. p7.content = forge.util.createBuffer('Hello');
  1061. // encrypt
  1062. p7.encrypt();
  1063. // convert message to PEM
  1064. var pem = forge.pkcs7.messageToPem(p7);
  1065. // create a degenerate PKCS#7 certificate container
  1066. // (CRLs not currently supported, only certificates)
  1067. var p7 = forge.pkcs7.createSignedData();
  1068. p7.addCertificate(certOrCertPem1);
  1069. p7.addCertificate(certOrCertPem2);
  1070. var pem = forge.pkcs7.messageToPem(p7);
  1071. // create PKCS#7 signed data with authenticatedAttributes
  1072. // attributes include: PKCS#9 content-type, message-digest, and signing-time
  1073. var p7 = forge.pkcs7.createSignedData();
  1074. p7.content = forge.util.createBuffer('Some content to be signed.', 'utf8');
  1075. p7.addCertificate(certOrCertPem);
  1076. p7.addSigner({
  1077. key: privateKeyAssociatedWithCert,
  1078. certificate: certOrCertPem,
  1079. digestAlgorithm: forge.pki.oids.sha256,
  1080. authenticatedAttributes: [{
  1081. type: forge.pki.oids.contentType,
  1082. value: forge.pki.oids.data
  1083. }, {
  1084. type: forge.pki.oids.messageDigest
  1085. // value will be auto-populated at signing time
  1086. }, {
  1087. type: forge.pki.oids.signingTime,
  1088. // value can also be auto-populated at signing time
  1089. value: new Date()
  1090. }]
  1091. });
  1092. p7.sign();
  1093. var pem = forge.pkcs7.messageToPem(p7);
  1094. ```
  1095. <a name="pkcs8" />
  1096. ### PKCS#8
  1097. __Examples__
  1098. ```js
  1099. var pki = forge.pki;
  1100. // convert a PEM-formatted private key to a Forge private key
  1101. var privateKey = pki.privateKeyFromPem(pem);
  1102. // convert a Forge private key to PEM-format
  1103. var pem = pki.privateKeyToPem(privateKey);
  1104. // convert an ASN.1 PrivateKeyInfo or RSAPrivateKey to a Forge private key
  1105. var privateKey = pki.privateKeyFromAsn1(rsaPrivateKey);
  1106. // convert a Forge private key to an ASN.1 RSAPrivateKey
  1107. var rsaPrivateKey = pki.privateKeyToAsn1(privateKey);
  1108. // wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo
  1109. var privateKeyInfo = pki.wrapRsaPrivateKey(rsaPrivateKey);
  1110. // convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM
  1111. var pem = pki.privateKeyInfoToPem(privateKeyInfo);
  1112. // encrypts a PrivateKeyInfo and outputs an EncryptedPrivateKeyInfo
  1113. var encryptedPrivateKeyInfo = pki.encryptPrivateKeyInfo(
  1114. privateKeyInfo, 'password', {
  1115. algorithm: 'aes256', // 'aes128', 'aes192', 'aes256', '3des'
  1116. });
  1117. // decrypts an ASN.1 EncryptedPrivateKeyInfo
  1118. var privateKeyInfo = pki.decryptPrivateKeyInfo(
  1119. encryptedPrivateKeyInfo, 'password');
  1120. // converts an EncryptedPrivateKeyInfo to PEM
  1121. var pem = pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo);
  1122. // converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format
  1123. var encryptedPrivateKeyInfo = pki.encryptedPrivateKeyFromPem(pem);
  1124. // wraps and encrypts a Forge private key and outputs it in PEM format
  1125. var pem = pki.encryptRsaPrivateKey(privateKey, 'password');
  1126. // encrypts a Forge private key and outputs it in PEM format using OpenSSL's
  1127. // proprietary legacy format + encapsulated PEM headers (DEK-Info)
  1128. var pem = pki.encryptRsaPrivateKey(privateKey, 'password', {legacy: true});
  1129. // decrypts a PEM-formatted, encrypted private key
  1130. var privateKey = pki.decryptRsaPrivateKey(pem, 'password');
  1131. // sets an RSA public key from a private key
  1132. var publicKey = pki.setRsaPublicKey(privateKey.n, privateKey.e);
  1133. ```
  1134. <a name="pkcs10" />
  1135. ### PKCS#10
  1136. Provides certification requests or certificate signing requests (CSR) from
  1137. [PKCS#10][].
  1138. __Examples__
  1139. ```js
  1140. // generate a key pair
  1141. var keys = forge.pki.rsa.generateKeyPair(1024);
  1142. // create a certification request (CSR)
  1143. var csr = forge.pki.createCertificationRequest();
  1144. csr.publicKey = keys.publicKey;
  1145. csr.setSubject([{
  1146. name: 'commonName',
  1147. value: 'example.org'
  1148. }, {
  1149. name: 'countryName',
  1150. value: 'US'
  1151. }, {
  1152. shortName: 'ST',
  1153. value: 'Virginia'
  1154. }, {
  1155. name: 'localityName',
  1156. value: 'Blacksburg'
  1157. }, {
  1158. name: 'organizationName',
  1159. value: 'Test'
  1160. }, {
  1161. shortName: 'OU',
  1162. value: 'Test'
  1163. }]);
  1164. // set (optional) attributes
  1165. csr.setAttributes([{
  1166. name: 'challengePassword',
  1167. value: 'password'
  1168. }, {
  1169. name: 'unstructuredName',
  1170. value: 'My Company, Inc.'
  1171. }, {
  1172. name: 'extensionRequest',
  1173. extensions: [{
  1174. name: 'subjectAltName',
  1175. altNames: [{
  1176. // 2 is DNS type
  1177. type: 2,
  1178. value: 'test.domain.com'
  1179. }, {
  1180. type: 2,
  1181. value: 'other.domain.com',
  1182. }, {
  1183. type: 2,
  1184. value: 'www.domain.net'
  1185. }]
  1186. }]
  1187. }]);
  1188. // sign certification request
  1189. csr.sign(keys.privateKey);
  1190. // verify certification request
  1191. var verified = csr.verify();
  1192. // convert certification request to PEM-format
  1193. var pem = forge.pki.certificationRequestToPem(csr);
  1194. // convert a Forge certification request from PEM-format
  1195. var csr = forge.pki.certificationRequestFromPem(pem);
  1196. // get an attribute
  1197. csr.getAttribute({name: 'challengePassword'});
  1198. // get extensions array
  1199. csr.getAttribute({name: 'extensionRequest'}).extensions;
  1200. ```
  1201. <a name="pkcs12" />
  1202. ### PKCS#12
  1203. Provides the cryptographic archive file format from [PKCS#12][].
  1204. **Note for Chrome/Firefox/iOS/similar users**: If you have trouble importing
  1205. a PKCS#12 container, try using the TripleDES algorithm. It can be passed
  1206. to `forge.pkcs12.toPkcs12Asn1` using the `{algorithm: '3des'}` option.
  1207. __Examples__
  1208. ```js
  1209. // decode p12 from base64
  1210. var p12Der = forge.util.decode64(p12b64);
  1211. // get p12 as ASN.1 object
  1212. var p12Asn1 = forge.asn1.fromDer(p12Der);
  1213. // decrypt p12 using the password 'password'
  1214. var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password');
  1215. // decrypt p12 using non-strict parsing mode (resolves some ASN.1 parse errors)
  1216. var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, 'password');
  1217. // decrypt p12 using literally no password (eg: Mac OS X/apple push)
  1218. var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1);
  1219. // decrypt p12 using an "empty" password (eg: OpenSSL with no password input)
  1220. var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, '');
  1221. // p12.safeContents is an array of safe contents, each of
  1222. // which contains an array of safeBags
  1223. // get bags by friendlyName
  1224. var bags = p12.getBags({friendlyName: 'test'});
  1225. // bags are key'd by attribute type (here "friendlyName")
  1226. // and the key values are an array of matching objects
  1227. var cert = bags.friendlyName[0];
  1228. // get bags by localKeyId
  1229. var bags = p12.getBags({localKeyId: buffer});
  1230. // bags are key'd by attribute type (here "localKeyId")
  1231. // and the key values are an array of matching objects
  1232. var cert = bags.localKeyId[0];
  1233. // get bags by localKeyId (input in hex)
  1234. var bags = p12.getBags({localKeyIdHex: '7b59377ff142d0be4565e9ac3d396c01401cd879'});
  1235. // bags are key'd by attribute type (here "localKeyId", *not* "localKeyIdHex")
  1236. // and the key values are an array of matching objects
  1237. var cert = bags.localKeyId[0];
  1238. // get bags by type
  1239. var bags = p12.getBags({bagType: forge.pki.oids.certBag});
  1240. // bags are key'd by bagType and each bagType key's value
  1241. // is an array of matches (in this case, certificate objects)
  1242. var cert = bags[forge.pki.oids.certBag][0];
  1243. // get bags by friendlyName and filter on bag type
  1244. var bags = p12.getBags({
  1245. friendlyName: 'test',
  1246. bagType: forge.pki.oids.certBag
  1247. });
  1248. // get key bags
  1249. var bags = p12.getBags({bagType: forge.pki.oids.keyBag});
  1250. // get key
  1251. var bag = bags[forge.pki.oids.keyBag][0];
  1252. var key = bag.key;
  1253. // if the key is in a format unrecognized by forge then
  1254. // bag.key will be `null`, use bag.asn1 to get the ASN.1
  1255. // representation of the key
  1256. if(bag.key === null) {
  1257. var keyAsn1 = bag.asn1;
  1258. // can now convert back to DER/PEM/etc for export
  1259. }
  1260. // generate a p12 using AES (default)
  1261. var p12Asn1 = forge.pkcs12.toPkcs12Asn1(
  1262. privateKey, certificateChain, 'password');
  1263. // generate a p12 that can be imported by Chrome/Firefox/iOS
  1264. // (requires the use of Triple DES instead of AES)
  1265. var p12Asn1 = forge.pkcs12.toPkcs12Asn1(
  1266. privateKey, certificateChain, 'password',
  1267. {algorithm: '3des'});
  1268. // base64-encode p12
  1269. var p12Der = forge.asn1.toDer(p12Asn1).getBytes();
  1270. var p12b64 = forge.util.encode64(p12Der);
  1271. // create download link for p12
  1272. var a = document.createElement('a');
  1273. a.download = 'example.p12';
  1274. a.setAttribute('href', 'data:application/x-pkcs12;base64,' + p12b64);
  1275. a.appendChild(document.createTextNode('Download'));
  1276. ```
  1277. <a name="asn" />
  1278. ### ASN.1
  1279. Provides [ASN.1][] DER encoding and decoding.
  1280. __Examples__
  1281. ```js
  1282. var asn1 = forge.asn1;
  1283. // create a SubjectPublicKeyInfo
  1284. var subjectPublicKeyInfo =
  1285. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
  1286. // AlgorithmIdentifier
  1287. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
  1288. // algorithm
  1289. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
  1290. asn1.oidToDer(pki.oids['rsaEncryption']).getBytes()),
  1291. // parameters (null)
  1292. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
  1293. ]),
  1294. // subjectPublicKey
  1295. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [
  1296. // RSAPublicKey
  1297. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
  1298. // modulus (n)
  1299. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
  1300. _bnToBytes(key.n)),
  1301. // publicExponent (e)
  1302. asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
  1303. _bnToBytes(key.e))
  1304. ])
  1305. ])
  1306. ]);
  1307. // serialize an ASN.1 object to DER format
  1308. var derBuffer = asn1.toDer(subjectPublicKeyInfo);
  1309. // deserialize to an ASN.1 object from a byte buffer filled with DER data
  1310. var object = asn1.fromDer(derBuffer);
  1311. // convert an OID dot-separated string to a byte buffer
  1312. var derOidBuffer = asn1.oidToDer('1.2.840.113549.1.1.5');
  1313. // convert a byte buffer with a DER-encoded OID to a dot-separated string
  1314. console.log(asn1.derToOid(derOidBuffer));
  1315. // output: 1.2.840.113549.1.1.5
  1316. // validates that an ASN.1 object matches a particular ASN.1 structure and
  1317. // captures data of interest from that structure for easy access
  1318. var publicKeyValidator = {
  1319. name: 'SubjectPublicKeyInfo',
  1320. tagClass: asn1.Class.UNIVERSAL,
  1321. type: asn1.Type.SEQUENCE,
  1322. constructed: true,
  1323. captureAsn1: 'subjectPublicKeyInfo',
  1324. value: [{
  1325. name: 'SubjectPublicKeyInfo.AlgorithmIdentifier',
  1326. tagClass: asn1.Class.UNIVERSAL,
  1327. type: asn1.Type.SEQUENCE,
  1328. constructed: true,
  1329. value: [{
  1330. name: 'AlgorithmIdentifier.algorithm',
  1331. tagClass: asn1.Class.UNIVERSAL,
  1332. type: asn1.Type.OID,
  1333. constructed: false,
  1334. capture: 'publicKeyOid'
  1335. }]
  1336. }, {
  1337. // subjectPublicKey
  1338. name: 'SubjectPublicKeyInfo.subjectPublicKey',
  1339. tagClass: asn1.Class.UNIVERSAL,
  1340. type: asn1.Type.BITSTRING,
  1341. constructed: false,
  1342. value: [{
  1343. // RSAPublicKey
  1344. name: 'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey',
  1345. tagClass: asn1.Class.UNIVERSAL,
  1346. type: asn1.Type.SEQUENCE,
  1347. constructed: true,
  1348. optional: true,
  1349. captureAsn1: 'rsaPublicKey'
  1350. }]
  1351. }]
  1352. };
  1353. var capture = {};
  1354. var errors = [];
  1355. if(!asn1.validate(
  1356. publicKeyValidator, subjectPublicKeyInfo, validator, capture, errors)) {
  1357. throw 'ASN.1 object is not a SubjectPublicKeyInfo.';
  1358. }
  1359. // capture.subjectPublicKeyInfo contains the full ASN.1 object
  1360. // capture.rsaPublicKey contains the full ASN.1 object for the RSA public key
  1361. // capture.publicKeyOid only contains the value for the OID
  1362. var oid = asn1.derToOid(capture.publicKeyOid);
  1363. if(oid !== pki.oids['rsaEncryption']) {
  1364. throw 'Unsupported OID.';
  1365. }
  1366. // pretty print an ASN.1 object to a string for debugging purposes
  1367. asn1.prettyPrint(object);
  1368. ```
  1369. Message Digests
  1370. ----------------
  1371. <a name="sha1" />
  1372. ### SHA1
  1373. Provides [SHA-1][] message digests.
  1374. __Examples__
  1375. ```js
  1376. var md = forge.md.sha1.create();
  1377. md.update('The quick brown fox jumps over the lazy dog');
  1378. console.log(md.digest().toHex());
  1379. // output: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
  1380. ```
  1381. <a name="sha256" />
  1382. ### SHA256
  1383. Provides [SHA-256][] message digests.
  1384. __Examples__
  1385. ```js
  1386. var md = forge.md.sha256.create();
  1387. md.update('The quick brown fox jumps over the lazy dog');
  1388. console.log(md.digest().toHex());
  1389. // output: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
  1390. ```
  1391. <a name="sha384" />
  1392. ### SHA384
  1393. Provides [SHA-384][] message digests.
  1394. __Examples__
  1395. ```js
  1396. var md = forge.md.sha384.create();
  1397. md.update('The quick brown fox jumps over the lazy dog');
  1398. console.log(md.digest().toHex());
  1399. // output: ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1
  1400. ```
  1401. <a name="sha512" />
  1402. ### SHA512
  1403. Provides [SHA-512][] message digests.
  1404. __Examples__
  1405. ```js
  1406. // SHA-512
  1407. var md = forge.md.sha512.create();
  1408. md.update('The quick brown fox jumps over the lazy dog');
  1409. console.log(md.digest().toHex());
  1410. // output: 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6
  1411. // SHA-512/224
  1412. var md = forge.md.sha512.sha224.create();
  1413. md.update('The quick brown fox jumps over the lazy dog');
  1414. console.log(md.digest().toHex());
  1415. // output: 944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37
  1416. // SHA-512/256
  1417. var md = forge.md.sha512.sha256.create();
  1418. md.update('The quick brown fox jumps over the lazy dog');
  1419. console.log(md.digest().toHex());
  1420. // output: dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d
  1421. ```
  1422. <a name="md5" />
  1423. ### MD5
  1424. Provides [MD5][] message digests.
  1425. __Examples__
  1426. ```js
  1427. var md = forge.md.md5.create();
  1428. md.update('The quick brown fox jumps over the lazy dog');
  1429. console.log(md.digest().toHex());
  1430. // output: 9e107d9d372bb6826bd81d3542a419d6
  1431. ```
  1432. <a name="hmac" />
  1433. ### HMAC
  1434. Provides [HMAC][] w/any supported message digest algorithm.
  1435. __Examples__
  1436. ```js
  1437. var hmac = forge.hmac.create();
  1438. hmac.start('sha1', 'Jefe');
  1439. hmac.update('what do ya want for nothing?');
  1440. console.log(hmac.digest().toHex());
  1441. // output: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
  1442. ```
  1443. Utilities
  1444. ---------
  1445. <a name="prime" />
  1446. ### Prime
  1447. Provides an API for generating large, random, probable primes.
  1448. __Examples__
  1449. ```js
  1450. // generate a random prime on the main JS thread
  1451. var bits = 1024;
  1452. forge.prime.generateProbablePrime(bits, function(err, num) {
  1453. console.log('random prime', num.toString(16));
  1454. });
  1455. // generate a random prime using Web Workers (if available, otherwise
  1456. // falls back to the main thread)
  1457. var bits = 1024;
  1458. var options = {
  1459. algorithm: {
  1460. name: 'PRIMEINC',
  1461. workers: -1 // auto-optimize # of workers
  1462. }
  1463. };
  1464. forge.prime.generateProbablePrime(bits, options, function(err, num) {
  1465. console.log('random prime', num.toString(16));
  1466. });
  1467. ```
  1468. <a name="prng" />
  1469. ### PRNG
  1470. Provides a [Fortuna][]-based cryptographically-secure pseudo-random number
  1471. generator, to be used with a cryptographic function backend, e.g. [AES][]. An
  1472. implementation using [AES][] as a backend is provided. An API for collecting
  1473. entropy is given, though if window.crypto.getRandomValues is available, it will
  1474. be used automatically.
  1475. __Examples__
  1476. ```js
  1477. // get some random bytes synchronously
  1478. var bytes = forge.random.getBytesSync(32);
  1479. console.log(forge.util.bytesToHex(bytes));
  1480. // get some random bytes asynchronously
  1481. forge.random.getBytes(32, function(err, bytes) {
  1482. console.log(forge.util.bytesToHex(bytes));
  1483. });
  1484. // collect some entropy if you'd like
  1485. forge.random.collect(someRandomBytes);
  1486. jQuery().mousemove(function(e) {
  1487. forge.random.collectInt(e.clientX, 16);
  1488. forge.random.collectInt(e.clientY, 16);
  1489. });
  1490. // specify a seed file for use with the synchronous API if you'd like
  1491. forge.random.seedFileSync = function(needed) {
  1492. // get 'needed' number of random bytes from somewhere
  1493. return fetchedRandomBytes;
  1494. };
  1495. // specify a seed file for use with the asynchronous API if you'd like
  1496. forge.random.seedFile = function(needed, callback) {
  1497. // get the 'needed' number of random bytes from somewhere
  1498. callback(null, fetchedRandomBytes);
  1499. });
  1500. // register the main thread to send entropy or a Web Worker to receive
  1501. // entropy on demand from the main thread
  1502. forge.random.registerWorker(self);
  1503. // generate a new instance of a PRNG with no collected entropy
  1504. var myPrng = forge.random.createInstance();
  1505. ```
  1506. <a name="task" />
  1507. ### Tasks
  1508. Provides queuing and synchronizing tasks in a web application.
  1509. __Examples__
  1510. ```js
  1511. // TODO
  1512. ```
  1513. <a name="util" />
  1514. ### Utilities
  1515. Provides utility functions, including byte buffer support, base64,
  1516. bytes to/from hex, zlib inflate/deflate, etc.
  1517. __Examples__
  1518. ```js
  1519. // encode/decode base64
  1520. var encoded = forge.util.encode64(str);
  1521. var str = forge.util.decode64(encoded);
  1522. // encode/decode UTF-8
  1523. var encoded = forge.util.encodeUtf8(str);
  1524. var str = forge.util.decodeUtf8(encoded);
  1525. // bytes to/from hex
  1526. var bytes = forge.util.hexToBytes(hex);
  1527. var hex = forge.util.bytesToHex(bytes);
  1528. // create an empty byte buffer
  1529. var buffer = forge.util.createBuffer();
  1530. // create a byte buffer from raw binary bytes
  1531. var buffer = forge.util.createBuffer(input, 'raw');
  1532. // create a byte buffer from utf8 bytes
  1533. var buffer = forge.util.createBuffer(input, 'utf8');
  1534. // get the length of the buffer in bytes
  1535. buffer.length();
  1536. // put bytes into the buffer
  1537. buffer.putBytes(bytes);
  1538. // put a 32-bit integer into the buffer
  1539. buffer.putInt32(10);
  1540. // buffer to hex
  1541. buffer.toHex();
  1542. // get a copy of the bytes in the buffer
  1543. bytes.bytes(/* count */);
  1544. // empty this buffer and get its contents
  1545. bytes.getBytes(/* count */);
  1546. // convert a forge buffer into a Node.js Buffer
  1547. // make sure you specify the encoding as 'binary'
  1548. var forgeBuffer = forge.util.createBuffer();
  1549. var nodeBuffer = new Buffer(forgeBuffer.getBytes(), 'binary');
  1550. // convert a Node.js Buffer into a forge buffer
  1551. // make sure you specify the encoding as 'binary'
  1552. var nodeBuffer = new Buffer();
  1553. var forgeBuffer = forge.util.createBuffer(nodeBuffer.toString('binary'));
  1554. // parse a URL
  1555. var parsed = forge.util.parseUrl('http://example.com/foo?bar=baz');
  1556. // parsed.scheme, parsed.host, parsed.port, parsed.path, parsed.fullHost
  1557. ```
  1558. <a name="log" />
  1559. ### Logging
  1560. Provides logging to a javascript console using various categories and
  1561. levels of verbosity.
  1562. __Examples__
  1563. ```js
  1564. // TODO
  1565. ```
  1566. <a name="debug" />
  1567. ### Debugging
  1568. Provides storage of debugging information normally inaccessible in
  1569. closures for viewing/investigation.
  1570. __Examples__
  1571. ```js
  1572. // TODO
  1573. ```
  1574. <a name="flash" />
  1575. ### Flash Networking Support
  1576. The [flash README](./flash/README.md) provides details on rebuilding the
  1577. optional Flash component used for networking. It also provides details on
  1578. Policy Server support.
  1579. Security Considerations
  1580. -----------------------
  1581. When using this code please keep the following in mind:
  1582. - Cryptography is hard. Please review and test this code before depending on it
  1583. for critical functionality.
  1584. - The nature of JavaScript is that execution of this code depends on trusting a
  1585. very large set of JavaScript tools and systems. Consider runtime variations,
  1586. runtime characteristics, runtime optimization, code optimization, code
  1587. minimization, code obfuscation, bundling tools, possible bugs, the Forge code
  1588. itself, and so on.
  1589. - If using pre-built bundles from [Bower][] or similar be aware someone else
  1590. ran the tools to create those files.
  1591. - Use a secure transport channel such as [TLS][] to load scripts and consider
  1592. using additional security mechanisms such as [Subresource Integrity][] script
  1593. attributes.
  1594. - Use "native" functionality where possible. This can be critical when dealing
  1595. with performance and random number generation. Note that the JavaScript
  1596. random number algorithms should perform well if given suitable entropy.
  1597. - Understand possible attacks against cryptographic systems. For instance side
  1598. channel and timing attacks may be possible due to the difficulty in
  1599. implementing constant time algorithms in pure JavaScript.
  1600. - Certain features in this library are less susceptible to attacks depending on
  1601. usage. This primarily includes features that deal with data format
  1602. manipulation or those that are not involved in communication.
  1603. Library Background
  1604. ------------------
  1605. * http://digitalbazaar.com/2010/07/20/javascript-tls-1/
  1606. * http://digitalbazaar.com/2010/07/20/javascript-tls-2/
  1607. Contact
  1608. -------
  1609. * Code: https://github.com/digitalbazaar/forge
  1610. * Bugs: https://github.com/digitalbazaar/forge/issues
  1611. * Email: support@digitalbazaar.com
  1612. * IRC: [#forgejs][] on [freenode][]
  1613. Donations
  1614. ---------
  1615. Financial support is welcome and helps contribute to futher development:
  1616. * For [PayPal][] please send to paypal@digitalbazaar.com.
  1617. * Something else? Please contact support@digitalbazaar.com.
  1618. [#forgejs]: https://webchat.freenode.net/?channels=#forgejs
  1619. [0.6.x]: https://github.com/digitalbazaar/forge/tree/0.6.x
  1620. [3DES]: http://en.wikipedia.org/wiki/Triple_DES
  1621. [AES]: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
  1622. [ASN.1]: http://en.wikipedia.org/wiki/ASN.1
  1623. [Bower]: https://bower.io/
  1624. [Browserify]: http://browserify.org/
  1625. [CBC]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  1626. [CFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  1627. [CTR]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  1628. [CommonJS]: https://en.wikipedia.org/wiki/CommonJS
  1629. [DES]: http://en.wikipedia.org/wiki/Data_Encryption_Standard
  1630. [ECB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  1631. [Fortuna]: http://en.wikipedia.org/wiki/Fortuna_(PRNG)
  1632. [GCM]: http://en.wikipedia.org/wiki/GCM_mode
  1633. [HMAC]: http://en.wikipedia.org/wiki/HMAC
  1634. [JavaScript]: http://en.wikipedia.org/wiki/JavaScript
  1635. [Karma]: https://karma-runner.github.io/
  1636. [MD5]: http://en.wikipedia.org/wiki/MD5
  1637. [Node.js]: http://nodejs.org/
  1638. [OFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  1639. [PKCS#10]: http://en.wikipedia.org/wiki/Certificate_signing_request
  1640. [PKCS#12]: http://en.wikipedia.org/wiki/PKCS_%E2%99%AF12
  1641. [PKCS#5]: http://en.wikipedia.org/wiki/PKCS
  1642. [PKCS#7]: http://en.wikipedia.org/wiki/Cryptographic_Message_Syntax
  1643. [PayPal]: https://www.paypal.com/
  1644. [RC2]: http://en.wikipedia.org/wiki/RC2
  1645. [SHA-1]: http://en.wikipedia.org/wiki/SHA-1
  1646. [SHA-256]: http://en.wikipedia.org/wiki/SHA-256
  1647. [SHA-384]: http://en.wikipedia.org/wiki/SHA-384
  1648. [SHA-512]: http://en.wikipedia.org/wiki/SHA-512
  1649. [Subresource Integrity]: https://www.w3.org/TR/SRI/
  1650. [TLS]: http://en.wikipedia.org/wiki/Transport_Layer_Security
  1651. [UMD]: https://github.com/umdjs/umd
  1652. [X.509]: http://en.wikipedia.org/wiki/X.509
  1653. [freenode]: https://freenode.net/
  1654. [unpkg]: https://unpkg.com/
  1655. [webpack]: https://webpack.github.io/
  1656. [TweetNaCl]: https://github.com/dchest/tweetnacl-js