diff --git a/lnbits/extensions/watchonly/static/components/serial-signer/serial-signer.js b/lnbits/extensions/watchonly/static/components/serial-signer/serial-signer.js index 4766351f..940d4ad6 100644 --- a/lnbits/extensions/watchonly/static/components/serial-signer/serial-signer.js +++ b/lnbits/extensions/watchonly/static/components/serial-signer/serial-signer.js @@ -206,7 +206,6 @@ async function serialSigner(path) { handleSerialPortResponse: async function (value) { const {command, commandData} = await this.extractCommand(value) this.logPublicCommandsResponse(command, commandData) - switch (command) { case COMMAND_SIGN_PSBT: @@ -243,7 +242,7 @@ async function serialSigner(path) { console.log(` %c${value}`, 'background: #222; color: red') } }, - logPublicCommandsResponse: function(command, commandData){ + logPublicCommandsResponse: function (command, commandData) { switch (command) { case COMMAND_SIGN_PSBT: case COMMAND_PASSWORD: @@ -595,7 +594,6 @@ async function serialSigner(path) { .getSharedSecret(this.decryptionKey, hwwPublicKey) .slice(1, 33) - this.$q.notify({ type: 'positive', message: 'Secure session created!', @@ -666,15 +664,19 @@ async function serialSigner(path) { }, sendCommandSecure: async function (command, attrs = []) { + console.log('### sendCommandSecure') const message = [command].concat(attrs).join(' ') - - const encrypted = await encryptMessage2( + const iv = window.crypto.getRandomValues(new Uint8Array(16)) + const encrypted = await this.encryptMessage( this.sharedSecret, + iv, message.length + ' ' + message ) const encryptedHex = nobleSecp256k1.utils.bytesToHex(encrypted) - await this.writer.write(encryptedHex + '\n') + const encryptedIvHex = nobleSecp256k1.utils.bytesToHex(iv) + console.log('### encryptedIvHex', encryptedIvHex) + await this.writer.write(encryptedHex + encryptedIvHex + '\n') }, extractCommand: async function (value) { const command = value.split(' ')[0] @@ -695,17 +697,17 @@ async function serialSigner(path) { }, decryptData: async function (value) { if (!this.sharedSecret) { - this.$q.notify({ - type: 'warning', - message: 'Secure session not established!', - timeout: 10000 - }) return '/error Secure session not established!' } try { - const messageBytes = nobleSecp256k1.utils.hexToBytes(value) - const decrypted1 = await decryptMessage2( + const ivSize = 32 + const messageHex = value.substring(0, value.length - ivSize) + const ivHex = value.substring(value.length - ivSize) + const messageBytes = nobleSecp256k1.utils.hexToBytes(messageHex) + const iv = nobleSecp256k1.utils.hexToBytes(ivHex) + const decrypted1 = await this.decryptMessage( this.sharedSecret, + iv, messageBytes ) const data = new TextDecoder().decode(decrypted1) @@ -724,6 +726,20 @@ async function serialSigner(path) { }) return '/error Failed to decrypt message from device!' } + }, + encryptMessage: async function (key, iv, message) { + while (message.length % 16 !== 0) message += ' ' + const encodedMessage = asciiToUint8Array(message) + + const aesCbc = new aesjs.ModeOfOperation.cbc(key, iv) + const encryptedBytes = aesCbc.encrypt(encodedMessage) + + return encryptedBytes + }, + decryptMessage: async function (key, iv, encryptedBytes) { + const aesCbc = new aesjs.ModeOfOperation.cbc(key, iv) + const decryptedBytes = aesCbc.decrypt(encryptedBytes) + return decryptedBytes } }, created: async function () { diff --git a/lnbits/extensions/watchonly/static/js/crypto/aes.js b/lnbits/extensions/watchonly/static/js/crypto/aes.js index 8a28b655..92a17ca2 100644 --- a/lnbits/extensions/watchonly/static/js/crypto/aes.js +++ b/lnbits/extensions/watchonly/static/js/crypto/aes.js @@ -47,7 +47,6 @@ if (checkInt(arg.length) && checkInts(arg)) { return new Uint8Array(arg); } - console.log('### aes encypt') throw new Error('unsupported array-like object'); } diff --git a/lnbits/extensions/watchonly/static/js/utils.js b/lnbits/extensions/watchonly/static/js/utils.js index 36a2247c..adfd2422 100644 --- a/lnbits/extensions/watchonly/static/js/utils.js +++ b/lnbits/extensions/watchonly/static/js/utils.js @@ -184,9 +184,6 @@ function findAccountPathIssues(path = '') { } } -/////////////// -let ivHex = '000102030405060708090a0b0c0d0e0f' - function asciiToUint8Array(str) { var chars = [] for (var i = 0; i < str.length; ++i) { @@ -195,124 +192,3 @@ function asciiToUint8Array(str) { return new Uint8Array(chars) } -async function encryptMessage(key, message) { - // The iv must never be reused with a given key. - // iv = window.crypto.getRandomValues(new Uint8Array(16)); - iv = new Uint8Array([ - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f - ]) - const ciphertext = await window.crypto.subtle.encrypt( - { - name: 'AES-CBC', - iv - }, - key, - message - ) - - console.log('### #####################################') - return new Uint8Array(ciphertext) -} - -async function encryptMessage2(key, message) { - // The iv must never be reused with a given key. - // iv = window.crypto.getRandomValues(new Uint8Array(16)); - while (message.length % 16 !== 0) message += ' ' - const encodedMessage = asciiToUint8Array(message) - iv = new Uint8Array([ - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f - ]) - - const aesCbc = new aesjs.ModeOfOperation.cbc(key, iv) - const encryptedBytes = aesCbc.encrypt(encodedMessage) - - console.log('### #####################################') - return encryptedBytes -} - -async function decryptMessage(key, ciphertext) { - iv = new Uint8Array([ - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f - ]) - - let decrypted = await window.crypto.subtle.decrypt( - { - name: 'AES-CBC', - iv - }, - key, - ciphertext - ) - - return decrypted -} - -async function decryptMessage2(key, encryptedBytes) { - iv = new Uint8Array([ - 0x00, - 0x01, - 0x02, - 0x03, - 0x04, - 0x05, - 0x06, - 0x07, - 0x08, - 0x09, - 0x0a, - 0x0b, - 0x0c, - 0x0d, - 0x0e, - 0x0f - ]) - const aesCbc = new aesjs.ModeOfOperation.cbc(key, iv) - const decryptedBytes = aesCbc.decrypt(encryptedBytes) - console.log('### decryptedBytes', decryptedBytes) - return decryptedBytes -}