### Install Flex SDK Dependency Source: https://github.com/digitalbazaar/forge/blob/main/flash/README.md Installs the Flex SDK using npm. This is a prerequisite for building the SocketPool.swf component. ```bash npm install ``` -------------------------------- ### Build Forge for browser use Source: https://github.com/digitalbazaar/forge/blob/main/README.md Install dependencies and run the build script to create browser-ready bundles. This process generates 'dist/forge.js' and 'dist/forge.min.js'. ```bash npm install npm run build ``` -------------------------------- ### Create and Send HTTP GET Request Source: https://github.com/digitalbazaar/forge/blob/main/README.md Demonstrates how to create an HTTP GET request using forge.http and prepare it for sending. Includes logic for receiving and parsing an HTTP response, handling headers and body incrementally. ```javascript var request = forge.http.createRequest({method: 'GET', path: url.path}); sendSomehow(request.toString()); var buffer = forge.util.createBuffer(); var response = forge.http.createResponse(); var someAsyncDataHandler = 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); } } } }; ``` -------------------------------- ### Create HMAC-SHA256, HMAC-SHA1, and HMAC-MD5 Source: https://context7.com/digitalbazaar/forge/llms.txt Demonstrates creating Hash-based Message Authentication Codes (HMAC) using SHA-256, SHA-1, and MD5. Shows how to start an HMAC with a digest algorithm and secret key, update it with a message, and retrieve the MAC. Includes examples of reusing keys and using a message digest object directly. ```javascript var forge = require('node-forge'); // HMAC-SHA256 var hmac = forge.hmac.create(); hmac.start('sha256', 'my-secret-key'); hmac.update('message to authenticate'); console.log('HMAC-SHA256:', hmac.digest().toHex()); // HMAC-SHA1 (classic) var hmac1 = forge.hmac.create(); hmac1.start('sha1', 'Jefe'); hmac1.update('what do ya want for nothing?'); console.log('HMAC-SHA1:', hmac1.digest().toHex()); // effcdf6ae5eb2fa2d27416d5f184df9c259a7c79 // HMAC-MD5 var hmacMd5 = forge.hmac.create(); hmacMd5.start('md5', 'secret'); hmacMd5.update('data'); console.log('HMAC-MD5:', hmacMd5.digest().toHex()); // Reuse the same HMAC object for a new message (same key) hmac.start('sha256', null); // null = reuse previous key hmac.update('another message'); console.log('HMAC-SHA256 (reused key):', hmac.digest().toHex()); // Using a message digest object directly var md = forge.md.sha256.create(); var hmacWithMd = forge.hmac.create(); hmacWithMd.start(md, 'my-key'); hmacWithMd.update('payload'); console.log('HMAC (md object):', hmacWithMd.getMac().toHex()); ``` -------------------------------- ### Run Test Server for Browser Tests Source: https://github.com/digitalbazaar/forge/blob/main/README.md Start the custom test server that provides HTTP or HTTPS URLs for running browser-based tests. ```bash npm run test-server ``` -------------------------------- ### Install node-forge with npm Source: https://github.com/digitalbazaar/forge/blob/main/README.md Install the node-forge package using npm for Node.js projects. This is the recommended method for server-side JavaScript. ```bash npm install node-forge ``` -------------------------------- ### Install node-forge Source: https://context7.com/digitalbazaar/forge/llms.txt Install the node-forge npm package. You can optionally disable native code to force pure JavaScript, which is useful for testing. ```bash npm install node-forge ``` ```javascript // Node.js var forge = require('node-forge'); // Disable native code (force pure JS, e.g. for testing) forge.options.usePureJavaScript = true; ``` -------------------------------- ### Create and Use SHA-256, SHA-512, SHA-384, SHA-1, MD5, and SHA-512/256 Digests Source: https://context7.com/digitalbazaar/forge/llms.txt Demonstrates creating and using various message digest algorithms including SHA-256, SHA-512, SHA-384, SHA-1, MD5, and the SHA-512/256 variant. Shows how to update the digest with data and retrieve the hexadecimal representation of the digest. Also includes an example of streaming updates. ```javascript var forge = require('node-forge'); // SHA-256 var sha256 = forge.md.sha256.create(); sha256.update('The quick brown fox jumps over the lazy dog', 'utf8'); console.log('SHA-256:', sha256.digest().toHex()); // d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592 // SHA-512 var sha512 = forge.md.sha512.create(); sha512.update('hello', 'utf8'); console.log('SHA-512:', sha512.digest().toHex()); // SHA-384 var sha384 = forge.md.sha384.create(); sha384.update('hello', 'utf8'); console.log('SHA-384:', sha384.digest().toHex()); // SHA-1 var sha1 = forge.md.sha1.create(); sha1.update('hello', 'utf8'); console.log('SHA-1:', sha1.digest().toHex()); // MD5 var md5 = forge.md.md5.create(); md5.update('hello', 'utf8'); console.log('MD5:', md5.digest().toHex()); // SHA-512/256 variant var sha512_256 = forge.md.sha512.sha256.create(); sha512_256.update('hello', 'utf8'); console.log('SHA-512/256:', sha512_256.digest().toHex()); // Streaming: update multiple times var md = forge.md.sha256.create(); md.update('part 1 '); md.update('part 2'); console.log('Streaming SHA-256:', md.digest().toHex()); ``` -------------------------------- ### X.509 Certificate Generation and Signing Source: https://github.com/digitalbazaar/forge/blob/main/README.md Provides a comprehensive example of generating an RSA key pair, creating a new X.509v3 certificate, setting subject and issuer attributes, defining various extensions (basic constraints, key usage, subject alternative names), and self-signing the certificate. ```javascript var pki = forge.pki; // generate a keypair and create an X.509v3 certificate var keys = pki.rsa.generateKeyPair(2048); var cert = 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 = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); var attrs = [{ 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); ``` -------------------------------- ### RC2 Encryption and Decryption Example Source: https://github.com/digitalbazaar/forge/blob/main/README.md Demonstrates how to generate a random key and IV, then use them to encrypt and decrypt data using RC2 in CBC mode. Ensure the key and IV are kept secret and are the same for encryption and decryption. ```javascript var key = forge.random.getBytesSync(16); var iv = forge.random.getBytesSync(8); // encrypt some bytes var cipher = forge.rc2.createEncryptionCipher(key); cipher.start(iv); cipher.update(forge.util.createBuffer(someBytes)); cipher.finish(); var encrypted = cipher.output; // outputs encrypted hex console.log(encrypted.toHex()); // decrypt some bytes var cipher = forge.rc2.createDecryptionCipher(key); cipher.start(iv); cipher.update(encrypted); cipher.finish(); // outputs decrypted hex console.log(cipher.output.toHex()); ``` -------------------------------- ### Compute SHA-512 Variants with Forge Source: https://github.com/digitalbazaar/forge/blob/main/README.md Provides examples for computing SHA-512, SHA-512/224, and SHA-512/256 message digests. Each variant requires its specific creator function. ```javascript // SHA-512 var md = 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 var md = 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 var md = forge.md.sha512.sha256.create(); md.update('The quick brown fox jumps over the lazy dog'); console.log(md.digest().toHex()); // output: dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d ``` -------------------------------- ### Run automated tests with Node.js Source: https://github.com/digitalbazaar/forge/blob/main/README.md Execute the automated test suite for Forge within a Node.js environment. Ensure you have installed dependencies first. ```bash npm test ``` -------------------------------- ### Node.js Encryption with OpenSSL Compatibility Source: https://github.com/digitalbazaar/forge/blob/main/README.md Demonstrates using Node.js and forge to encrypt data, mimicking OpenSSL's 'enc' command. This example uses 3DES with a derived key and IV from a password and salt. Note that OpenSSL's default key derivation is considered less secure. ```javascript var forge = require('node-forge'); var fs = require('fs'); // openssl enc -des3 -in input.txt -out input.enc function encrypt(password) { var input = fs.readFileSync('input.txt', {encoding: 'binary'}); // 3DES key and IV sizes var keySize = 24; var ivSize = 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. var salt = forge.random.getBytesSync(8); // var md = forge.md.sha1.create(); // "-md sha1" var derivedBytes = forge.pbe.opensslDeriveBytes( password, salt, keySize + ivSize/*, md*/); var buffer = forge.util.createBuffer(derivedBytes); var key = buffer.getBytes(keySize); var iv = buffer.getBytes(ivSize); ``` -------------------------------- ### Byte Buffer Operations Source: https://github.com/digitalbazaar/forge/blob/main/README.md Demonstrates common operations on a forge.util.ByteBuffer, including getting its length, putting bytes or integers into it, converting it to hex, and retrieving its contents as bytes. ```javascript // 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 */); ``` -------------------------------- ### Create and Parse PKCS#12 Archives Source: https://context7.com/digitalbazaar/forge/llms.txt Shows how to create a PKCS#12 bundle with a private key and certificate, and then parse it to extract the certificate and private key. Specify the '3des' algorithm for compatibility with older systems. ```javascript var forge = require('node-forge'); // --- Create a PKCS#12 bundle --- var keys = forge.pki.rsa.generateKeyPair(2048); var cert = forge.pki.createCertificate(); cert.publicKey = keys.publicKey; cert.serialNumber = '01'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); var attrs = [{name: 'commonName', value: 'pkcs12.example.com'}]; cert.setSubject(attrs); cert.setIssuer(attrs); cert.setExtensions([{name: 'basicConstraints', cA: true}]); cert.sign(keys.privateKey); // Build P12 (AES encryption by default; use 3des for Chrome/Firefox/iOS compat) var p12Asn1 = forge.pkcs12.toPkcs12Asn1( keys.privateKey, [cert], 'p12password', {algorithm: '3des', friendlyName: 'my-cert'} ); var p12Der = forge.asn1.toDer(p12Asn1).getBytes(); var p12b64 = forge.util.encode64(p12Der); console.log('P12 base64 length:', p12b64.length); // --- Parse a PKCS#12 bundle --- var p12FromDer = forge.pkcs12.pkcs12FromAsn1( forge.asn1.fromDer(forge.util.decode64(p12b64)), 'p12password' ); // Get certificates var certBags = p12FromDer.getBags({bagType: forge.pki.oids.certBag}); var extractedCert = certBags[forge.pki.oids.certBag][0].cert; console.log('Extracted cert CN:', extractedCert.subject.getField('CN').value); // Get private key var keyBags = p12FromDer.getBags({bagType: forge.pki.oids.pkcs8ShroudedKeyBag}); var extractedKey = keyBags[forge.pki.oids.pkcs8ShroudedKeyBag][0].key; console.log('Extracted key type:', typeof extractedKey); // Get bags by friendlyName var named = p12FromDer.getBags({friendlyName: 'my-cert'}); console.log('Named bag found:', !!named.friendlyName[0]); ``` -------------------------------- ### Require node-forge in Node.js Source: https://github.com/digitalbazaar/forge/blob/main/README.md Import the node-forge library into your Node.js project after installation. This makes the forge object available for use. ```javascript var forge = require('node-forge'); ``` -------------------------------- ### Get Random Bytes Synchronously Source: https://github.com/digitalbazaar/forge/blob/main/README.md Retrieves a specified number of cryptographically secure random bytes synchronously. The forge.random module is required. ```javascript // get some random bytes synchronously var bytes = forge.random.getBytesSync(32); console.log(forge.util.bytesToHex(bytes)); ``` -------------------------------- ### X.509 Certificate Signing and Verification Source: https://github.com/digitalbazaar/forge/blob/main/README.md Illustrates how to sign an X.509 certificate using a private key, with an option to specify the hashing algorithm (e.g., SHA-256). Also demonstrates verifying an issued certificate against its issuer's public key. ```javascript var pki = forge.pki; // 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 var verified = issuer.verify(issued); ``` -------------------------------- ### Run Automated Tests with Browserify Bundler Source: https://github.com/digitalbazaar/forge/blob/main/README.md Configure automated tests to use Browserify as the bundler instead of the default webpack. ```bash BUNDLER=browserify npm run test-karma ``` -------------------------------- ### Get Random Bytes Asynchronously Source: https://github.com/digitalbazaar/forge/blob/main/README.md Retrieves a specified number of cryptographically secure random bytes asynchronously. A callback function is used to handle the result. ```javascript // get some random bytes asynchronously forge.random.getBytes(32, function(err, bytes) { console.log(forge.util.bytesToHex(bytes)); }); ``` -------------------------------- ### Create TLS Server Source: https://github.com/digitalbazaar/forge/blob/main/README.md Instantiate a TLS server connection. Requires server configuration, CA store, session cache, and supported cipher suites. The `verifyClient` option and `verify` callback enforce client certificate validation. Callbacks manage connection events and data flow, similar to the client. ```javascript var server = 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) { var cn = 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.' }; } } return verified; }, 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) { return myServerCertificate; }, getPrivateKey: function(connection, cert) { return myServerPrivateKey; }, 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); } }); ``` -------------------------------- ### Convert Forge Buffer to Node.js Buffer Source: https://github.com/digitalbazaar/forge/blob/main/README.md Converts a forge.util.ByteBuffer object into a Node.js Buffer. Ensure the encoding is specified as 'binary' when getting bytes from the forge buffer. ```javascript // convert a forge buffer into a Node.js Buffer // make sure you specify the encoding as 'binary' var forgeBuffer = forge.util.createBuffer(); var nodeBuffer = Buffer.from(forgeBuffer.getBytes(), 'binary'); ``` -------------------------------- ### X.509 Public Key Conversion and Fingerprinting Source: https://github.com/digitalbazaar/forge/blob/main/README.md Demonstrates converting PEM-formatted public keys to Forge objects and vice-versa. Also shows how to generate SHA-1 or MD5 fingerprints of public keys in various formats. ```javascript var pki = forge.pki; // convert a PEM-formatted public key to a Forge public key var publicKey = pki.publicKeyFromPem(pem); // convert a Forge public key to PEM-format var pem = pki.publicKeyToPem(publicKey); // convert an ASN.1 SubjectPublicKeyInfo to a Forge public key var publicKey = pki.publicKeyFromAsn1(subjectPublicKeyInfo); // convert a Forge public key to an ASN.1 SubjectPublicKeyInfo var subjectPublicKeyInfo = 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: ':' }); ``` -------------------------------- ### ASN.1 DER Encoding and Decoding Source: https://context7.com/digitalbazaar/forge/llms.txt Provides low-level ASN.1 DER encoding, decoding, and structural validation. Includes examples for creating structures, serializing, deserializing, and validating with schemas. ```javascript var forge = require('node-forge'); var asn1 = forge.asn1; // --- Create an ASN.1 structure manually --- var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [ asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false, asn1.oidToDer('1.2.840.113549.1.1.1').getBytes()), // rsaEncryption asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '') ]); // --- Serialize to DER --- var derBuf = asn1.toDer(seq); console.log('DER (hex):', derBuf.toHex()); // --- Deserialize from DER --- var obj = asn1.fromDer(derBuf); console.log('Tag:', obj.type); // SEQUENCE type = 16 // --- OID conversion --- var oidDer = asn1.oidToDer('1.2.840.113549.1.1.1'); console.log('OID DER (hex):', oidDer.toHex()); var oidStr = asn1.derToOid(oidDer); console.log('OID string:', oidStr); // 1.2.840.113549.1.1.1 // --- Validate an ASN.1 structure with a schema --- var validator = { name: '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: 'algorithm' }] }; var capture = {}; var errors = []; if(asn1.validate(obj, validator, capture, errors)) { console.log('Validated. OID:', asn1.derToOid(capture.algorithm)); } else { console.error('Validation failed:', errors); } // --- Pretty print for debugging --- console.log(asn1.prettyPrint(obj)); ``` -------------------------------- ### Create TLS Client Source: https://github.com/digitalbazaar/forge/blob/main/README.md Instantiate a TLS client connection. Requires server configuration, CA store, session cache, and supported cipher suites. The `verify` callback handles certificate validation, and `connected`, `tlsDataReady`, `dataReady`, `closed`, and `error` callbacks manage connection events and data flow. ```javascript var client = 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) { var cn = 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.' }; } } return verified; }, 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) { return myClientPrivateKey; }, 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); ``` -------------------------------- ### Forge.util.ByteBuffer Operations Source: https://context7.com/digitalbazaar/forge/llms.txt Demonstrates creating and manipulating byte buffers using forge.util. Includes putting bytes, integers, and bytes, and converting to hex. Supports creation from UTF-8 strings and raw binary data. ```javascript var forge = require('node-forge'); // --- ByteBuffer --- var buf = forge.util.createBuffer(); buf.putBytes('\x00\x01\x02'); buf.putInt32(0xDEADBEEF); buf.putByte(0xFF); console.log('Buffer hex:', buf.toHex()); console.log('Buffer length:', buf.length()); // Create from UTF-8 string var utf8Buf = forge.util.createBuffer('hello 🌍', 'utf8'); // Create from raw binary var rawBuf = forge.util.createBuffer('\xDE\xAD', 'raw'); ``` -------------------------------- ### Create and Use PKCS#7 Signed and Enveloped Data Source: https://context7.com/digitalbazaar/forge/llms.txt Demonstrates creating a PKCS#7 signed message with a self-signed certificate and an enveloped (encrypted) message. Also shows how to decrypt the enveloped message. Ensure the forge library is required. ```javascript var forge = require('node-forge'); // --- Create a PKCS#7 signed message --- var keys = forge.pki.rsa.generateKeyPair(2048); var cert = forge.pki.createCertificate(); cert.publicKey = keys.publicKey; cert.serialNumber = '01'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); var attrs = [{name: 'commonName', value: 'signer.example.com'}]; cert.setSubject(attrs); cert.setIssuer(attrs); cert.setExtensions([{name: 'basicConstraints', cA: true}]); cert.sign(keys.privateKey, forge.md.sha256.create()); var p7 = forge.pkcs7.createSignedData(); p7.content = forge.util.createBuffer('Content to be signed', 'utf8'); p7.addCertificate(cert); p7.addSigner({ key: keys.privateKey, certificate: cert, digestAlgorithm: forge.pki.oids.sha256, authenticatedAttributes: [ {type: forge.pki.oids.contentType, value: forge.pki.oids.data}, {type: forge.pki.oids.messageDigest}, {type: forge.pki.oids.signingTime, value: new Date()} ] }); p7.sign(); var signedPem = forge.pkcs7.messageToPem(p7); console.log('Signed PKCS#7:\n', signedPem); // Detached signature p7.sign({detached: true}); // --- Create an enveloped (encrypted) PKCS#7 message --- var env = forge.pkcs7.createEnvelopedData(); env.addRecipient(cert); env.content = forge.util.createBuffer('Secret envelope content', 'utf8'); env.encrypt(); var envelopedPem = forge.pkcs7.messageToPem(env); // --- Decrypt an enveloped message --- var received = forge.pkcs7.messageFromPem(envelopedPem); var recipient = received.findRecipient(cert); received.decrypt(recipient, keys.privateKey); console.log('Decrypted envelope:', received.content.toString()); // Secret envelope content ``` -------------------------------- ### Encode SSH Keys using Forge Source: https://github.com/digitalbazaar/forge/blob/main/README.md Provides functions for encoding RSA keys into various SSH file formats. Supports encoding private keys to Putty PPK and OpenSSH formats, and public keys to OpenSSH format. Also includes a utility to get the public key fingerprint. ```javascript forge.ssh.privateKeyToPutty(privateKey, passphrase, comment); ``` ```javascript forge.ssh.publicKeyToOpenSSH(key, comment); ``` ```javascript forge.ssh.privateKeyToOpenSSH(privateKey, passphrase); ``` ```javascript forge.ssh.getPublicKeyFingerprint(key); ``` ```javascript forge.ssh.getPublicKeyFingerprint(key, {encoding: 'hex', delimiter: ':'}); ``` -------------------------------- ### Build Regular SocketPool.swf Component Source: https://github.com/digitalbazaar/forge/blob/main/flash/README.md Builds a regular SocketPool.swf component. This command is defined in the package.json file. ```bash npm run build ``` -------------------------------- ### Create MD5 Hash Source: https://github.com/digitalbazaar/forge/blob/main/README.md Use this to create an MD5 hash of a given string. Ensure the forge.md.md5 module is available. ```javascript var md = forge.md.md5.create(); md.update('The quick brown fox jumps over the lazy dog'); console.log(md.digest().toHex()); // output: 9e107d9d372bb6826bd81d3542a419d6 ``` -------------------------------- ### Generate and Manage PKCS#10 Certification Requests Source: https://github.com/digitalbazaar/forge/blob/main/README.md Use this snippet to generate a new key pair, create a certification request (CSR), set subject and attributes, sign the request, verify it, and convert it to and from PEM format. It also shows how to extract specific attributes and extensions. ```javascript // generate a key pair var keys = forge.pki.rsa.generateKeyPair(2048); // create a certification request (CSR) var csr = 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 var verified = csr.verify(); // convert certification request to PEM-format var pem = forge.pki.certificationRequestToPem(csr); // convert a Forge certification request from PEM-format var csr = forge.pki.certificationRequestFromPem(pem); // get an attribute csr.getAttribute({name: 'challengePassword'}); // get extensions array csr.getAttribute({name: 'extensionRequest'}).extensions; ``` -------------------------------- ### Create and Parse ASN.1 DER with Forge Source: https://github.com/digitalbazaar/forge/blob/main/README.md Demonstrates creating an ASN.1 SubjectPublicKeyInfo structure, serializing it to DER, deserializing it back, and converting OIDs. Includes validation of ASN.1 structures and pretty-printing for debugging. ```javascript var asn1 = forge.asn1; // create a SubjectPublicKeyInfo var subjectPublicKeyInfo = 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 var derBuffer = asn1.toDer(subjectPublicKeyInfo); // deserialize to an ASN.1 object from a byte buffer filled with DER data var object = asn1.fromDer(derBuffer); // convert an OID dot-separated string to a byte buffer var derOidBuffer = 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 var publicKeyValidator = { 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' }] }] }; var capture = {}; var errors = []; 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 var oid = 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); ``` -------------------------------- ### Build for Unit Browser Tests Source: https://github.com/digitalbazaar/forge/blob/main/README.md Create a special Forge build necessary for running unit tests in a browser. ```bash npm run test-build ``` -------------------------------- ### forge.pki.privateKeyFromPem, forge.pki.publicKeyFromPem Source: https://context7.com/digitalbazaar/forge/llms.txt Loads RSA private and public keys from PEM format. ```APIDOC ## forge.pki.privateKeyFromPem, forge.pki.publicKeyFromPem ### Description Loads RSA private and public keys from PEM format. ### Parameters - **pem** (string) - The PEM-encoded string of the private or public key. ### Returns - (forge.pki.RSAPrivateKey | forge.pki.RSAPublicKey) - The loaded RSA private or public key object. ### Request Example ```javascript var privPem = '-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----'; var pubPem = '-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----'; var privFromPem = forge.pki.privateKeyFromPem(privPem); var pubFromPem = forge.pki.publicKeyFromPem(pubPem); ``` ``` -------------------------------- ### Perform Coverage Testing Source: https://github.com/digitalbazaar/forge/blob/main/README.md Execute unit tests with coverage enabled. Results are stored in the 'coverage/' directory. Note that coverage testing may significantly slow down test execution. ```bash npm install npm run coverage ``` -------------------------------- ### Generate RSA Key Pair (Step-by-Step) Source: https://github.com/digitalbazaar/forge/blob/main/README.md Generates an RSA key pair in steps, allowing execution on the main JS thread for a specified duration. Useful for avoiding long-running operations. ```javascript // generate an RSA key pair in steps that attempt to run for a specified period // of time on the main JS thread var state = rsa.createKeyPairGenerationState(2048, 0x10001); var step = 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); ``` -------------------------------- ### Build SocketPool.swf Component with Debug Support Source: https://github.com/digitalbazaar/forge/blob/main/flash/README.md Builds the SocketPool.swf component with additional debug support enabled. This command is defined in the package.json file. ```bash npm run build-debug ``` -------------------------------- ### Run Automated Tests with Karma Source: https://github.com/digitalbazaar/forge/blob/main/README.md Execute automated tests using Karma. By default, tests run with Headless Chrome. ```bash npm run test-karma ``` -------------------------------- ### Decode and Manage PKCS#12 Archives Source: https://github.com/digitalbazaar/forge/blob/main/README.md This snippet demonstrates how to decode a PKCS#12 archive from base64, parse it into an ASN.1 object, and decrypt it using a password. It covers various decryption scenarios, including strict/non-strict parsing, no password, and empty passwords. It also shows how to retrieve specific bags (certificates, keys) by friendly name, local key ID, or bag type. ```javascript // decode p12 from base64 var p12Der = forge.util.decode64(p12b64); // get p12 as ASN.1 object var p12Asn1 = forge.asn1.fromDer(p12Der); // decrypt p12 using the password 'password' var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password'); // decrypt p12 using non-strict parsing mode (resolves some ASN.1 parse errors) var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, 'password'); // decrypt p12 using literally no password (eg: Mac OS X/apple push) var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1); // decrypt p12 using an "empty" password (eg: OpenSSL with no password input) var p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, ''); // p12.safeContents is an array of safe contents, each of // which contains an array of safeBags // get bags by friendlyName var bags = p12.getBags({friendlyName: 'test'}); // bags are key'd by attribute type (here "friendlyName") // and the key values are an array of matching objects var cert = bags.friendlyName[0]; // get bags by localKeyId var bags = p12.getBags({localKeyId: buffer}); // bags are key'd by attribute type (here "localKeyId") // and the key values are an array of matching objects var cert = bags.localKeyId[0]; // get bags by localKeyId (input in hex) var bags = 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 var cert = bags.localKeyId[0]; // get bags by type var bags = 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) var cert = bags[forge.pki.oids.certBag][0]; // get bags by friendlyName and filter on bag type var bags = p12.getBags({ friendlyName: 'test', bagType: forge.pki.oids.certBag }); // get key bags var bags = p12.getBags({bagType: forge.pki.oids.keyBag}); // get key var bag = bags[forge.pki.oids.keyBag][0]; var key = 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) { var keyAsn1 = bag.asn1; // can now convert back to DER/PEM/etc for export } // generate a p12 using AES (default) var p12Asn1 = 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) var p12Asn1 = forge.pkcs12.toPkcs12Asn1( privateKey, certificateChain, 'password', {algorithm: '3des'}); // base64-encode p12 var p12Der = forge.asn1.toDer(p12Asn1).getBytes(); var p12b64 = forge.util.encode64(p12Der); // create download link for p12 var a = document.createElement('a'); a.download = 'example.p12'; a.setAttribute('href', 'data:application/x-pkcs12;base64,' + p12b64); a.appendChild(document.createTextNode('Download')); ``` -------------------------------- ### Forge.util Interoperability with Node.js Buffers Source: https://context7.com/digitalbazaar/forge/llms.txt Demonstrates converting between Forge's ByteBuffer and Node.js Buffer objects. Supports conversion to and from binary string representations. ```javascript var forge = require('node-forge'); // --- Interop with Node.js Buffers --- var forgeBuffer = forge.util.createBuffer(); forgeBuffer.putBytes('\xCA\xFE'); var nodeBuffer = Buffer.from(forgeBuffer.getBytes(), 'binary'); console.log('Node buffer hex:', nodeBuffer.toString('hex')); // cafe var backToForge = forge.util.createBuffer( Buffer.from('cafe', 'hex').toString('binary') ); console.log('Back to forge (hex):', backToForge.toHex()); // cafe ```