diff --git a/src/composables/useNostrChat.ts b/src/composables/useNostrChat.ts index 343c25c..852d219 100644 --- a/src/composables/useNostrChat.ts +++ b/src/composables/useNostrChat.ts @@ -381,12 +381,44 @@ export function useNostrChat() { } try { + // Validate keys before encryption + if (!currentUser.value.prvkey || !peerPubkey) { + throw new Error('Missing private key or peer public key') + } + + // Ensure keys are in correct hex format (64 characters for private key, 64 characters for public key) + const privateKey = currentUser.value.prvkey.startsWith('0x') + ? currentUser.value.prvkey.slice(2) + : currentUser.value.prvkey + + const publicKey = peerPubkey.startsWith('0x') + ? peerPubkey.slice(2) + : peerPubkey + + if (privateKey.length !== 64) { + throw new Error(`Invalid private key length: ${privateKey.length} (expected 64)`) + } + + if (publicKey.length !== 64) { + throw new Error(`Invalid public key length: ${publicKey.length} (expected 64)`) + } + + console.log('Encrypting message with keys:', { + privateKeyLength: privateKey.length, + publicKeyLength: publicKey.length, + privateKeyPrefix: privateKey.slice(0, 8) + '...', + publicKeyPrefix: publicKey.slice(0, 8) + '...', + contentLength: content.length + }) + // Encrypt the message const encryptedContent = await nip04.encrypt( - currentUser.value.prvkey, - peerPubkey, + privateKey, + publicKey, content ) + + console.log('Message encrypted successfully, length:', encryptedContent.length) // Create the event template const eventTemplate: EventTemplate = { @@ -397,7 +429,7 @@ export function useNostrChat() { } // Finalize the event (sign it) - const event = finalizeEvent(eventTemplate, hexToBytes(currentUser.value.prvkey)) + const event = finalizeEvent(eventTemplate, hexToBytes(privateKey)) // Publish to relays const relayConfigs = getRelays() diff --git a/src/lib/utils/crypto.ts b/src/lib/utils/crypto.ts index 1a62f52..b82c217 100644 --- a/src/lib/utils/crypto.ts +++ b/src/lib/utils/crypto.ts @@ -6,16 +6,26 @@ * Convert hex string to Uint8Array */ export function hexToBytes(hex: string): Uint8Array { + if (typeof hex !== 'string') { + throw new TypeError('hexToBytes: expected string, got ' + typeof hex) + } + if (hex.length % 2 !== 0) { - throw new Error('Hex string must have even length') + throw new Error('hexToBytes: received invalid unpadded hex') } - const bytes = hex.match(/.{2}/g)?.map(byte => parseInt(byte, 16)) - if (!bytes) { - throw new Error('Invalid hex string') + const array = new Uint8Array(hex.length / 2) + for (let i = 0; i < array.length; i++) { + const j = i * 2 + const hexByte = hex.slice(j, j + 2) + const byte = Number.parseInt(hexByte, 16) + if (Number.isNaN(byte) || byte < 0) { + throw new Error('Invalid byte sequence') + } + array[i] = byte } - return new Uint8Array(bytes) + return array } /**