A native implementation ofTLS(and various other cryptographic tools) in JavaScript.
The Forge software is a fully native implementation of theTLSprotocol in JavaScript, a set of cryptography utilities, and a set of tools for developing Web Apps that utilize many network resources.
Forge is fast. Benchmarks against other popular JavaScript cryptography libraries can be found here:
- http://dominictarr.github.io/crypto-bench/
- http://cryptojs.altervista.org/test/simulate-threading-speed_test.html
Note:Please see theSecurity Considerations section before using packaging systems and pre-built files.
Forge uses aCommonJSmodule structure with a build process for browser bundles. The older0.6.xbranch with standalone files is available but will not be regularly updated.
If you want to use forge withNode.js,it is available throughnpm
:
https://www.npmjs.com/package/node-forge
Installation:
npm install node-forge
You can then use forge as a regular module:
varforge=require('node-forge');
The npm package includes pre-builtforge.min.js
,forge.all.min.js
,and
prime.worker.min.js
using theUMDformat.
To use it viajsDelivrinclude this in your html:
<scriptsrc= "https://cdn.jsdelivr.net/npm/[email protected]/dist/forge.min.js"></script>
To use it viaunpkginclude this in your html:
<scriptsrc= "https://unpkg.com/[email protected]/dist/forge.min.js"></script>
The core JavaScript has the following requirements to build and test:
- Building a browser bundle:
- Node.js
- npm
- Testing
- Node.js
- npm
- Chrome, Firefox, Safari (optional)
Some special networking features can optionally use a Flash component. See the Flash READMEfor details.
To create single file bundles for use with browsers run the following:
npm install
npm run build
This will create single non-minimized and minimized files that can be included in the browser:
dist/forge.js
dist/forge.min.js
A bundle that adds some utilities and networking support is also available:
dist/forge.all.js
dist/forge.all.min.js
Include the file via:
<scriptsrc= "YOUR_SCRIPT_PATH/forge.js"></script>
or
<scriptsrc= "YOUR_SCRIPT_PATH/forge.min.js"></script>
The above bundles will synchronously create a global 'forge' object.
Note:These bundles will not include any WebWorker scripts (eg:
dist/prime.worker.js
), so these will need to be accessible from the browser
if any WebWorkers are used.
The build process useswebpackand theconfigfile can be modified to generate a file or files that only contain the parts of forge you need.
Browserifyoverride support is also present inpackage.json
.
npm install
Forge natively runs in aNode.jsenvironment:
npm test
Automated testing is done viaKarma.By default it will run the tests with Headless Chrome.
npm run test-karma
Is 'mocha' reporter output too verbose? Other reporters are available. Try 'dots', 'progress', or 'tap'.
npm run test-karma -- --reporters progress
By defaultwebpackis used.Browserifycan also be used.
BUNDLER=browserify npm run test-karma
You can also specify one or more browsers to use.
npm run test-karma -- --browsers Chrome,Firefox,Safari,ChromeHeadless
The reporter option andBUNDLER
environment variable can also be used.
Testing in a browser useswebpackto combine forge and all tests and then
loading the result in a browser. A simple web server is provided that will
output the HTTP or HTTPS URLs to load. It also will start a simple Flash Policy
Server. Unit tests and older legacy tests are provided. Custom ports can be
used by runningnode tests/server.js
manually.
To run the unit tests in a browser a special forge build is required:
npm run test-build
To run legacy browser based tests the main forge build is required:
npm run build
The tests are run with a custom server that prints out the URLs to use:
npm run test-server
There are some other random tests and benchmarks available in the tests directory.
To perform coverage testing of the unit tests, run the following. The results
will be put in thecoverage/
directory. Note that coverage testing can slow
down some tests considerably.
npm install
npm run coverage
Any contributions (eg: PRs) that are accepted will be brought under the same license used by the rest of the Forge project. This license allows Forge to be used under the terms of either the BSD License or the GNU General Public License (GPL) Version 2.
See:LICENSE
If a contribution contains 3rd party source code with its own license, it may retain it, so long as that license is compatible with the Forge license.
If at any time you wish to disable the use of native code, where available,
for particular forge features like its secure random number generator, you
may set theforge.options.usePureJavaScript
flag totrue
.It is
not recommended that you set this flag as native code is typically more
performant and may have stronger security properties. It may be useful to
set this flag to test certain features that you plan to run in environments
that are different from your testing environment.
To disable native code when including forge in the browser:
// run this *after* including the forge script
forge.options.usePureJavaScript=true;
To disable native code when using Node.js:
varforge=require('node-forge');
forge.options.usePureJavaScript=true;
Provides a native javascript client and server-sideTLSimplementation.
Examples
// create TLS client
varclient=forge.tls.createConnection({
server:false,
caStore:/* Array of PEM-formatted certs or a CA store object */,
sessionCache:{},
// supported cipher suites in order of preference
cipherSuites:[
forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
virtualHost:'example.com',
verify:function(connection,verified,depth,certs){
if(depth===0){
varcn=certs[0].subject.getField('CN').value;
if(cn!=='example.com'){
verified={
alert:forge.tls.Alert.Description.bad_certificate,
message:'Certificate common name does not match hostname.'
};
}
}
returnverified;
},
connected:function(connection){
console.log('connected');
// send message to server
connection.prepare(forge.util.encodeUtf8('Hi server!'));
/* NOTE: experimental, start heartbeat retransmission timer
myHeartbeatTimer = setInterval(function() {
connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
}, 5*60*1000);*/
},
/* provide a client-side cert if you want
getCertificate: function(connection, hint) {
return myClientCertificate;
},
/* the private key for the client-side cert if provided */
getPrivateKey:function(connection,cert){
returnmyClientPrivateKey;
},
tlsDataReady:function(connection){
// TLS data (encrypted) is ready to be sent to the server
sendToServerSomehow(connection.tlsData.getBytes());
// if you were communicating with the server below, you'd do:
// server.process(connection.tlsData.getBytes());
},
dataReady:function(connection){
// clear data from the server is ready
console.log('the server sent: '+
forge.util.decodeUtf8(connection.data.getBytes()));
// close connection
connection.close();
},
/* NOTE: experimental
heartbeatReceived: function(connection, payload) {
// restart retransmission timer, look at payload
clearInterval(myHeartbeatTimer);
myHeartbeatTimer = setInterval(function() {
connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
}, 5*60*1000);
payload.getBytes();
},*/
closed:function(connection){
console.log('disconnected');
},
error:function(connection,error){
console.log('uh oh',error);
}
});
// start the handshake process
client.handshake();
// when encrypted TLS data is received from the server, process it
client.process(encryptedBytesFromServer);
// create TLS server
varserver=forge.tls.createConnection({
server:true,
caStore:/* Array of PEM-formatted certs or a CA store object */,
sessionCache:{},
// supported cipher suites in order of preference
cipherSuites:[
forge.tls.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA,
forge.tls.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA],
// require a client-side certificate if you want
verifyClient:true,
verify:function(connection,verified,depth,certs){
if(depth===0){
varcn=certs[0].subject.getField('CN').value;
if(cn!=='the-client'){
verified={
alert:forge.tls.Alert.Description.bad_certificate,
message:'Certificate common name does not match expected client.'
};
}
}
returnverified;
},
connected:function(connection){
console.log('connected');
// send message to client
connection.prepare(forge.util.encodeUtf8('Hi client!'));
/* NOTE: experimental, start heartbeat retransmission timer
myHeartbeatTimer = setInterval(function() {
connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
}, 5*60*1000);*/
},
getCertificate:function(connection,hint){
returnmyServerCertificate;
},
getPrivateKey:function(connection,cert){
returnmyServerPrivateKey;
},
tlsDataReady:function(connection){
// TLS data (encrypted) is ready to be sent to the client
sendToClientSomehow(connection.tlsData.getBytes());
// if you were communicating with the client above you'd do:
// client.process(connection.tlsData.getBytes());
},
dataReady:function(connection){
// clear data from the client is ready
console.log('the client sent: '+
forge.util.decodeUtf8(connection.data.getBytes()));
// close connection
connection.close();
},
/* NOTE: experimental
heartbeatReceived: function(connection, payload) {
// restart retransmission timer, look at payload
clearInterval(myHeartbeatTimer);
myHeartbeatTimer = setInterval(function() {
connection.prepareHeartbeatRequest(forge.util.createBuffer('1234'));
}, 5*60*1000);
payload.getBytes();
},*/
closed:function(connection){
console.log('disconnected');
},
error:function(connection,error){
console.log('uh oh',error);
}
});
// when encrypted TLS data is received from the client, process it
server.process(encryptedBytesFromClient);
Connect to a TLS server using node's net.Socket:
varsocket=newnet.Socket();
varclient=forge.tls.createConnection({
server:false,
verify:function(connection,verified,depth,certs){
// skip verification for testing
console.log('[tls] server certificate verified');
returntrue;
},
connected:function(connection){
console.log('[tls] connected');
// prepare some data to send (note that the string is interpreted as
// 'binary' encoded, which works for HTTP which only uses ASCII, use
// forge.util.encodeUtf8(str) otherwise
client.prepare('GET / HTTP/1.0\r\n\r\n');
},
tlsDataReady:function(connection){
// encrypted data is ready to be sent to the server
vardata=connection.tlsData.getBytes();
socket.write(data,'binary');// encoding should be 'binary'
},
dataReady:function(connection){
// clear data from the server is ready
vardata=connection.data.getBytes();
console.log('[tls] data received from the server: '+data);
},
closed:function(){
console.log('[tls] disconnected');
},
error:function(connection,error){
console.log('[tls] error',error);
}
});
socket.on('connect',function(){
console.log('[socket] connected');
client.handshake();
});
socket.on('data',function(data){
client.process(data.toString('binary'));// encoding should be 'binary'
});
socket.on('end',function(){
console.log('[socket] disconnected');
});
// connect to google.com
socket.connect(443,'google.com');
// or connect to gmail's imap server (but don't send the HTTP header above)
//socket.connect(993, 'imap.gmail.com');
Provides a nativeJavaScriptmini-implementation of an http client that uses pooled sockets.
Examples
// create an HTTP GET request
varrequest=forge.http.createRequest({method:'GET',path:url.path});
// send the request somewhere
sendSomehow(request.toString());
// receive response
varbuffer=forge.util.createBuffer();
varresponse=forge.http.createResponse();
varsomeAsyncDataHandler=function(bytes){
if(!response.bodyReceived){
buffer.putBytes(bytes);
if(!response.headerReceived){
if(response.readHeader(buffer)){
console.log('HTTP response header: '+response.toString());
}
}
if(response.headerReceived&&!response.bodyReceived){
if(response.readBody(buffer)){
console.log('HTTP response body: '+response.body);
}
}
}
};
Provides some SSH utility functions.
Examples
// encodes (and optionally encrypts) a private RSA key as a Putty PPK file
forge.ssh.privateKeyToPutty(privateKey,passphrase,comment);
// encodes a public RSA key as an OpenSSH file
forge.ssh.publicKeyToOpenSSH(key,comment);
// encodes a private RSA key as an OpenSSH file
forge.ssh.privateKeyToOpenSSH(privateKey,passphrase);
// gets the SSH public key fingerprint in a byte buffer
forge.ssh.getPublicKeyFingerprint(key);
// gets a hex-encoded, colon-delimited SSH public key fingerprint
forge.ssh.getPublicKeyFingerprint(key,{encoding:'hex',delimiter:':'});
Provides an XmlHttpRequest implementation using forge.http as a backend.
Examples
// TODO
Provides an interface to create and use raw sockets provided via Flash.
Examples
// TODO
Provides a basic API for block encryption and decryption. There is built-in support for the ciphers:AES,3DES,andDES,and for the modes of operation:ECB,CBC,CFB,OFB,CTR,andGCM.
These algorithms are currently supported:
- AES-ECB
- AES-CBC
- AES-CFB
- AES-OFB
- AES-CTR
- AES-GCM
- 3DES-ECB
- 3DES-CBC
- DES-ECB
- DES-CBC
When using anAESalgorithm, the key size will determine whether AES-128, AES-192, or AES-256 is used (all are supported). When aDES algorithm is used, the key size will determine whether3DESor regular DESis used. Use a3DESalgorithm to enforce Triple-DES.
Examples
// generate a random key and IV
// Note: a key size of 16 bytes will use AES-128, 24 => AES-192, 32 => AES-256
varkey=forge.random.getBytesSync(16);
variv=forge.random.getBytesSync(16);
/* alternatively, generate a password-based 16-byte key
var salt = forge.random.getBytesSync(128);
var key = forge.pkcs5.pbkdf2('password', salt, numIterations, 16);
*/
// encrypt some bytes using CBC mode
// (other modes include: ECB, CFB, OFB, CTR, and GCM)
// Note: CBC and ECB modes use PKCS#7 padding as default
varcipher=forge.cipher.createCipher('AES-CBC',key);
cipher.start({iv:iv});
cipher.update(forge.util.createBuffer(someBytes));
cipher.finish();
varencrypted=cipher.output;
// outputs encrypted hex
console.log(encrypted.toHex());
// decrypt some bytes using CBC mode
// (other modes include: CFB, OFB, CTR, and GCM)
vardecipher=forge.cipher.createDecipher('AES-CBC',key);
decipher.start({iv:iv});
decipher.update(encrypted);
varresult=decipher.finish();// check 'result' for true/false
// outputs decrypted hex
console.log(decipher.output.toHex());
// decrypt bytes using CBC mode and streaming
// Performance can suffer for large multi-MB inputs due to buffer
// manipulations. Stream processing in chunks can offer significant
// improvement. CPU intensive update() calls could also be performed with
// setImmediate/setTimeout to avoid blocking the main browser UI thread (not
// shown here). Optimal block size depends on the JavaScript VM and other
// factors. Encryption can use a simple technique for increased performance.
varencryptedBytes=encrypted.bytes();
vardecipher=forge.cipher.createDecipher('AES-CBC',key);
decipher.start({iv:iv});
varlength=encryptedBytes.length;
varchunkSize=1024*64;
varindex=0;
vardecrypted='';
do{
decrypted+=decipher.output.getBytes();
varbuf=forge.util.createBuffer(encryptedBytes.substr(index,chunkSize));
decipher.update(buf);
index+=chunkSize;
}while(index<length);
varresult=decipher.finish();
assert(result);
decrypted+=decipher.output.getBytes();
console.log(forge.util.bytesToHex(decrypted));
// encrypt some bytes using GCM mode
varcipher=forge.cipher.createCipher('AES-GCM',key);
cipher.start({
iv:iv,// should be a 12-byte binary-encoded string or byte buffer
additionalData:'binary-encoded string',// optional
tagLength:128// optional, defaults to 128 bits
});
cipher.update(forge.util.createBuffer(someBytes));
cipher.finish();
varencrypted=cipher.output;
vartag=cipher.mode.tag;
// outputs encrypted hex
console.log(encrypted.toHex());
// outputs authentication tag
console.log(tag.toHex());
// decrypt some bytes using GCM mode
vardecipher=forge.cipher.createDecipher('AES-GCM',key);
decipher.start({
iv:iv,
additionalData:'binary-encoded string',// optional
tagLength:128,// optional, defaults to 128 bits
tag:tag// authentication tag from encryption
});
decipher.update(encrypted);
varpass=decipher.finish();
// pass is false if there was a failure (eg: authentication tag didn't match)
if(pass){
// outputs decrypted hex
console.log(decipher.output.toHex());
}
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 asOpenPGP/GnuPG):
varforge=require('node-forge');
varfs=require('fs');
// openssl enc -des3 -in input.txt -out input.enc
functionencrypt(password){
varinput=fs.readFileSync('input.txt',{encoding:'binary'});
// 3DES key and IV sizes
varkeySize=24;
varivSize=8;
// get derived bytes
// Notes:
// 1. If using an alternative hash (eg: "-md sha1" ) pass
// "forge.md.sha1.create()" as the final parameter.
// 2. If using "-nosalt", set salt to null.
varsalt=forge.random.getBytesSync(8);
// var md = forge.md.sha1.create(); // "-md sha1"
varderivedBytes=forge.pbe.opensslDeriveBytes(
password,salt,keySize+ivSize/*, md*/);
varbuffer=forge.util.createBuffer(derivedBytes);
varkey=buffer.getBytes(keySize);
variv=buffer.getBytes(ivSize);
varcipher=forge.cipher.createCipher('3DES-CBC',key);
cipher.start({iv:iv});
cipher.update(forge.util.createBuffer(input,'binary'));
cipher.finish();
varoutput=forge.util.createBuffer();
// if using a salt, prepend this to the output:
if(salt!==null){
output.putBytes('Salted__');// (add to match openssl tool output)
output.putBytes(salt);
}
output.putBuffer(cipher.output);
fs.writeFileSync('input.enc',output.getBytes(),{encoding:'binary'});
}
// openssl enc -d -des3 -in input.enc -out input.dec.txt
functiondecrypt(password){
varinput=fs.readFileSync('input.enc',{encoding:'binary'});
// parse salt from input
input=forge.util.createBuffer(input,'binary');
// skip "Salted__" (if known to be present)
input.getBytes('Salted__'.length);
// read 8-byte salt
varsalt=input.getBytes(8);
// Note: if using "-nosalt", skip above parsing and use
// var salt = null;
// 3DES key and IV sizes
varkeySize=24;
varivSize=8;
varderivedBytes=forge.pbe.opensslDeriveBytes(
password,salt,keySize+ivSize);
varbuffer=forge.util.createBuffer(derivedBytes);
varkey=buffer.getBytes(keySize);
variv=buffer.getBytes(ivSize);
vardecipher=forge.cipher.createDecipher('3DES-CBC',key);
decipher.start({iv:iv});
decipher.update(input);
varresult=decipher.finish();// check 'result' for true/false
fs.writeFileSync(
'input.dec.txt',decipher.output.getBytes(),{encoding:'binary'});
}
ProvidesAESencryption and decryption inCBC,CFB,OFB, CTR,andGCMmodes. SeeCIPHERfor examples.
Provides3DESandDESencryption and decryption inECBand CBCmodes. SeeCIPHERfor examples.
Examples
// generate a random key and IV
varkey=forge.random.getBytesSync(16);
variv=forge.random.getBytesSync(8);
// encrypt some bytes
varcipher=forge.rc2.createEncryptionCipher(key);
cipher.start(iv);
cipher.update(forge.util.createBuffer(someBytes));
cipher.finish();
varencrypted=cipher.output;
// outputs encrypted hex
console.log(encrypted.toHex());
// decrypt some bytes
varcipher=forge.rc2.createDecryptionCipher(key);
cipher.start(iv);
cipher.update(encrypted);
cipher.finish();
// outputs decrypted hex
console.log(cipher.output.toHex());
ProvidesX.509certificate support, ED25519 key generation and signing/verifying, and RSA public and private key encoding, decoding, encryption/decryption, and signing/verifying.
Special thanks toTweetNaCl.jsfor providing the bulk of the implementation.
Examples
vared25519=forge.pki.ed25519;
// generate a random ED25519 keypair
varkeypair=ed25519.generateKeyPair();
// `keypair.publicKey` is a node.js Buffer or Uint8Array
// `keypair.privateKey` is a node.js Buffer or Uint8Array
// generate a random ED25519 keypair based on a random 32-byte seed
varseed=forge.random.getBytesSync(32);
varkeypair=ed25519.generateKeyPair({seed:seed});
// generate a random ED25519 keypair based on a "password" 32-byte seed
varpassword='Mai9ohgh6ahxee0jutheew0pungoozil';
varseed=newforge.util.ByteBuffer(password,'utf8');
varkeypair=ed25519.generateKeyPair({seed:seed});
// sign a UTF-8 message
varsignature=ED25519.sign({
message:'test',
// also accepts `binary` if you want to pass a binary string
encoding:'utf8',
// node.js Buffer, Uint8Array, forge ByteBuffer, binary string
privateKey:privateKey
});
// `signature` is a node.js Buffer or Uint8Array
// sign a message passed as a buffer
varsignature=ED25519.sign({
// also accepts a forge ByteBuffer or Uint8Array
message:Buffer.from('test','utf8'),
privateKey:privateKey
});
// sign a message digest (shorter "message" == better performance)
varmd=forge.md.sha256.create();
md.update('test','utf8');
varsignature=ED25519.sign({
md:md,
privateKey:privateKey
});
// verify a signature on a UTF-8 message
varverified=ED25519.verify({
message:'test',
encoding:'utf8',
// node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
signature:signature,
// node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
publicKey:publicKey
});
// `verified` is true/false
// sign a message passed as a buffer
varverified=ED25519.verify({
// also accepts a forge ByteBuffer or Uint8Array
message:Buffer.from('test','utf8'),
// node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
signature:signature,
// node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
publicKey:publicKey
});
// verify a signature on a message digest
varmd=forge.md.sha256.create();
md.update('test','utf8');
varverified=ED25519.verify({
md:md,
// node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
signature:signature,
// node.js Buffer, Uint8Array, forge ByteBuffer, or binary string
publicKey:publicKey
});
Examples
varrsa=forge.pki.rsa;
// generate an RSA key pair synchronously
// *NOT RECOMMENDED*: Can be significantly slower than async and may block
// JavaScript execution. Will use native Node.js 10.12.0+ API if possible.
varkeypair=rsa.generateKeyPair({bits:2048,e:0x10001});
// generate an RSA key pair asynchronously (uses web workers if available)
// use workers: -1 to run a fast core estimator to optimize # of workers
// *RECOMMENDED*: Can be significantly faster than sync. Will use native
// Node.js 10.12.0+ or WebCrypto API if possible.
rsa.generateKeyPair({bits:2048,workers:2},function(err,keypair){
// keypair.privateKey, keypair.publicKey
});
// generate an RSA key pair in steps that attempt to run for a specified period
// of time on the main JS thread
varstate=rsa.createKeyPairGenerationState(2048,0x10001);
varstep=function(){
// run for 100 ms
if(!rsa.stepKeyPairGenerationState(state,100)){
setTimeout(step,1);
}
else{
// done, turn off progress indicator, use state.keys
}
};
// turn on progress indicator, schedule generation to run
setTimeout(step);
// sign data with a private key and output DigestInfo DER-encoded bytes
// (defaults to RSASSA PKCS#1 v1.5)
varmd=forge.md.sha1.create();
md.update('sign this','utf8');
varsignature=privateKey.sign(md);
// verify data with a public key
// (defaults to RSASSA PKCS#1 v1.5)
varverified=publicKey.verify(md.digest().bytes(),signature);
// sign data using RSASSA-PSS where PSS uses a SHA-1 hash, a SHA-1 based
// masking function MGF1, and a 20 byte salt
varmd=forge.md.sha1.create();
md.update('sign this','utf8');
varpss=forge.pss.create({
md:forge.md.sha1.create(),
mgf:forge.mgf.mgf1.create(forge.md.sha1.create()),
saltLength:20
// optionally pass 'prng' with a custom PRNG implementation
// optionalls pass 'salt' with a forge.util.ByteBuffer w/custom salt
});
varsignature=privateKey.sign(md,pss);
// verify RSASSA-PSS signature
varpss=forge.pss.create({
md:forge.md.sha1.create(),
mgf:forge.mgf.mgf1.create(forge.md.sha1.create()),
saltLength:20
// optionally pass 'prng' with a custom PRNG implementation
});
varmd=forge.md.sha1.create();
md.update('sign this','utf8');
publicKey.verify(md.digest().getBytes(),signature,pss);
// encrypt data with a public key (defaults to RSAES PKCS#1 v1.5)
varencrypted=publicKey.encrypt(bytes);
// decrypt data with a private key (defaults to RSAES PKCS#1 v1.5)
vardecrypted=privateKey.decrypt(encrypted);
// encrypt data with a public key using RSAES PKCS#1 v1.5
varencrypted=publicKey.encrypt(bytes,'RSAES-PKCS1-V1_5');
// decrypt data with a private key using RSAES PKCS#1 v1.5
vardecrypted=privateKey.decrypt(encrypted,'RSAES-PKCS1-V1_5');
// encrypt data with a public key using RSAES-OAEP
varencrypted=publicKey.encrypt(bytes,'RSA-OAEP');
// decrypt data with a private key using RSAES-OAEP
vardecrypted=privateKey.decrypt(encrypted,'RSA-OAEP');
// encrypt data with a public key using RSAES-OAEP/SHA-256
varencrypted=publicKey.encrypt(bytes,'RSA-OAEP',{
md:forge.md.sha256.create()
});
// decrypt data with a private key using RSAES-OAEP/SHA-256
vardecrypted=privateKey.decrypt(encrypted,'RSA-OAEP',{
md:forge.md.sha256.create()
});
// encrypt data with a public key using RSAES-OAEP/SHA-256/MGF1-SHA-1
// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
varencrypted=publicKey.encrypt(bytes,'RSA-OAEP',{
md:forge.md.sha256.create(),
mgf1:{
md:forge.md.sha1.create()
}
});
// decrypt data with a private key using RSAES-OAEP/SHA-256/MGF1-SHA-1
// compatible with Java's RSA/ECB/OAEPWithSHA-256AndMGF1Padding
vardecrypted=privateKey.decrypt(encrypted,'RSA-OAEP',{
md:forge.md.sha256.create(),
mgf1:{
md:forge.md.sha1.create()
}
});
Examples
// generate an RSA key pair asynchronously (uses web workers if available)
// use workers: -1 to run a fast core estimator to optimize # of workers
forge.rsa.generateKeyPair({bits:2048,workers:-1},function(err,keypair){
// keypair.privateKey, keypair.publicKey
});
// generate and encapsulate a 16-byte secret key
varkdf1=newforge.kem.kdf1(forge.md.sha1.create());
varkem=forge.kem.rsa.create(kdf1);
varresult=kem.encrypt(keypair.publicKey,16);
// result has 'encapsulation' and 'key'
// encrypt some bytes
variv=forge.random.getBytesSync(12);
varsomeBytes='hello world!';
varcipher=forge.cipher.createCipher('AES-GCM',result.key);
cipher.start({iv:iv});
cipher.update(forge.util.createBuffer(someBytes));
cipher.finish();
varencrypted=cipher.output.getBytes();
vartag=cipher.mode.tag.getBytes();
// send 'encrypted', 'iv', 'tag', and result.encapsulation to recipient
// decrypt encapsulated 16-byte secret key
varkdf1=newforge.kem.kdf1(forge.md.sha1.create());
varkem=forge.kem.rsa.create(kdf1);
varkey=kem.decrypt(keypair.privateKey,result.encapsulation,16);
// decrypt some bytes
vardecipher=forge.cipher.createDecipher('AES-GCM',key);
decipher.start({iv:iv,tag:tag});
decipher.update(forge.util.createBuffer(encrypted));
varpass=decipher.finish();
// pass is false if there was a failure (eg: authentication tag didn't match)
if(pass){
// outputs 'hello world!'
console.log(decipher.output.getBytes());
}
Examples
varpki=forge.pki;
// convert a PEM-formatted public key to a Forge public key
varpublicKey=pki.publicKeyFromPem(pem);
// convert a Forge public key to PEM-format
varpem=pki.publicKeyToPem(publicKey);
// convert an ASN.1 SubjectPublicKeyInfo to a Forge public key
varpublicKey=pki.publicKeyFromAsn1(subjectPublicKeyInfo);
// convert a Forge public key to an ASN.1 SubjectPublicKeyInfo
varsubjectPublicKeyInfo=pki.publicKeyToAsn1(publicKey);
// gets a SHA-1 RSAPublicKey fingerprint a byte buffer
pki.getPublicKeyFingerprint(key);
// gets a SHA-1 SubjectPublicKeyInfo fingerprint a byte buffer
pki.getPublicKeyFingerprint(key,{type:'SubjectPublicKeyInfo'});
// gets a hex-encoded, colon-delimited SHA-1 RSAPublicKey public key fingerprint
pki.getPublicKeyFingerprint(key,{encoding:'hex',delimiter:':'});
// gets a hex-encoded, colon-delimited SHA-1 SubjectPublicKeyInfo public key fingerprint
pki.getPublicKeyFingerprint(key,{
type:'SubjectPublicKeyInfo',
encoding:'hex',
delimiter:':'
});
// gets a hex-encoded, colon-delimited MD5 RSAPublicKey public key fingerprint
pki.getPublicKeyFingerprint(key,{
md:forge.md.md5.create(),
encoding:'hex',
delimiter:':'
});
// creates a CA store
varcaStore=pki.createCaStore([/* PEM-encoded cert */,...]);
// add a certificate to the CA store
caStore.addCertificate(certObjectOrPemString);
// gets the issuer (its certificate) for the given certificate
varissuerCert=caStore.getIssuer(subjectCert);
// verifies a certificate chain against a CA store
pki.verifyCertificateChain(caStore,chain,customVerifyCallback);
// signs a certificate using the given private key
cert.sign(privateKey);
// signs a certificate using SHA-256 instead of SHA-1
cert.sign(privateKey,forge.md.sha256.create());
// verifies an issued certificate using the certificates public key
varverified=issuer.verify(issued);
// generate a keypair and create an X.509v3 certificate
varkeys=pki.rsa.generateKeyPair(2048);
varcert=pki.createCertificate();
cert.publicKey=keys.publicKey;
// alternatively set public key from a csr
//cert.publicKey = csr.publicKey;
// NOTE: serialNumber is the hex encoded value of an ASN.1 INTEGER.
// Conforming CAs should ensure serialNumber is:
// - no more than 20 octets
// - non-negative (prefix a '00' if your value starts with a '1' bit)
cert.serialNumber='01';
cert.validity.notBefore=newDate();
cert.validity.notAfter=newDate();
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear()+1);
varattrs=[{
name:'commonName',
value:'example.org'
},{
name:'countryName',
value:'US'
},{
shortName:'ST',
value:'Virginia'
},{
name:'localityName',
value:'Blacksburg'
},{
name:'organizationName',
value:'Test'
},{
shortName:'OU',
value:'Test'
}];
cert.setSubject(attrs);
// alternatively set subject from a csr
//cert.setSubject(csr.subject.attributes);
cert.setIssuer(attrs);
cert.setExtensions([{
name:'basicConstraints',
cA:true
},{
name:'keyUsage',
keyCertSign:true,
digitalSignature:true,
nonRepudiation:true,
keyEncipherment:true,
dataEncipherment:true
},{
name:'extKeyUsage',
serverAuth:true,
clientAuth:true,
codeSigning:true,
emailProtection:true,
timeStamping:true
},{
name:'nsCertType',
client:true,
server:true,
email:true,
objsign:true,
sslCA:true,
emailCA:true,
objCA:true
},{
name:'subjectAltName',
altNames:[{
type:6,// URI
value:'http://example.org/webid#me'
},{
type:7,// IP
ip:'127.0.0.1'
}]
},{
name:'subjectKeyIdentifier'
}]);
/* alternatively set extensions from a csr
var extensions = csr.getAttribute({name: 'extensionRequest'}).extensions;
// optionally add more extensions
extensions.push.apply(extensions, [{
name: 'basicConstraints',
cA: true
}, {
name: 'keyUsage',
keyCertSign: true,
digitalSignature: true,
nonRepudiation: true,
keyEncipherment: true,
dataEncipherment: true
}]);
cert.setExtensions(extensions);
*/
// self-sign certificate
cert.sign(keys.privateKey);
// convert a Forge certificate to PEM
varpem=pki.certificateToPem(cert);
// convert a Forge certificate from PEM
varcert=pki.certificateFromPem(pem);
// convert an ASN.1 X.509x3 object to a Forge certificate
varcert=pki.certificateFromAsn1(obj);
// convert a Forge certificate to an ASN.1 X.509v3 object
varasn1Cert=pki.certificateToAsn1(cert);
Provides the password-based key-derivation function fromPKCS#5.
Examples
// generate a password-based 16-byte key
// note an optional message digest can be passed as the final parameter
varsalt=forge.random.getBytesSync(128);
varderivedKey=forge.pkcs5.pbkdf2('password',salt,numIterations,16);
// generate key asynchronously
// note an optional message digest can be passed before the callback
forge.pkcs5.pbkdf2('password',salt,numIterations,16,function(err,derivedKey){
// do something w/derivedKey
});
Provides cryptographically protected messages fromPKCS#7.
Examples
// convert a message from PEM
varp7=forge.pkcs7.messageFromPem(pem);
// look at p7.recipients
// find a recipient by the issuer of a certificate
varrecipient=p7.findRecipient(cert);
// decrypt
p7.decrypt(p7.recipients[0],privateKey);
// create a p7 enveloped message
varp7=forge.pkcs7.createEnvelopedData();
// add a recipient
varcert=forge.pki.certificateFromPem(certPem);
p7.addRecipient(cert);
// set content
p7.content=forge.util.createBuffer('Hello');
// encrypt
p7.encrypt();
// convert message to PEM
varpem=forge.pkcs7.messageToPem(p7);
// create a degenerate PKCS#7 certificate container
// (CRLs not currently supported, only certificates)
varp7=forge.pkcs7.createSignedData();
p7.addCertificate(certOrCertPem1);
p7.addCertificate(certOrCertPem2);
varpem=forge.pkcs7.messageToPem(p7);
// create PKCS#7 signed data with authenticatedAttributes
// attributes include: PKCS#9 content-type, message-digest, and signing-time
varp7=forge.pkcs7.createSignedData();
p7.content=forge.util.createBuffer('Some content to be signed.','utf8');
p7.addCertificate(certOrCertPem);
p7.addSigner({
key:privateKeyAssociatedWithCert,
certificate:certOrCertPem,
digestAlgorithm:forge.pki.oids.sha256,
authenticatedAttributes:[{
type:forge.pki.oids.contentType,
value:forge.pki.oids.data
},{
type:forge.pki.oids.messageDigest
// value will be auto-populated at signing time
},{
type:forge.pki.oids.signingTime,
// value can also be auto-populated at signing time
value:newDate()
}]
});
p7.sign();
varpem=forge.pkcs7.messageToPem(p7);
// PKCS#7 Sign in detached mode.
// Includes the signature and certificate without the signed data.
p7.sign({detached:true});
Examples
varpki=forge.pki;
// convert a PEM-formatted private key to a Forge private key
varprivateKey=pki.privateKeyFromPem(pem);
// convert a Forge private key to PEM-format
varpem=pki.privateKeyToPem(privateKey);
// convert an ASN.1 PrivateKeyInfo or RSAPrivateKey to a Forge private key
varprivateKey=pki.privateKeyFromAsn1(rsaPrivateKey);
// convert a Forge private key to an ASN.1 RSAPrivateKey
varrsaPrivateKey=pki.privateKeyToAsn1(privateKey);
// wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo
varprivateKeyInfo=pki.wrapRsaPrivateKey(rsaPrivateKey);
// convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM
varpem=pki.privateKeyInfoToPem(privateKeyInfo);
// encrypts a PrivateKeyInfo using a custom password and
// outputs an EncryptedPrivateKeyInfo
varencryptedPrivateKeyInfo=pki.encryptPrivateKeyInfo(
privateKeyInfo,'myCustomPasswordHere',{
algorithm:'aes256',// 'aes128', 'aes192', 'aes256', '3des'
});
// decrypts an ASN.1 EncryptedPrivateKeyInfo that was encrypted
// with a custom password
varprivateKeyInfo=pki.decryptPrivateKeyInfo(
encryptedPrivateKeyInfo,'myCustomPasswordHere');
// converts an EncryptedPrivateKeyInfo to PEM
varpem=pki.encryptedPrivateKeyToPem(encryptedPrivateKeyInfo);
// converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format
varencryptedPrivateKeyInfo=pki.encryptedPrivateKeyFromPem(pem);
// wraps and encrypts a Forge private key and outputs it in PEM format
varpem=pki.encryptRsaPrivateKey(privateKey,'password');
// encrypts a Forge private key and outputs it in PEM format using OpenSSL's
// proprietary legacy format + encapsulated PEM headers (DEK-Info)
varpem=pki.encryptRsaPrivateKey(privateKey,'password',{legacy:true});
// decrypts a PEM-formatted, encrypted private key
varprivateKey=pki.decryptRsaPrivateKey(pem,'password');
// sets an RSA public key from a private key
varpublicKey=pki.setRsaPublicKey(privateKey.n,privateKey.e);
Provides certification requests or certificate signing requests (CSR) from PKCS#10.
Examples
// generate a key pair
varkeys=forge.pki.rsa.generateKeyPair(2048);
// create a certification request (CSR)
varcsr=forge.pki.createCertificationRequest();
csr.publicKey=keys.publicKey;
csr.setSubject([{
name:'commonName',
value:'example.org'
},{
name:'countryName',
value:'US'
},{
shortName:'ST',
value:'Virginia'
},{
name:'localityName',
value:'Blacksburg'
},{
name:'organizationName',
value:'Test'
},{
shortName:'OU',
value:'Test'
}]);
// set (optional) attributes
csr.setAttributes([{
name:'challengePassword',
value:'password'
},{
name:'unstructuredName',
value:'My Company, Inc.'
},{
name:'extensionRequest',
extensions:[{
name:'subjectAltName',
altNames:[{
// 2 is DNS type
type:2,
value:'test.domain.com'
},{
type:2,
value:'other.domain.com',
},{
type:2,
value:'www.domain.net'
}]
}]
}]);
// sign certification request
csr.sign(keys.privateKey);
// verify certification request
varverified=csr.verify();
// convert certification request to PEM-format
varpem=forge.pki.certificationRequestToPem(csr);
// convert a Forge certification request from PEM-format
varcsr=forge.pki.certificationRequestFromPem(pem);
// get an attribute
csr.getAttribute({name:'challengePassword'});
// get extensions array
csr.getAttribute({name:'extensionRequest'}).extensions;
Provides the cryptographic archive file format fromPKCS#12.
Note for Chrome/Firefox/iOS/similar users:If you have trouble importing
a PKCS#12 container, try using the TripleDES algorithm. It can be passed
toforge.pkcs12.toPkcs12Asn1
using the{algorithm: '3des'}
option.
Examples
// decode p12 from base64
varp12Der=forge.util.decode64(p12b64);
// get p12 as ASN.1 object
varp12Asn1=forge.asn1.fromDer(p12Der);
// decrypt p12 using the password 'password'
varp12=forge.pkcs12.pkcs12FromAsn1(p12Asn1,'password');
// decrypt p12 using non-strict parsing mode (resolves some ASN.1 parse errors)
varp12=forge.pkcs12.pkcs12FromAsn1(p12Asn1,false,'password');
// decrypt p12 using literally no password (eg: Mac OS X/apple push)
varp12=forge.pkcs12.pkcs12FromAsn1(p12Asn1);
// decrypt p12 using an "empty" password (eg: OpenSSL with no password input)
varp12=forge.pkcs12.pkcs12FromAsn1(p12Asn1,'');
// p12.safeContents is an array of safe contents, each of
// which contains an array of safeBags
// get bags by friendlyName
varbags=p12.getBags({friendlyName:'test'});
// bags are key'd by attribute type (here "friendlyName" )
// and the key values are an array of matching objects
varcert=bags.friendlyName[0];
// get bags by localKeyId
varbags=p12.getBags({localKeyId:buffer});
// bags are key'd by attribute type (here "localKeyId" )
// and the key values are an array of matching objects
varcert=bags.localKeyId[0];
// get bags by localKeyId (input in hex)
varbags=p12.getBags({localKeyIdHex:'7b59377ff142d0be4565e9ac3d396c01401cd879'});
// bags are key'd by attribute type (here "localKeyId", *not* "localKeyIdHex" )
// and the key values are an array of matching objects
varcert=bags.localKeyId[0];
// get bags by type
varbags=p12.getBags({bagType:forge.pki.oids.certBag});
// bags are key'd by bagType and each bagType key's value
// is an array of matches (in this case, certificate objects)
varcert=bags[forge.pki.oids.certBag][0];
// get bags by friendlyName and filter on bag type
varbags=p12.getBags({
friendlyName:'test',
bagType:forge.pki.oids.certBag
});
// get key bags
varbags=p12.getBags({bagType:forge.pki.oids.keyBag});
// get key
varbag=bags[forge.pki.oids.keyBag][0];
varkey=bag.key;
// if the key is in a format unrecognized by forge then
// bag.key will be `null`, use bag.asn1 to get the ASN.1
// representation of the key
if(bag.key===null){
varkeyAsn1=bag.asn1;
// can now convert back to DER/PEM/etc for export
}
// generate a p12 using AES (default)
varp12Asn1=forge.pkcs12.toPkcs12Asn1(
privateKey,certificateChain,'password');
// generate a p12 that can be imported by Chrome/Firefox/iOS
// (requires the use of Triple DES instead of AES)
varp12Asn1=forge.pkcs12.toPkcs12Asn1(
privateKey,certificateChain,'password',
{algorithm:'3des'});
// base64-encode p12
varp12Der=forge.asn1.toDer(p12Asn1).getBytes();
varp12b64=forge.util.encode64(p12Der);
// create download link for p12
vara=document.createElement('a');
a.download='example.p12';
a.setAttribute('href','data:application/x-pkcs12;base64,'+p12b64);
a.appendChild(document.createTextNode('Download'));
ProvidesASN.1DER encoding and decoding.
Examples
varasn1=forge.asn1;
// create a SubjectPublicKeyInfo
varsubjectPublicKeyInfo=
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.SEQUENCE,true,[
// AlgorithmIdentifier
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.SEQUENCE,true,[
// algorithm
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.OID,false,
asn1.oidToDer(pki.oids['rsaEncryption']).getBytes()),
// parameters (null)
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.NULL,false,'')
]),
// subjectPublicKey
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.BITSTRING,false,[
// RSAPublicKey
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.SEQUENCE,true,[
// modulus (n)
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.INTEGER,false,
_bnToBytes(key.n)),
// publicExponent (e)
asn1.create(asn1.Class.UNIVERSAL,asn1.Type.INTEGER,false,
_bnToBytes(key.e))
])
])
]);
// serialize an ASN.1 object to DER format
varderBuffer=asn1.toDer(subjectPublicKeyInfo);
// deserialize to an ASN.1 object from a byte buffer filled with DER data
varobject=asn1.fromDer(derBuffer);
// convert an OID dot-separated string to a byte buffer
varderOidBuffer=asn1.oidToDer('1.2.840.113549.1.1.5');
// convert a byte buffer with a DER-encoded OID to a dot-separated string
console.log(asn1.derToOid(derOidBuffer));
// output: 1.2.840.113549.1.1.5
// validates that an ASN.1 object matches a particular ASN.1 structure and
// captures data of interest from that structure for easy access
varpublicKeyValidator={
name:'SubjectPublicKeyInfo',
tagClass:asn1.Class.UNIVERSAL,
type:asn1.Type.SEQUENCE,
constructed:true,
captureAsn1:'subjectPublicKeyInfo',
value:[{
name:'SubjectPublicKeyInfo.AlgorithmIdentifier',
tagClass:asn1.Class.UNIVERSAL,
type:asn1.Type.SEQUENCE,
constructed:true,
value:[{
name:'AlgorithmIdentifier.algorithm',
tagClass:asn1.Class.UNIVERSAL,
type:asn1.Type.OID,
constructed:false,
capture:'publicKeyOid'
}]
},{
// subjectPublicKey
name:'SubjectPublicKeyInfo.subjectPublicKey',
tagClass:asn1.Class.UNIVERSAL,
type:asn1.Type.BITSTRING,
constructed:false,
value:[{
// RSAPublicKey
name:'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey',
tagClass:asn1.Class.UNIVERSAL,
type:asn1.Type.SEQUENCE,
constructed:true,
optional:true,
captureAsn1:'rsaPublicKey'
}]
}]
};
varcapture={};
varerrors=[];
if(!asn1.validate(
publicKeyValidator,subjectPublicKeyInfo,validator,capture,errors)){
throw'ASN.1 object is not a SubjectPublicKeyInfo.';
}
// capture.subjectPublicKeyInfo contains the full ASN.1 object
// capture.rsaPublicKey contains the full ASN.1 object for the RSA public key
// capture.publicKeyOid only contains the value for the OID
varoid=asn1.derToOid(capture.publicKeyOid);
if(oid!==pki.oids['rsaEncryption']){
throw'Unsupported OID.';
}
// pretty print an ASN.1 object to a string for debugging purposes
asn1.prettyPrint(object);
ProvidesSHA-1message digests.
Examples
varmd=forge.md.sha1.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
ProvidesSHA-256message digests.
Examples
varmd=forge.md.sha256.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
ProvidesSHA-384message digests.
Examples
varmd=forge.md.sha384.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1
ProvidesSHA-512message digests.
Examples
// SHA-512
varmd=forge.md.sha512.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: 07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6
// SHA-512/224
varmd=forge.md.sha512.sha224.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: 944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37
// SHA-512/256
varmd=forge.md.sha512.sha256.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d
ProvidesMD5message digests.
Examples
varmd=forge.md.md5.create();
md.update('The quick brown fox jumps over the lazy dog');
console.log(md.digest().toHex());
// output: 9e107d9d372bb6826bd81d3542a419d6
ProvidesHMACw/any supported message digest algorithm.
Examples
varhmac=forge.hmac.create();
hmac.start('sha1','Jefe');
hmac.update('what do ya want for nothing?');
console.log(hmac.digest().toHex());
// output: effcdf6ae5eb2fa2d27416d5f184df9c259a7c79
Provides an API for generating large, random, probable primes.
Examples
// generate a random prime on the main JS thread
varbits=1024;
forge.prime.generateProbablePrime(bits,function(err,num){
console.log('random prime',num.toString(16));
});
// generate a random prime using Web Workers (if available, otherwise
// falls back to the main thread)
varbits=1024;
varoptions={
algorithm:{
name:'PRIMEINC',
workers:-1// auto-optimize # of workers
}
};
forge.prime.generateProbablePrime(bits,options,function(err,num){
console.log('random prime',num.toString(16));
});
Provides aFortuna-based cryptographically-secure pseudo-random number generator, to be used with a cryptographic function backend, e.g.AES.An implementation usingAESas a backend is provided. An API for collecting entropy is given, though if window.crypto.getRandomValues is available, it will be used automatically.
Examples
// get some random bytes synchronously
varbytes=forge.random.getBytesSync(32);
console.log(forge.util.bytesToHex(bytes));
// get some random bytes asynchronously
forge.random.getBytes(32,function(err,bytes){
console.log(forge.util.bytesToHex(bytes));
});
// collect some entropy if you'd like
forge.random.collect(someRandomBytes);
jQuery().mousemove(function(e){
forge.random.collectInt(e.clientX,16);
forge.random.collectInt(e.clientY,16);
});
// specify a seed file for use with the synchronous API if you'd like
forge.random.seedFileSync=function(needed){
// get 'needed' number of random bytes from somewhere
returnfetchedRandomBytes;
};
// specify a seed file for use with the asynchronous API if you'd like
forge.random.seedFile=function(needed,callback){
// get the 'needed' number of random bytes from somewhere
callback(null,fetchedRandomBytes);
});
// register the main thread to send entropy or a Web Worker to receive
// entropy on demand from the main thread
forge.random.registerWorker(self);
// generate a new instance of a PRNG with no collected entropy
varmyPrng=forge.random.createInstance();
Provides queuing and synchronizing tasks in a web application.
Examples
// TODO
Provides utility functions, including byte buffer support, base64, bytes to/from hex, zlib inflate/deflate, etc.
Examples
// encode/decode base64
varencoded=forge.util.encode64(str);
varstr=forge.util.decode64(encoded);
// encode/decode UTF-8
varencoded=forge.util.encodeUtf8(str);
varstr=forge.util.decodeUtf8(encoded);
// bytes to/from hex
varbytes=forge.util.hexToBytes(hex);
varhex=forge.util.bytesToHex(bytes);
// create an empty byte buffer
varbuffer=forge.util.createBuffer();
// create a byte buffer from raw binary bytes
varbuffer=forge.util.createBuffer(input,'raw');
// create a byte buffer from utf8 bytes
varbuffer=forge.util.createBuffer(input,'utf8');
// get the length of the buffer in bytes
buffer.length();
// put bytes into the buffer
buffer.putBytes(bytes);
// put a 32-bit integer into the buffer
buffer.putInt32(10);
// buffer to hex
buffer.toHex();
// get a copy of the bytes in the buffer
bytes.bytes(/* count */);
// empty this buffer and get its contents
bytes.getBytes(/* count */);
// convert a forge buffer into a Node.js Buffer
// make sure you specify the encoding as 'binary'
varforgeBuffer=forge.util.createBuffer();
varnodeBuffer=Buffer.from(forgeBuffer.getBytes(),'binary');
// convert a Node.js Buffer into a forge buffer
// make sure you specify the encoding as 'binary'
varnodeBuffer=Buffer.from('CAFE','hex');
varforgeBuffer=forge.util.createBuffer(nodeBuffer.toString('binary'));
Provides logging to a javascript console using various categories and levels of verbosity.
Examples
// TODO
Theflash READMEprovides details on rebuilding the optional Flash component used for networking. It also provides details on Policy Server support.
When using this code please keep the following in mind:
- Cryptography is hard. Please review and test this code before depending on it for critical functionality.
- The nature of JavaScript is that execution of this code depends on trusting a very large set of JavaScript tools and systems. Consider runtime variations, runtime characteristics, runtime optimization, code optimization, code minimization, code obfuscation, bundling tools, possible bugs, the Forge code itself, and so on.
- If using pre-built bundles fromNPM,another CDN, or similar, be aware someone else ran the tools to create those files.
- Use a secure transport channel such asTLSto load scripts and consider using additional security mechanisms such asSubresource Integrityscript attributes.
- Use "native" functionality where possible. This can be critical when dealing with performance and random number generation. Note that the JavaScript random number algorithms should perform well if given suitable entropy.
- Understand possible attacks against cryptographic systems. For instance side channel and timing attacks may be possible due to the difficulty in implementing constant time algorithms in pure JavaScript.
- Certain features in this library are less susceptible to attacks depending on usage. This primarily includes features that deal with data format manipulation or those that are not involved in communication.
- https://digitalbazaar.com/2010/07/20/javascript-tls-1/
- https://digitalbazaar.com/2010/07/20/javascript-tls-2/
- Code:https://github.com/digitalbazaar/forge
- Bugs:https://github.com/digitalbazaar/forge/issues
- Email:[email protected]
- IRC:#forgejsonLibera.Chat(people may also be onfreenodefor historical reasons).
Financial support is welcome and helps contribute to futher development:
- ForPayPalplease send to[email protected].
- Something else? Please contact[email protected].