@civic/nexus-bridge
Version:
Stdio <-> HTTP/SSE MCP bridge with Civic auth handling
44 lines • 1.97 kB
JavaScript
/**
* encryption.ts
*
* Utilities for encrypting and decrypting sensitive data like tokens
* when passing them between services.
*/
import * as jose from 'jose';
import { TOKEN_ENCRYPTION_PUBLIC_KEY_PROD } from "../config.js";
import { logger } from "./logger.js";
/**
* Encrypts a token using JOSE JWE format (which handles hybrid encryption internally)
* This handles tokens of any size by using RSA to encrypt a symmetric key
* and using that symmetric key to encrypt the actual token.
*
* @param token The token to encrypt
* @returns Compact JWE format encrypted token
*/
export async function encryptToken(token) {
try {
logger.info('[ServiceAuthHandler] Encrypting token using JOSE JWE...');
// Get public key from environment
const publicKeyString = process.env.TOKEN_ENCRYPTION_PUBLIC_KEY ?? TOKEN_ENCRYPTION_PUBLIC_KEY_PROD;
logger.info(`[ServiceAuthHandler] Public key found, proceeding with encryption... [Public key: ${publicKeyString.slice(0, 30)}]...`); // Log first 30 chars for brevity
// Format key correctly (replace \n with actual newlines)
const formattedKey = publicKeyString.replace(/\\n/g, '\n');
// Import the public key
const publicKey = await jose.importSPKI(formattedKey, 'RSA-OAEP-256');
// Encode the token as Uint8Array (required by JOSE)
const tokenBytes = new TextEncoder().encode(token);
// Encrypt using JOSE's JWE format, which handles the hybrid encryption process
const jwe = await new jose.CompactEncrypt(tokenBytes)
.setProtectedHeader({
alg: 'RSA-OAEP-256', // Key encryption algorithm
enc: 'A256GCM' // Content encryption algorithm
})
.encrypt(publicKey);
return jwe;
}
catch (error) {
console.error('Error encrypting token:', error);
throw new Error('Failed to encrypt token');
}
}
//# sourceMappingURL=encryption.js.map