mirror of
https://github.com/keeweb/keeweb.git
synced 2024-06-22 07:16:38 +02:00
argon2 kdf settings editor
This commit is contained in:
parent
a77f61cc5d
commit
ab46c0d08b
|
@ -397,6 +397,10 @@
|
|||
"setFileBackupMonthly": "Monthly",
|
||||
"setFileBackupManually": "Manually, no auto-backups",
|
||||
"setFileRounds": "Key encryption rounds",
|
||||
"setFileKdfParams": "Key derivation function",
|
||||
"setFileKdfParamsIter": "Iterations",
|
||||
"setFileKdfParamsMem": "Memory, KB",
|
||||
"setFileKdfParamsPar": "Parallelism",
|
||||
"setFileKeyChangeForce": "Ask to change key after (days)",
|
||||
"setFileUseKeyFile": "Use key file",
|
||||
"setFileUseGenKeyFile": "Use generated key file",
|
||||
|
|
|
@ -59,23 +59,8 @@ const FileModel = Backbone.Model.extend({
|
|||
if (keyFileData) {
|
||||
kdbxweb.ByteUtils.zeroBuffer(keyFileData);
|
||||
}
|
||||
let kdfParams = '';
|
||||
if (db.header.kdfParameters) {
|
||||
kdfParams = db.header.kdfParameters.keys().map(key => {
|
||||
let val = db.header.kdfParameters.get(key);
|
||||
if (val instanceof ArrayBuffer) {
|
||||
return;
|
||||
}
|
||||
if (val.value) {
|
||||
val = val.value;
|
||||
}
|
||||
return key + '=' + val;
|
||||
}).filter(p => p).join('&');
|
||||
} else if (db.header.keyEncryptionRounds) {
|
||||
kdfParams = db.header.keyEncryptionRounds + ' rounds';
|
||||
}
|
||||
logger.info('Opened file ' + this.get('name') + ': ' + logger.ts(ts) + ', ' +
|
||||
kdfParams + ', ' + Math.round(fileData.byteLength / 1024) + ' kB');
|
||||
this.kdfArgsToString(db.header) + ', ' + Math.round(fileData.byteLength / 1024) + ' kB');
|
||||
callback();
|
||||
})
|
||||
.catch(err => {
|
||||
|
@ -92,6 +77,22 @@ const FileModel = Backbone.Model.extend({
|
|||
}
|
||||
},
|
||||
|
||||
kdfArgsToString: function(header) {
|
||||
if (header.kdfParameters) {
|
||||
return header.kdfParameters.keys().map(key => {
|
||||
const val = header.kdfParameters.get(key);
|
||||
if (val instanceof ArrayBuffer) {
|
||||
return;
|
||||
}
|
||||
return key + '=' + val;
|
||||
}).filter(p => p).join('&');
|
||||
} else if (header.keyEncryptionRounds) {
|
||||
return header.keyEncryptionRounds + ' rounds';
|
||||
} else {
|
||||
return '?';
|
||||
}
|
||||
},
|
||||
|
||||
create: function(name) {
|
||||
const password = kdbxweb.ProtectedValue.fromString('');
|
||||
const credentials = new kdbxweb.Credentials(password);
|
||||
|
@ -162,7 +163,8 @@ const FileModel = Backbone.Model.extend({
|
|||
historyMaxItems: this.db.meta.historyMaxItems,
|
||||
historyMaxSize: this.db.meta.historyMaxSize,
|
||||
keyEncryptionRounds: this.db.header.keyEncryptionRounds,
|
||||
keyChangeForce: this.db.meta.keyChangeForce
|
||||
keyChangeForce: this.db.meta.keyChangeForce,
|
||||
kdfParameters: this.readKdfParams()
|
||||
}, { silent: true });
|
||||
this.db.groups.forEach(function(group) {
|
||||
let groupModel = this.getGroup(this.subId(group.uuid.id));
|
||||
|
@ -177,6 +179,26 @@ const FileModel = Backbone.Model.extend({
|
|||
this.resolveFieldReferences();
|
||||
},
|
||||
|
||||
readKdfParams: function() {
|
||||
const kdfParameters = this.db.header.kdfParameters;
|
||||
if (!kdfParameters) {
|
||||
return undefined;
|
||||
}
|
||||
let uuid = kdfParameters.get('$UUID');
|
||||
if (!uuid) {
|
||||
return undefined;
|
||||
}
|
||||
uuid = kdbxweb.ByteUtils.bytesToBase64(uuid);
|
||||
if (uuid !== kdbxweb.Consts.KdfId.Argon2) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
parallelism: kdfParameters.get('P').valueOf(),
|
||||
iterations: kdfParameters.get('I').valueOf(),
|
||||
memory: kdfParameters.get('M').valueOf()
|
||||
};
|
||||
},
|
||||
|
||||
subId: function(id) {
|
||||
return this.id + ':' + id;
|
||||
},
|
||||
|
@ -496,6 +518,25 @@ const FileModel = Backbone.Model.extend({
|
|||
this.setModified();
|
||||
},
|
||||
|
||||
setKdfParameter: function(field, value) {
|
||||
const ValueType = kdbxweb.VarDictionary.ValueType;
|
||||
switch (field) {
|
||||
case 'memory':
|
||||
this.db.header.kdfParameters.set('M', ValueType.UInt64, kdbxweb.Int64.from(value));
|
||||
break;
|
||||
case 'iterations':
|
||||
this.db.header.kdfParameters.set('I', ValueType.UInt64, kdbxweb.Int64.from(value));
|
||||
break;
|
||||
case 'parallelism':
|
||||
this.db.header.kdfParameters.set('P', ValueType.UInt32, value);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
this.set('kdfParameters', this.readKdfParams());
|
||||
this.setModified();
|
||||
},
|
||||
|
||||
emptyTrash: function() {
|
||||
const trashGroup = this.getTrashGroup();
|
||||
if (trashGroup) {
|
||||
|
|
|
@ -43,7 +43,8 @@ const SettingsFileView = Backbone.View.extend({
|
|||
'input #settings__file-hist-len': 'changeHistoryLength',
|
||||
'input #settings__file-hist-size': 'changeHistorySize',
|
||||
'input #settings__file-key-rounds': 'changeKeyRounds',
|
||||
'input #settings__file-key-change-force': 'changeKeyChangeForce'
|
||||
'input #settings__file-key-change-force': 'changeKeyChangeForce',
|
||||
'input .settings__input-kdf': 'changeKdfParameter'
|
||||
},
|
||||
|
||||
appModel: null,
|
||||
|
@ -86,6 +87,7 @@ const SettingsFileView = Backbone.View.extend({
|
|||
historyMaxSize: Math.round(this.model.get('historyMaxSize') / 1024 / 1024),
|
||||
keyEncryptionRounds: this.model.get('keyEncryptionRounds'),
|
||||
keyChangeForce: this.model.get('keyChangeForce') > 0 ? this.model.get('keyChangeForce') : null,
|
||||
kdfParameters: this.kdfParametersToUi(this.model.get('kdfParameters')),
|
||||
storageProviders: storageProviders
|
||||
});
|
||||
if (!this.model.get('created')) {
|
||||
|
@ -94,6 +96,10 @@ const SettingsFileView = Backbone.View.extend({
|
|||
this.renderKeyFileSelect();
|
||||
},
|
||||
|
||||
kdfParametersToUi: function(kdfParameters) {
|
||||
return kdfParameters ? _.extend({}, kdfParameters, { memory: Math.round(kdfParameters.memory / 1024) }) : null;
|
||||
},
|
||||
|
||||
renderKeyFileSelect: function() {
|
||||
const keyFileName = this.model.get('keyFileName');
|
||||
const oldKeyFileName = this.model.get('oldKeyFileName');
|
||||
|
@ -494,6 +500,19 @@ const SettingsFileView = Backbone.View.extend({
|
|||
value = -1;
|
||||
}
|
||||
this.model.setKeyChange(true, value);
|
||||
},
|
||||
|
||||
changeKdfParameter: function(e) {
|
||||
const field = $(e.target).data('field');
|
||||
const mul = $(e.target).data('mul') || 1;
|
||||
const value = e.target.value * mul;
|
||||
if (isNaN(value)) {
|
||||
e.target.value = Math.round(this.model.get('kdfParameters')[field] / mul);
|
||||
return;
|
||||
}
|
||||
if (value > 0) {
|
||||
this.model.setKdfParameter(field, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -62,6 +62,26 @@
|
|||
height: 2em;
|
||||
}
|
||||
|
||||
&__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@extend .input-size-base;
|
||||
}
|
||||
|
||||
&__col-small {
|
||||
width: 30%;
|
||||
position: relative;
|
||||
>.settings__input {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__col-small-label {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__pre {
|
||||
@include user-select(text);
|
||||
white-space: pre-wrap;
|
||||
|
|
|
@ -250,11 +250,13 @@ input[type=range] {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.input-base {
|
||||
.input-size-base {
|
||||
width: 60%;
|
||||
@include tablet {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
}
|
||||
|
||||
.input-base {
|
||||
@extend .input-size-base;
|
||||
}
|
||||
|
|
|
@ -101,8 +101,29 @@
|
|||
<input type="text" pattern="\d+" required class="settings__input input-base" id="settings__file-hist-size" value="{{historyMaxSize}}" />
|
||||
|
||||
<h2>{{res 'advanced'}}</h2>
|
||||
{{#if keyEncryptionRounds}}
|
||||
<label for="settings__file-key-rounds">{{res 'setFileRounds'}}:</label>
|
||||
<input type="text" pattern="\d+" required class="settings__input input-base" id="settings__file-key-rounds" value="{{keyEncryptionRounds}}" />
|
||||
{{else if kdfParameters}}
|
||||
<label>{{res 'setFileKdfParams'}}: Argon2</label>
|
||||
<div class="settings__row">
|
||||
<div class="settings__col-small">
|
||||
<label class="settings__col-small-label" for="settings__file-kdf-iter">{{res 'setFileKdfParamsIter'}}:</label>
|
||||
<input type="text" pattern="\d+" required class="settings__input input-base settings__input-kdf"
|
||||
data-field="iterations" id="settings__file-kdf-iter" value="{{kdfParameters.iterations}}" maxlength="10" />
|
||||
</div>
|
||||
<div class="settings__col-small">
|
||||
<label class="settings__col-small-label" for="settings__file-kdf-mem">{{res 'setFileKdfParamsMem'}}:</label>
|
||||
<input type="text" pattern="\d+" required class="settings__input input-base settings__input-kdf"
|
||||
data-field="memory" data-mul="1024" id="settings__file-kdf-mem" value="{{kdfParameters.memory}}" maxlength="10" />
|
||||
</div>
|
||||
<div class="settings__col-small">
|
||||
<label class="settings__col-small-label" for="settings__file-kdf-par">{{res 'setFileKdfParamsPar'}}:</label>
|
||||
<input type="text" pattern="\d+" required class="settings__input input-base settings__input-kdf"
|
||||
data-field="parallelism" id="settings__file-kdf-par" value="{{kdfParameters.parallelism}}" maxlength="2" />
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<label for="settings__file-key-change-force">{{res 'setFileKeyChangeForce'}}:</label>
|
||||
<input type="text" pattern="\d*" class="settings__input input-base" id="settings__file-key-change-force" value="{{keyChangeForce}}" />
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"bourbon": "4.2.7",
|
||||
"dropbox": "keeweb/dropbox-js#0ac0efdc2711eece73f6ac044459e1fd0d5e9390",
|
||||
"font-awesome": "4.6.3",
|
||||
"kdbxweb": "c44761da37d41c799ece04799e3c164cfa79804c",
|
||||
"kdbxweb": "a4d58631f2c98667e0de2f46915db2dd79bddd07",
|
||||
"normalize.css": "4.2.0",
|
||||
"pikaday": "1.4.0",
|
||||
"FileSaver.js": "eligrey/FileSaver.js",
|
||||
|
|
Loading…
Reference in New Issue
Block a user