### Manage Server Time in TypeScript Source: https://context7.com/protonmail/pmcrypto/llms.txt Manages server time for cryptographic operations, synchronizing with a trusted time source. Useful for ensuring consistent signature validity. Provides functions to get current server time and update it from a trusted source. Requires the 'pmcrypto' library. ```typescript import { serverTime, updateServerTime } from 'pmcrypto'; // Get current server time (falls back to local time if not set) const currentTime = serverTime(); console.log('Current server time:', currentTime); // Update server time from a trusted source (only updates if newer) const serverDate = new Date('2024-01-15T12:00:00Z'); const updatedTime = updateServerTime(serverDate); console.log('Updated server time:', updatedTime); // Subsequent calls return the updated time console.log('Server time:', serverTime()); ``` -------------------------------- ### Get SHA-256 Fingerprints Source: https://context7.com/protonmail/pmcrypto/llms.txt Retrieves the SHA-256 fingerprints for all keys and subkeys within a given key object. For older key versions, it computes the SHA-256 hash; for newer versions, it returns the existing SHA-256 fingerprint. ```APIDOC ## getSHA256Fingerprints ### Description Returns SHA-256 fingerprints for all keys and subkeys in a key object. For v4 keys, computes SHA-256 hash; v5/v6 keys already use SHA-256. ### Method POST (Implied by operation) ### Endpoint /protonmail/pmcrypto/getSHA256Fingerprints ### Parameters #### Request Body - **publicKey** (object) - Required - The public key object for which to retrieve fingerprints. ### Request Example ```json { "publicKey": { ... public key object ... } } ``` ### Response #### Success Response (200) - **fingerprints** (array of strings) - An array containing the SHA-256 fingerprints of the primary key and all subkeys. #### Response Example ```json [ "abc123...primary...", "def456...subkey1...", "ghi789...subkey2..." ] ``` ``` -------------------------------- ### Get SHA-256 Fingerprints using pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Retrieves the SHA-256 fingerprints for all keys and subkeys within a given key object. For v4 keys, it computes the SHA-256 hash, while v5/v6 keys already utilize SHA-256. ```typescript import { readKey, getSHA256Fingerprints } from 'pmcrypto'; const publicKey = await readKey({ armoredKey: '...' }); const fingerprints = await getSHA256Fingerprints(publicKey); console.log('Primary key fingerprint:', fingerprints[0]); console.log('All fingerprints:', fingerprints); // ['abc123...primary...', 'def456...subkey1...', 'ghi789...subkey2...'] ``` -------------------------------- ### Initialize pmcrypto Source: https://github.com/protonmail/pmcrypto/blob/main/README.md Initializes the pmcrypto library to apply changes to the underlying OpenPGP.js configuration. This is a required step before using other pmcrypto functions. ```javascript import { init } from 'pmcrypto'; init(); ``` -------------------------------- ### Encrypt/Sign and Decrypt/Verify Messages with Keys Source: https://github.com/protonmail/pmcrypto/blob/main/README.md Demonstrates encrypting and signing messages using recipient public keys and sender private keys, and subsequently decrypting and verifying them. Supports both string and binary data, and armored or binary formats. It also includes handling for streamed inputs and legacy browser polyfills. ```javascript const recipientPublicKey = await readKey({ armoredKey: '...' }); // or `binaryKey` const senderPrivateKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'personal key passphrase' }); const { message: armoredMessage, encryptedSignature: armoredEncryptedSignature } = await encryptMessage({ textData: 'text data to encrypt', // or `binaryData` for Uint8Arrays encryptionKeys: recipientPublicKey, // and/or `passwords` signingKeys: senderPrivateKey, detached: true, format: 'armored' // or 'binary' to output a binary message and signature }); // share `armoredMessage` // load the required keys const senderPublicKey = await readKey(...); const recipientPrivateKey = await decryptKey(...); const { data: decryptedData, verificationStatus } = await decryptMessage({ message: await readMessage({ armoredMessage }), // or `binaryMessage` encryptedSignature: await readMessage({ armoredMessage: armoredEncryptedSignature }), decryptionKeys: recipientPrivateKey, // and/or 'passwords' verificationKeys: senderPublicKey }); // For streamed inputs: // explicitly loading stream polyfills for legacy browsers is required since v7.2.2 if (!globalThis.TransformStream) { await import('web-streams-polyfill/es6'); } const { data: dataStream, verificationStatus: verifiedPromise } = await decryptMessage({ message: await readMessage({ armoredMessage: streamedArmoredMessage }), // ... other options }); // you need to read `dataStream` before resolving `verifiedPromise`, even if you do not need the decrypted data const decryptedData = await readToEnd(dataStream); const verificationStatus = await verificationStatus; ``` -------------------------------- ### Initialize pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Initializes the pmcrypto library, configuring underlying OpenPGP.js with Proton-specific settings. This function must be called before any other pmcrypto operations. ```typescript import { init } from 'pmcrypto'; // Initialize pmcrypto (required before any other operations) init(); // The library is now ready to use ``` -------------------------------- ### Encrypt/Decrypt Using Session Key Source: https://github.com/protonmail/pmcrypto/blob/main/README.md Illustrates encrypting and decrypting data using a session key. This involves generating a session key, encrypting data with it, and then decrypting the data using the same session key. It also covers encrypting and decrypting the session key itself. ```javascript // First generate the session key const sessionKey = await generateSessionKey({ recipientKeys: recipientPublicKey }); // Then encrypt the data with it const { message: armoredMessage } = await encryptMessage({ textData: 'text data to encrypt', // or `binaryData` for Uint8Arrays sessionKey, encryptionKeys: recipientPublicKey, // and/or `passwords`, used to encrypt the session key signingKeys: senderPrivateKey, }); // To decrypt, you can again provide the session key directly: const { data } = await decryptMessage({ message: await readMessage({ armoredMessage }), sessionKeys: sessionKey, verificationKeys: senderPublicKey, }); // You can also encrypt the session key on its own: const armoredEncryptedSessionKey = await encryptSessionKey({ sessionKey, encryptionKeys, format: 'armored' }); // And decrypt it with: const sessionKey = await decryptSessionKey({ message: await readMessage({ armoredMessage: armoredEncryptedSessionKey }), decryptionsKeys // and/or passwords }); ``` -------------------------------- ### Streaming Encryption and Decryption (TypeScript) Source: https://context7.com/protonmail/pmcrypto/llms.txt Demonstrates how to use pmcrypto for streaming encryption and decryption of large files. It initializes the library, loads keys, creates a readable data stream, encrypts it, and then decrypts the encrypted stream, verifying the signature. ```typescript import { init, readKey, readPrivateKey, decryptKey, encryptMessage, decryptMessage, readMessage } from 'pmcrypto'; import { readToEnd } from '@openpgp/web-stream-tools'; init(); // Load polyfill for legacy browsers if needed if (!globalThis.TransformStream) { await import('web-streams-polyfill/es6'); } const publicKey = await readKey({ armoredKey: '...' }); const privateKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'passphrase' }); // Create a readable stream of data const inputStream = new ReadableStream({ start(controller) { controller.enqueue(new TextEncoder().encode('Chunk 1 of large file... ')); controller.enqueue(new TextEncoder().encode('Chunk 2 of large file... ')); controller.enqueue(new TextEncoder().encode('Chunk 3 of large file...')); controller.close(); } }); // Encrypt streaming data const { message: encryptedStream } = await encryptMessage({ textData: inputStream, encryptionKeys: publicKey, signingKeys: privateKey, format: 'armored' }); // For streamed output, collect the result const encryptedMessage = await readToEnd(encryptedStream); // Decrypt streaming message const { data: dataStream, verificationStatus: verificationPromise } = await decryptMessage({ message: await readMessage({ armoredMessage: encryptedMessage }), decryptionKeys: privateKey, verificationKeys: publicKey }); // IMPORTANT: Must read data stream before awaiting verification const decryptedData = await readToEnd(dataStream); const verificationStatus = await verificationPromise; console.log('Decrypted:', decryptedData); console.log('Verification:', verificationStatus); ``` -------------------------------- ### Convert Between Binary and ASCII-Armored OpenPGP Source: https://context7.com/protonmail/pmcrypto/llms.txt Provides functions to convert binary OpenPGP data to a human-readable ASCII-armored format and vice-versa. This is essential for handling OpenPGP messages in text-based environments. ```typescript import { readMessage, armorBytes, stripArmor } from 'pmcrypto'; // Convert binary message to armored format const binaryMessage = new Uint8Array([0xc3, 0x04, ...]); // OpenPGP binary const armoredMessage = await armorBytes(binaryMessage); console.log(armoredMessage); // -----BEGIN PGP MESSAGE----- // ... // -----END PGP MESSAGE----- // Convert armored message to binary format const armored = `-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----`; const binary = await stripArmor(armored); console.log('Binary length:', binary.length); ``` -------------------------------- ### Use Signature Context for Domain Separation in TypeScript Source: https://context7.com/protonmail/pmcrypto/llms.txt Implements signature context for OpenPGP signatures using notation data, preventing signature reuse across different contexts. This ensures that signatures are only valid within their intended domain. Supports critical signatures and grace periods for verification. Requires initialization and various key/message handling functions from 'pmcrypto'. ```typescript import { init, readKey, readPrivateKey, decryptKey, encryptMessage, decryptMessage, readMessage, signMessage, verifyMessage, VERIFICATION_STATUS, SignatureContextError } from 'pmcrypto'; init(); const publicKey = await readKey({ armoredKey: '...' }); const privateKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'passphrase' }); // Sign with context (critical = true means verification fails without context) const { message: encryptedMessage } = await encryptMessage({ textData: 'Context-bound message', encryptionKeys: publicKey, signingKeys: privateKey, signatureContext: { value: 'email.body', critical: true } }); // Decrypt and verify with matching context const { data, verificationStatus } = await decryptMessage({ message: await readMessage({ armoredMessage: encryptedMessage }), decryptionKeys: privateKey, verificationKeys: publicKey, signatureContext: { value: 'email.body', required: true } }); console.log('Verification status:', verificationStatus === VERIFICATION_STATUS.SIGNED_AND_VALID); // Context with grace period (requiredAfter) const resultWithGrace = await decryptMessage({ message: await readMessage({ armoredMessage: '...' }), decryptionKeys: privateKey, verificationKeys: publicKey, signatureContext: { value: 'email.body', requiredAfter: new Date('2024-01-01') // Signatures before this date don't need context } }); ``` -------------------------------- ### Generate Forwarding Material in TypeScript Source: https://context7.com/protonmail/pmcrypto/llms.txt Generates forwarding material for encrypted message forwarding, creating a forwardee key and proxy parameters for blind forwarding. This function is essential for enabling secure, anonymous forwarding of encrypted emails. Requires initialization and specific key management functions from 'pmcrypto'. ```typescript import { init, readPrivateKey, decryptKey, generateForwardingMaterial, doesKeySupportForwarding, isForwardingKey } from 'pmcrypto'; init(); const forwarderKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...ECC key...' }), passphrase: 'passphrase' }); // Check if the key supports forwarding const supportsForwarding = await doesKeySupportForwarding(forwarderKey); console.log('Key supports forwarding:', supportsForwarding); if (supportsForwarding) { // Generate forwarding material const { forwardeeKey, proxyInstances } = await generateForwardingMaterial( forwarderKey, [{ name: 'Forwardee', email: 'forwardee@example.com' }] ); console.log('Forwardee key fingerprint:', forwardeeKey.getFingerprint()); console.log('Proxy instances:', proxyInstances.map(p => ({ keyVersion: p.keyVersion, forwarderFingerprint: Buffer.from(p.forwarderKeyFingerprint).toString('hex'), forwardeeFingerprint: Buffer.from(p.forwardeeKeyFingerprint).toString('hex') }))); // Check if a key is configured for forwarding const isForwarding = await isForwardingKey(forwardeeKey); console.log('Is forwarding key:', isForwarding); } ``` -------------------------------- ### armorBytes / stripArmor Source: https://context7.com/protonmail/pmcrypto/llms.txt Converts between binary and ASCII-armored OpenPGP message formats. ```APIDOC ## armorBytes / stripArmor ### Description Converts between binary and ASCII-armored OpenPGP message formats. ### Method [Not specified, likely utility functions] ### Endpoint [Not applicable, these are library functions] ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **binaryMessage** (Uint8Array) - The binary data to armor. - **armored** (string) - The ASCII-armored string to strip. ### Request Example ```typescript import { readMessage, armorBytes, stripArmor } from 'pmcrypto'; // Convert binary message to armored format const binaryMessage = new Uint8Array([0xc3, 0x04, ...]); // OpenPGP binary const armoredMessage = await armorBytes(binaryMessage); console.log(armoredMessage); // -----BEGIN PGP MESSAGE----- // ... // -----END PGP MESSAGE----- // Convert armored message to binary format const armored = `-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----`; const binary = await stripArmor(armored); console.log('Binary length:', binary.length); ``` ### Response #### Success Response (string | Uint8Array) - **armoredMessage** (string) - The ASCII-armored representation of the binary data. - **binary** (Uint8Array) - The binary representation of the armored data. ``` -------------------------------- ### Check Key Compatibility Source: https://context7.com/protonmail/pmcrypto/llms.txt Validates if a key is compatible with Proton Mail clients, checking for supported key versions and algorithms across the Proton ecosystem. ```APIDOC ## checkKeyCompatibility ### Description Validates that a key is compatible with Proton clients. Checks key version support and algorithm compatibility across the Proton ecosystem. ### Method POST (Implied by operation) ### Endpoint /protonmail/pmcrypto/checkKeyCompatibility ### Parameters #### Request Body - **publicKey** (object) - Required - The public key object to check. - **v6KeysAllowed** (boolean) - Optional - Whether to allow v6 keys. Defaults to false. ### Request Example ```json { "publicKey": { ... public key object ... } } ``` ```json { "publicKey": { ... public key object ... }, "v6KeysAllowed": true } ``` ### Response #### Success Response (200) Indicates the key is compatible. No specific data is returned on success, but an error is thrown if compatibility issues are found. #### Error Response - **message** (string) - Description of the compatibility issue (e.g., "Key compatibility issue"). ``` -------------------------------- ### Read OpenPGP Keys (Public/Private) Source: https://context7.com/protonmail/pmcrypto/llms.txt Parses armored or binary OpenPGP public or private keys into key objects. Supports single keys and multiple keys from a keyring. Use `readKey` for public and `readPrivateKey` for private keys. ```typescript import { readKey, readPrivateKey, readKeys } from 'pmcrypto'; // Parse a single public key from armored format const publicKey = await readKey({ armoredKey: `-----BEGIN PGP PUBLIC KEY BLOCK----- xjMEZQ... -----END PGP PUBLIC KEY BLOCK-----` }); // Parse a single private key from armored format const privateKey = await readPrivateKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- cncLYBGQ... -----END PGP PRIVATE KEY BLOCK-----` }); // Parse from binary format const binaryPublicKey = await readKey({ binaryKey: new Uint8Array([0x99, 0x01, ...]) }); // Parse multiple keys from a keyring const publicKeys = await readKeys({ armoredKeys: `-----BEGIN PGP PUBLIC KEY BLOCK----- ...multiple keys... -----END PGP PUBLIC KEY BLOCK-----` }); ``` -------------------------------- ### generateSessionKeyForAlgorithm Source: https://context7.com/protonmail/pmcrypto/llms.txt Generates a random session key for a specific symmetric algorithm without considering recipient key preferences. ```APIDOC ## generateSessionKeyForAlgorithm ### Description Generates a random session key for a specific symmetric algorithm without considering recipient key preferences. ### Method POST (Implicit, as it's a function call within the library) ### Endpoint N/A (Client-side library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **algorithm** (string) - Required - The desired symmetric algorithm (e.g., 'aes256', 'aes128', 'aes192'). ### Request Example ```typescript const aes256Key = await generateSessionKeyForAlgorithm('aes256'); console.log('AES-256 key length:', aes256Key.length); ``` ### Response #### Success Response (Implicit) - **sessionKey** (Uint8Array) - The generated random session key data. #### Response Example ```json "" ``` ``` -------------------------------- ### Check Key Compatibility with Proton Clients using pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Verifies if a public key is compatible with Proton clients, checking key version support and algorithm compatibility. By default, it checks for v4 keys, but can be configured to allow v6 keys. ```typescript import { readKey, checkKeyCompatibility } from 'pmcrypto'; const publicKey = await readKey({ armoredKey: '...' }); // Check compatibility (v4 keys only by default) try { checkKeyCompatibility(publicKey); console.log('Key is compatible with all Proton clients'); } catch (error) { console.error('Key compatibility issue:', error.message); } // Allow v6 keys (when client support is available) try { checkKeyCompatibility(publicKey, true); // v6KeysAllowed = true console.log('Key is compatible (including v6 support)'); } catch (error) { console.error('Key not supported:', error.message); } ``` -------------------------------- ### Generate OpenPGP Key Pair Source: https://context7.com/protonmail/pmcrypto/llms.txt Generates a new OpenPGP key pair (public and private) with specified parameters, including key type (ECC/RSA), user IDs, and optional expiration. Supports armored, binary, or object formats for output. ```typescript import { generateKey } from 'pmcrypto'; // Generate an ECC key (recommended) const { privateKey, publicKey, revocationCertificate } = await generateKey({ type: 'ecc', curve: 'curve25519Legacy', userIDs: [{ name: 'John Doe', email: 'john@example.com' }], passphrase: 'secure-passphrase', format: 'armored' // or 'binary' or 'object' }); console.log('Private key:', privateKey); console.log('Public key:', publicKey); console.log('Revocation certificate:', revocationCertificate); // Generate an RSA key with expiration const rsaKey = await generateKey({ type: 'rsa', rsaBits: 4096, userIDs: [{ name: 'Jane Doe', email: 'jane@example.com' }], passphrase: 'another-passphrase', keyExpirationTime: 365 * 24 * 60 * 60, // 1 year in seconds format: 'object' }); ``` -------------------------------- ### Reformat Key with New User IDs (TypeScript) Source: https://context7.com/protonmail/pmcrypto/llms.txt Reformats an existing private key to bind it to new user IDs and regenerate preference signatures. This function allows updating key metadata without generating a completely new key. It requires the original private key, new user ID details, a passphrase for the new key, and the desired output format. ```typescript import { readPrivateKey, decryptKey, reformatKey } from 'pmcrypto'; const originalKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'passphrase' }); // Reformat with new user IDs const { privateKey: reformattedKey, publicKey } = await reformatKey({ privateKey: originalKey, userIDs: [{ name: 'New Name', email: 'newemail@example.com' }], passphrase: 'new-passphrase', format: 'armored' }); console.log('Reformatted key:', reformattedKey); ``` -------------------------------- ### Compute Unsafe MD5 and SHA-1 Hashes Source: https://context7.com/protonmail/pmcrypto/llms.txt Computes MD5 and SHA-1 hashes. These algorithms are considered cryptographically unsafe due to known vulnerabilities and should only be used for legacy compatibility purposes. ```typescript import { unsafeMD5, unsafeSHA1 } from 'pmcrypto'; const data = new TextEncoder().encode('Hello, World!'); // WARNING: MD5 is cryptographically broken - use only for legacy auth const md5Hash = await unsafeMD5(data); console.log('MD5:', Buffer.from(md5Hash).toString('hex')); // WARNING: SHA-1 is not collision-resistant - do not use for security const sha1Hash = await unsafeSHA1(data); console.log('SHA-1:', Buffer.from(sha1Hash).toString('hex')); // unsafeSHA1 also supports streaming input const stream = new ReadableStream({ start(controller) { controller.enqueue(new Uint8Array([1, 2, 3])); controller.enqueue(new Uint8Array([4, 5, 6])); controller.close(); } }); const streamedHash = await unsafeSHA1(stream); ``` -------------------------------- ### Encrypt Private Key with Passphrase Source: https://context7.com/protonmail/pmcrypto/llms.txt Encrypts a private OpenPGP key with a passphrase for secure storage. This function utilizes optimized S2K iteration counts suitable for password-protected keys. ```typescript import { readPrivateKey, decryptKey, encryptKey } from 'pmcrypto'; // Assume we have a decrypted private key const decryptedKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'old-passphrase' }); // Encrypt with a new passphrase const encryptedKey = await encryptKey({ privateKey: decryptedKey, passphrase: 'new-secure-passphrase' }); // Result is an encrypted PrivateKey object console.log('Key encrypted:', !encryptedKey.isDecrypted()); // true ``` -------------------------------- ### reformatKey Source: https://context7.com/protonmail/pmcrypto/llms.txt Reformats an existing key to bind it to new user IDs and regenerate preference signatures. Useful for updating key metadata without generating a new key. ```APIDOC ## reformatKey ### Description Reformats an existing key to bind it to new user IDs and regenerate preference signatures. Useful for updating key metadata without generating a new key. ### Method POST ### Endpoint /reformatKey ### Parameters #### Request Body - **privateKey** (object) - Required - The original private key object. - **userIDs** (array) - Required - An array of user ID objects to associate with the reformatted key. - **name** (string) - Required - The name of the user. - **email** (string) - Required - The email of the user. - **passphrase** (string) - Required - The passphrase for the new key. - **format** (string) - Optional - The desired output format ('armored' or 'binary'). Defaults to 'armored'. ### Request Example ```json { "privateKey": { ... }, "userIDs": [ { "name": "New Name", "email": "newemail@example.com" } ], "passphrase": "new-passphrase", "format": "armored" } ``` ### Response #### Success Response (200) - **privateKey** (string) - The reformatted private key in the specified format. - **publicKey** (string) - The corresponding public key in the specified format. #### Response Example ```json { "privateKey": "-----BEGIN PGP PRIVATE KEY-----\n...\n-----END PGP PRIVATE KEY-----", "publicKey": "-----BEGIN PGP PUBLIC KEY-----\n...\n-----END PGP PUBLIC KEY-----" } ``` ``` -------------------------------- ### Can Key Encrypt Source: https://context7.com/protonmail/pmcrypto/llms.txt Tests if a key is capable of successfully encrypting a message, verifying its encryption capability, validity, and material integrity. ```APIDOC ## canKeyEncrypt ### Description Tests if a key can successfully encrypt a message. Verifies encryption capability, validity, and key material integrity. ### Method POST (Implied by operation) ### Endpoint /protonmail/pmcrypto/canKeyEncrypt ### Parameters #### Request Body - **publicKey** (object) - Required - The public key object to test. - **dateToCheck** (string) - Optional - A date string (e.g., 'YYYY-MM-DD') to check encryption capability against. Defaults to the current date. ### Request Example ```json { "publicKey": { ... public key object ... } } ``` ```json { "publicKey": { ... public key object ... }, "dateToCheck": "2025-01-01" } ``` ### Response #### Success Response (200) - **canEncrypt** (boolean) - True if the key can encrypt a message on or before the specified date, false otherwise. #### Response Example ```json { "canEncrypt": true } ``` ``` -------------------------------- ### getMatchingKey Source: https://context7.com/protonmail/pmcrypto/llms.txt Finds the key that generated a given signature from a set of candidate keys. This is useful for identifying the signer from a keyring. ```APIDOC ## getMatchingKey ### Description Finds the key that generated a given signature from a set of candidate keys. Useful for identifying the signer from a keyring. ### Method [Not specified, likely a utility function] ### Endpoint [Not applicable, this is a library function] ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **signature** (Signature) - The signature to match. - **candidateKeys** (Array) - An array of candidate keys to search within. ### Request Example ```typescript import { readKey, readSignature, getMatchingKey } from 'pmcrypto'; const signature = await readSignature({ armoredSignature: '...' }); const candidateKeys = [ await readKey({ armoredKey: '...key1...' }), await readKey({ armoredKey: '...key2...' }), await readKey({ armoredKey: '...key3...' }) ]; const signingKey = getMatchingKey(signature, candidateKeys); if (signingKey) { console.log('Signature was created by:', signingKey.getFingerprint()); } else { console.log('Signing key not found in provided keys'); } ``` ### Response #### Success Response (Key | null) - **signingKey** (Key | null) - The matching key if found, otherwise null. ``` -------------------------------- ### Compute SHA-256 and SHA-512 Hashes Source: https://context7.com/protonmail/pmcrypto/llms.txt Calculates SHA-256 and SHA-512 cryptographic hashes of input data using the Web Crypto API. These are standard and secure hashing algorithms. ```typescript import { SHA256, SHA512 } from 'pmcrypto'; const data = new TextEncoder().encode('Hello, World!'); const sha256Hash = await SHA256(data); console.log('SHA-256:', Buffer.from(sha256Hash).toString('hex')); // dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f const sha512Hash = await SHA512(data); console.log('SHA-512:', Buffer.from(sha512Hash).toString('hex')); ``` -------------------------------- ### Split OpenPGP Message into Packets Source: https://context7.com/protonmail/pmcrypto/llms.txt Deconstructs an OpenPGP message into its constituent packets, allowing for detailed inspection or targeted processing of specific parts like signatures, encrypted data, or literal data. ```typescript import { readMessage, splitMessage } from 'pmcrypto'; const message = await readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----` }); const packets = await splitMessage(message); console.log('Public-key encrypted session keys:', packets.asymmetric.length); console.log('Symmetric encrypted session keys:', packets.symmetric.length); console.log('Signature packets:', packets.signature.length); console.log('Encrypted data packets:', packets.encrypted.length); console.log('Compressed packets:', packets.compressed.length); console.log('Literal data packets:', packets.literal.length); ``` -------------------------------- ### processMIME Source: https://context7.com/protonmail/pmcrypto/llms.txt Parses and processes MIME-formatted email content, extracting body, attachments, encrypted subject, and verifying any embedded signatures. ```APIDOC ## processMIME ### Description Parses and processes MIME-formatted email content, extracting body, attachments, encrypted subject, and verifying any embedded signatures. ### Method [Not specified, likely a utility function] ### Endpoint [Not applicable, this is a library function] ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **data** (string) - The MIME-formatted email content. - **verificationKeys** (Key | Array) - The public key(s) to use for signature verification. - **sender** (string) - The sender's email address. - **headerFilename** (string) - The filename for encrypted headers. ### Request Example ```typescript import { init, readKey, processMIME, VERIFICATION_STATUS } from 'pmcrypto'; init(); const senderPublicKey = await readKey({ armoredKey: '...' }); const mimeContent = `Content-Type: multipart/mixed; boundary="boundary123" --boundary123 Content-Type: text/plain; charset=utf-8 Hello, this is the email body. --boundary123 Content-Type: application/pdf; name="document.pdf" Content-Disposition: attachment; filename="document.pdf" Content-Transfer-Encoding: base64 JVBERi0xLjQK... --boundary123--`; const result = await processMIME({ data: mimeContent, verificationKeys: senderPublicKey, sender: 'sender@example.com', headerFilename: 'Encrypted Headers' }); console.log('Body:', result.body); console.log('MIME type:', result.mimeType); // 'text/plain' or 'text/html' console.log('Encrypted subject:', result.encryptedSubject); console.log('Attachments:', result.attachments.map(a => ({ fileName: a.fileName, contentType: a.contentType, size: a.content.length }))); console.log('Signature valid:', result.verificationStatus === VERIFICATION_STATUS.SIGNED_AND_VALID); ``` ### Response #### Success Response (object) - **body** (string) - The extracted email body. - **mimeType** (string) - The MIME type of the body (e.g., 'text/plain', 'text/html'). - **encryptedSubject** (string | undefined) - The encrypted subject line, if present. - **attachments** (Array) - An array of attachment objects, each containing `fileName`, `contentType`, and `content`. - **verificationStatus** (VERIFICATION_STATUS) - The status of the signature verification. ``` -------------------------------- ### Generate Session Key with pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Generates a symmetric session key compatible with specified recipient PGP keys. This key is intended for efficient encryption of large data volumes. It requires 'pmcrypto' for key reading and session key generation. The output includes the session key's algorithm and data. ```typescript import { init, readKey, generateSessionKey, encryptMessage, decryptMessage, readMessage } from 'pmcrypto'; init(); const recipientPublicKey = await readKey({ armoredKey: '...' }); // Generate a session key based on recipient's key preferences const sessionKey = await generateSessionKey({ recipientKeys: recipientPublicKey }); console.log('Session key algorithm:', sessionKey.algorithm); // e.g., 'aes256' console.log('Session key data:', sessionKey.data); // Uint8Array // Use the session key for encryption const { message } = await encryptMessage({ textData: 'Message encrypted with explicit session key', sessionKey, encryptionKeys: recipientPublicKey }); ``` -------------------------------- ### Find Matching Key for Signature Source: https://context7.com/protonmail/pmcrypto/llms.txt Identifies the key that generated a given signature from a list of candidate keys. This function is crucial for verifying the origin of a signature within a set of known keys. ```typescript import { readKey, readSignature, getMatchingKey } from 'pmcrypto'; const signature = await readSignature({ armoredSignature: '...' }); const candidateKeys = [ await readKey({ armoredKey: '...key1...' }), await readKey({ armoredKey: '...key2...' }), await readKey({ armoredKey: '...key3...' }) ]; const signingKey = getMatchingKey(signature, candidateKeys); if (signingKey) { console.log('Signature was created by:', signingKey.getFingerprint()); } else { console.log('Signing key not found in provided keys'); } ``` -------------------------------- ### Test Key Encryption Capability using pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Tests whether a given key can successfully encrypt a message, verifying its encryption capability, validity, and the integrity of its key material. It can also test this capability at a specific point in time. ```typescript import { readKey, canKeyEncrypt } from 'pmcrypto'; const publicKey = await readKey({ armoredKey: '...' }); const canEncrypt = await canKeyEncrypt(publicKey); console.log('Key can encrypt:', canEncrypt); // Check encryption capability at a specific date const canEncryptOn = await canKeyEncrypt(publicKey, new Date('2025-01-01')); ``` -------------------------------- ### Derive Key with Argon2 in TypeScript Source: https://context7.com/protonmail/pmcrypto/llms.txt Derives a cryptographic key from a password using the Argon2 key derivation function as specified in RFC 9106. Supports recommended, minimum, and custom parameters for flexibility in different environments. Requires the 'pmcrypto' library. ```typescript import { argon2, ARGON2_PARAMS } from 'pmcrypto'; // Generate a random salt const salt = crypto.getRandomValues(new Uint8Array(16)); // Derive key with recommended parameters (memory-intensive) const derivedKey = await argon2({ password: 'user-password', salt, params: ARGON2_PARAMS.RECOMMENDED // passes: 1, parallelism: 4, memoryExponent: 19 }); console.log('Derived key length:', derivedKey.length); // 32 bytes // Use minimum parameters for constrained environments const fastDerivedKey = await argon2({ password: 'user-password', salt, params: ARGON2_PARAMS.MINIMUM // passes: 3, parallelism: 4, memoryExponent: 16 }); // Custom parameters const customKey = await argon2({ password: 'password', salt, params: { passes: 2, parallelism: 4, memoryExponent: 18, tagLength: 32 } }); ``` -------------------------------- ### unsafeMD5 / unsafeSHA1 Source: https://context7.com/protonmail/pmcrypto/llms.txt Computes MD5 or SHA-1 hashes. These are considered cryptographically unsafe and should only be used for legacy compatibility. ```APIDOC ## unsafeMD5 / unsafeSHA1 ### Description Computes MD5 or SHA-1 hashes. These are considered cryptographically unsafe and should only be used for legacy compatibility. ### Method [Not specified, likely utility functions] ### Endpoint [Not applicable, these are library functions] ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **data** (Uint8Array | ReadableStream) - The data to hash. Can be a Uint8Array or a ReadableStream for large inputs. ### Request Example ```typescript import { unsafeMD5, unsafeSHA1 } from 'pmcrypto'; const data = new TextEncoder().encode('Hello, World!'); // WARNING: MD5 is cryptographically broken - use only for legacy auth const md5Hash = await unsafeMD5(data); console.log('MD5:', Buffer.from(md5Hash).toString('hex')); // WARNING: SHA-1 is not collision-resistant - do not use for security const sha1Hash = await unsafeSHA1(data); console.log('SHA-1:', Buffer.from(sha1Hash).toString('hex')); // unsafeSHA1 also supports streaming input const stream = new ReadableStream({ start(controller) { controller.enqueue(new Uint8Array([1, 2, 3])); controller.enqueue(new Uint8Array([4, 5, 6])); controller.close(); } }); const streamedHash = await unsafeSHA1(stream); ``` ### Response #### Success Response (ArrayBuffer) - **hash** (ArrayBuffer) - The computed hash as an ArrayBuffer. ``` -------------------------------- ### Generate Session Key for Specific Algorithm with pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Generates a random symmetric session key for a specified algorithm (e.g., AES-256, AES-128) without considering recipient key preferences. This is useful for scenarios where the algorithm is predetermined. The function returns the key's length in bytes. ```typescript import { generateSessionKeyForAlgorithm } from 'pmcrypto'; // Generate a 256-bit AES key const aes256Key = await generateSessionKeyForAlgorithm('aes256'); console.log('AES-256 key length:', aes256Key.length); // 32 bytes // Generate a 128-bit AES key const aes128Key = await generateSessionKeyForAlgorithm('aes128'); console.log('AES-128 key length:', aes128Key.length); // 16 bytes // Generate a 192-bit AES key const aes192Key = await generateSessionKeyForAlgorithm('aes192'); console.log('AES-192 key length:', aes192Key.length); // 24 bytes ``` -------------------------------- ### Decrypt Private Key with Passphrase Source: https://context7.com/protonmail/pmcrypto/llms.txt Decrypts an encrypted private OpenPGP key using a provided passphrase. The resulting decrypted key can then be used for signing and decryption operations. ```typescript import { readPrivateKey, decryptKey } from 'pmcrypto'; // First parse the encrypted private key const encryptedKey = await readPrivateKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- cncLYBGQ...encrypted... -----END PGP PRIVATE KEY BLOCK-----` }); // Decrypt it with the passphrase const decryptedPrivateKey = await decryptKey({ privateKey: encryptedKey, passphrase: 'my-secret-passphrase' }); // The key is now ready for signing/decryption operations console.log('Key decrypted:', decryptedPrivateKey.isDecrypted()); // true ``` -------------------------------- ### Encrypt Message with Recipients and Signature (TypeScript) Source: https://context7.com/protonmail/pmcrypto/llms.txt Encrypts text or binary data for one or more recipients, with optional message signing. Supports attached/detached signatures and armored/binary output. Requires initialization, recipient public keys, and optionally sender private keys for signing. Outputs the encrypted message, and optionally signature and encrypted signature. ```typescript import { init, readKey, readPrivateKey, decryptKey, encryptMessage } from 'pmcrypto'; init(); // Prepare keys const recipientPublicKey = await readKey({ armoredKey: '...' }); const senderPrivateKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'sender-passphrase' }); // Encrypt text data with signature const { message: encryptedMessage } = await encryptMessage({ textData: 'Hello, this is a secret message!', encryptionKeys: recipientPublicKey, signingKeys: senderPrivateKey, format: 'armored' }); console.log(encryptedMessage); // -----BEGIN PGP MESSAGE----- // ... // -----END PGP MESSAGE----- // Encrypt binary data const { message: binaryMessage } = await encryptMessage({ binaryData: new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]), encryptionKeys: recipientPublicKey, format: 'binary' }); // Encrypt with detached signature const { message, signature, encryptedSignature } = await encryptMessage({ textData: 'Message with detached signature', encryptionKeys: recipientPublicKey, signingKeys: senderPrivateKey, detached: true, format: 'armored' }); ``` -------------------------------- ### splitMessage Source: https://context7.com/protonmail/pmcrypto/llms.txt Splits an OpenPGP message into its component packets for inspection or selective processing. ```APIDOC ## splitMessage ### Description Splits an OpenPGP message into its component packets for inspection or selective processing. ### Method [Not specified, likely a utility function] ### Endpoint [Not applicable, this is a library function] ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **message** (Message) - The OpenPGP message to split. ### Request Example ```typescript import { readMessage, splitMessage } from 'pmcrypto'; const message = await readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----` }); const packets = await splitMessage(message); console.log('Public-key encrypted session keys:', packets.asymmetric.length); console.log('Symmetric encrypted session keys:', packets.symmetric.length); console.log('Signature packets:', packets.signature.length); console.log('Encrypted data packets:', packets.encrypted.length); console.log('Compressed packets:', packets.compressed.length); console.log('Literal data packets:', packets.literal.length); ``` ### Response #### Success Response (Packets) - **packets** (object) - An object containing arrays of different packet types (e.g., `asymmetric`, `symmetric`, `signature`, `encrypted`, `compressed`, `literal`). ``` -------------------------------- ### Verify Detached Signature with pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Verifies a detached PGP signature against original data using the signer's public key. It returns the verification status, signature metadata, and any errors encountered. Dependencies include 'pmcrypto' for key and signature reading, and verification functions. ```typescript import { init, readKey, readSignature, verifyMessage, VERIFICATION_STATUS } from 'pmcrypto'; init(); const signerPublicKey = await readKey({ armoredKey: '...' }); // Verify a detached signature over text data const { data, verificationStatus, signatureTimestamp, errors } = await verifyMessage({ textData: 'Original message that was signed', signature: await readSignature({ armoredSignature: `-----BEGIN PGP SIGNATURE----- ... -----END PGP SIGNATURE-----` }), verificationKeys: signerPublicKey }); if (verificationStatus === VERIFICATION_STATUS.SIGNED_AND_VALID) { console.log('Signature is valid, signed at:', signatureTimestamp); } else if (verificationStatus === VERIFICATION_STATUS.SIGNED_AND_INVALID) { console.log('Signature verification failed:', errors); } else { console.log('Message was not signed'); } // Verify with expectSigned option (throws if invalid) try { await verifyMessage({ binaryData: new Uint8Array([...]), signature: await readSignature({ binarySignature: new Uint8Array([...]) }), verificationKeys: signerPublicKey, expectSigned: true }); console.log('Signature verified successfully'); } catch (error) { console.error('Verification failed:', error); } ``` -------------------------------- ### Decrypt Session Key with Private Key or Password using pmcrypto Source: https://context7.com/protonmail/pmcrypto/llms.txt Decrypts an encrypted session key using either a provided private key and passphrase or a list of passwords. It returns the session key object containing the algorithm and key data, or null if decryption fails. Ensure the pmcrypto library is initialized. ```typescript import { init, readPrivateKey, decryptKey, readMessage, decryptSessionKey } from 'pmcrypto'; init(); const recipientPrivateKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'passphrase' }); // Decrypt session key from encrypted key packet const sessionKey = await decryptSessionKey({ message: await readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----` }), decryptionKeys: recipientPrivateKey }); if (sessionKey) { console.log('Algorithm:', sessionKey.algorithm); console.log('Key data:', sessionKey.data); } // Decrypt with password const sessionKeyFromPassword = await decryptSessionKey({ message: await readMessage({ armoredMessage: '...' }), passwords: ['shared-password'] }); ``` -------------------------------- ### Decrypt Message and Verify Signature (TypeScript) Source: https://context7.com/protonmail/pmcrypto/llms.txt Decrypts an encrypted message and verifies its signature if present. Returns the decrypted data, verification status, and signatures. Requires initialization, recipient private keys for decryption, and sender public keys for verification. Supports different output formats like 'utf8' or 'binary'. ```typescript import { init, readKey, readPrivateKey, decryptKey, readMessage, decryptMessage, VERIFICATION_STATUS } from 'pmcrypto'; init(); // Prepare keys const senderPublicKey = await readKey({ armoredKey: '...' }); const recipientPrivateKey = await decryptKey({ privateKey: await readPrivateKey({ armoredKey: '...' }), passphrase: 'recipient-passphrase' }); // Decrypt and verify a message const { data, verificationStatus, signatures } = await decryptMessage({ message: await readMessage({ armoredMessage: `-----BEGIN PGP MESSAGE----- ... -----END PGP MESSAGE-----` }), decryptionKeys: recipientPrivateKey, verificationKeys: senderPublicKey, format: 'utf8' // or 'binary' }); console.log('Decrypted:', data); console.log('Verification:', verificationStatus === VERIFICATION_STATUS.SIGNED_AND_VALID ? 'Valid' : 'Invalid or unsigned'); // Decrypt with encrypted detached signature const resultWithDetachedSig = await decryptMessage({ message: await readMessage({ armoredMessage: '...' }), encryptedSignature: await readMessage({ armoredMessage: '...encrypted signature...' }), decryptionKeys: recipientPrivateKey, verificationKeys: senderPublicKey }); ```