feat: use random IV for each request
This commit is contained in:
parent
19dfef6044
commit
a32754610a
3 changed files with 29 additions and 138 deletions
|
|
@ -206,7 +206,6 @@ async function serialSigner(path) {
|
||||||
handleSerialPortResponse: async function (value) {
|
handleSerialPortResponse: async function (value) {
|
||||||
const {command, commandData} = await this.extractCommand(value)
|
const {command, commandData} = await this.extractCommand(value)
|
||||||
this.logPublicCommandsResponse(command, commandData)
|
this.logPublicCommandsResponse(command, commandData)
|
||||||
|
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case COMMAND_SIGN_PSBT:
|
case COMMAND_SIGN_PSBT:
|
||||||
|
|
@ -243,7 +242,7 @@ async function serialSigner(path) {
|
||||||
console.log(` %c${value}`, 'background: #222; color: red')
|
console.log(` %c${value}`, 'background: #222; color: red')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
logPublicCommandsResponse: function(command, commandData){
|
logPublicCommandsResponse: function (command, commandData) {
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case COMMAND_SIGN_PSBT:
|
case COMMAND_SIGN_PSBT:
|
||||||
case COMMAND_PASSWORD:
|
case COMMAND_PASSWORD:
|
||||||
|
|
@ -595,7 +594,6 @@ async function serialSigner(path) {
|
||||||
.getSharedSecret(this.decryptionKey, hwwPublicKey)
|
.getSharedSecret(this.decryptionKey, hwwPublicKey)
|
||||||
.slice(1, 33)
|
.slice(1, 33)
|
||||||
|
|
||||||
|
|
||||||
this.$q.notify({
|
this.$q.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
message: 'Secure session created!',
|
message: 'Secure session created!',
|
||||||
|
|
@ -666,15 +664,19 @@ async function serialSigner(path) {
|
||||||
},
|
},
|
||||||
|
|
||||||
sendCommandSecure: async function (command, attrs = []) {
|
sendCommandSecure: async function (command, attrs = []) {
|
||||||
|
console.log('### sendCommandSecure')
|
||||||
const message = [command].concat(attrs).join(' ')
|
const message = [command].concat(attrs).join(' ')
|
||||||
|
const iv = window.crypto.getRandomValues(new Uint8Array(16))
|
||||||
const encrypted = await encryptMessage2(
|
const encrypted = await this.encryptMessage(
|
||||||
this.sharedSecret,
|
this.sharedSecret,
|
||||||
|
iv,
|
||||||
message.length + ' ' + message
|
message.length + ' ' + message
|
||||||
)
|
)
|
||||||
|
|
||||||
const encryptedHex = nobleSecp256k1.utils.bytesToHex(encrypted)
|
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) {
|
extractCommand: async function (value) {
|
||||||
const command = value.split(' ')[0]
|
const command = value.split(' ')[0]
|
||||||
|
|
@ -695,17 +697,17 @@ async function serialSigner(path) {
|
||||||
},
|
},
|
||||||
decryptData: async function (value) {
|
decryptData: async function (value) {
|
||||||
if (!this.sharedSecret) {
|
if (!this.sharedSecret) {
|
||||||
this.$q.notify({
|
|
||||||
type: 'warning',
|
|
||||||
message: 'Secure session not established!',
|
|
||||||
timeout: 10000
|
|
||||||
})
|
|
||||||
return '/error Secure session not established!'
|
return '/error Secure session not established!'
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const messageBytes = nobleSecp256k1.utils.hexToBytes(value)
|
const ivSize = 32
|
||||||
const decrypted1 = await decryptMessage2(
|
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,
|
this.sharedSecret,
|
||||||
|
iv,
|
||||||
messageBytes
|
messageBytes
|
||||||
)
|
)
|
||||||
const data = new TextDecoder().decode(decrypted1)
|
const data = new TextDecoder().decode(decrypted1)
|
||||||
|
|
@ -724,6 +726,20 @@ async function serialSigner(path) {
|
||||||
})
|
})
|
||||||
return '/error Failed to decrypt message from device!'
|
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 () {
|
created: async function () {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@
|
||||||
if (checkInt(arg.length) && checkInts(arg)) {
|
if (checkInt(arg.length) && checkInts(arg)) {
|
||||||
return new Uint8Array(arg);
|
return new Uint8Array(arg);
|
||||||
}
|
}
|
||||||
console.log('### aes encypt')
|
|
||||||
throw new Error('unsupported array-like object');
|
throw new Error('unsupported array-like object');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,9 +184,6 @@ function findAccountPathIssues(path = '') {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////
|
|
||||||
let ivHex = '000102030405060708090a0b0c0d0e0f'
|
|
||||||
|
|
||||||
function asciiToUint8Array(str) {
|
function asciiToUint8Array(str) {
|
||||||
var chars = []
|
var chars = []
|
||||||
for (var i = 0; i < str.length; ++i) {
|
for (var i = 0; i < str.length; ++i) {
|
||||||
|
|
@ -195,124 +192,3 @@ function asciiToUint8Array(str) {
|
||||||
return new Uint8Array(chars)
|
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue