floDapps, floCloudAPI: Secure private key
- Store AES-encrypted private key in memory. (exploring memory of browser will not have raw private key)
- floDapps lock/unlock (in user): locks or unlock the private key (ie, lock= Password required, unlock= password not required in returning private key)
- floDapps.launchStartUp now accepts options object
- to lock the private key on startup, pass {lock_key: true} in options objects of launchStartUp
This commit is contained in:
parent
5ab0bc36f0
commit
b80bd43313
@ -1,4 +1,4 @@
|
|||||||
(function(EXPORTS) { //floCloudAPI v2.4.0
|
(function(EXPORTS) { //floCloudAPI v2.4.1
|
||||||
/* FLO Cloud operations to send/request application data*/
|
/* FLO Cloud operations to send/request application data*/
|
||||||
'use strict';
|
'use strict';
|
||||||
const floCloudAPI = EXPORTS;
|
const floCloudAPI = EXPORTS;
|
||||||
@ -10,7 +10,7 @@
|
|||||||
callback: (d, e) => console.debug(d, e)
|
callback: (d, e) => console.debug(d, e)
|
||||||
};
|
};
|
||||||
|
|
||||||
var user_id, user_public, user_private;
|
var user_id, user_public, user_private, aes_key;
|
||||||
const user = {
|
const user = {
|
||||||
get id() {
|
get id() {
|
||||||
if (!user_id)
|
if (!user_id)
|
||||||
@ -25,10 +25,10 @@
|
|||||||
sign(msg) {
|
sign(msg) {
|
||||||
if (!user_private)
|
if (!user_private)
|
||||||
throw "User not set";
|
throw "User not set";
|
||||||
return floCrypto.signData(msg, user_private);
|
return floCrypto.signData(msg, Crypto.AES.decrypt(user_private, aes_key));
|
||||||
},
|
},
|
||||||
clear() {
|
clear() {
|
||||||
user_id = user_public = user_private = undefined;
|
user_id = user_public = user_private = aes_key = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,14 +45,17 @@
|
|||||||
user: {
|
user: {
|
||||||
set: priv => {
|
set: priv => {
|
||||||
if (!priv)
|
if (!priv)
|
||||||
user_id = user_public = user_private = undefined;
|
user_id = user_public = user_private = aes_key = undefined;
|
||||||
else {
|
else {
|
||||||
user_public = floCrypto.getPubKeyHex(priv);
|
user_public = floCrypto.getPubKeyHex(priv);
|
||||||
user_id = floCrypto.getFloID(user_public);
|
user_id = floCrypto.getFloID(user_public);
|
||||||
if (!user_public || !user_id || !floCrypto.verifyPrivKey(priv, user_id))
|
if (!user_public || !user_id || !floCrypto.verifyPrivKey(priv, user_id))
|
||||||
user_id = user_public = user_private = undefined;
|
user_id = user_public = user_private = aes_key = undefined;
|
||||||
else
|
else {
|
||||||
user_private = priv;
|
let n = floCrypto.randInt(12, 20);
|
||||||
|
aes_key = floCrypto.randString(n);
|
||||||
|
user_private = Crypto.AES.encrypt(priv, aes_key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
get: () => user
|
get: () => user
|
||||||
|
|||||||
33
floDapps.js
33
floDapps.js
@ -1,4 +1,4 @@
|
|||||||
(function(EXPORTS) { //floDapps v2.3.0
|
(function(EXPORTS) { //floDapps v2.3.1
|
||||||
/* General functions for FLO Dapps*/
|
/* General functions for FLO Dapps*/
|
||||||
'use strict';
|
'use strict';
|
||||||
const floDapps = EXPORTS;
|
const floDapps = EXPORTS;
|
||||||
@ -11,12 +11,12 @@
|
|||||||
adminID: floGlobals.adminID
|
adminID: floGlobals.adminID
|
||||||
};
|
};
|
||||||
|
|
||||||
var raw_user_private; //private variable inside capsule
|
var user_priv_raw, aes_key, user_priv_wrap; //private variable inside capsule
|
||||||
const raw_user = {
|
const raw_user = {
|
||||||
get private() {
|
get private() {
|
||||||
if (!raw_user_private)
|
if (!user_priv_raw)
|
||||||
throw "User not logged in";
|
throw "User not logged in";
|
||||||
return raw_user_private;
|
return Crypto.AES.decrypt(user_priv_raw, aes_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,14 +38,21 @@
|
|||||||
else if (user_private instanceof Function)
|
else if (user_private instanceof Function)
|
||||||
return user_private();
|
return user_private();
|
||||||
else
|
else
|
||||||
return user_private;
|
return Crypto.AES.decrypt(user_private, aes_key);
|
||||||
},
|
},
|
||||||
get db_name() {
|
get db_name() {
|
||||||
return "floDapps#" + user.id;
|
return "floDapps#" + user.id;
|
||||||
},
|
},
|
||||||
|
lock() {
|
||||||
|
user_private = user_priv_wrap;
|
||||||
|
},
|
||||||
|
async unlock() {
|
||||||
|
if (await user.private === raw_user.private)
|
||||||
|
user_private = user_priv_raw;
|
||||||
|
},
|
||||||
clear() {
|
clear() {
|
||||||
user_id = user_public = user_private = undefined;
|
user_id = user_public = user_private = undefined;
|
||||||
raw_user_private = undefined;
|
user_priv_raw = aes_key = undefined;
|
||||||
delete user.contacts;
|
delete user.contacts;
|
||||||
delete user.pubKeys;
|
delete user.pubKeys;
|
||||||
delete user.messages;
|
delete user.messages;
|
||||||
@ -233,7 +240,7 @@
|
|||||||
resolve(inputVal)
|
resolve(inputVal)
|
||||||
});
|
});
|
||||||
|
|
||||||
function getCredentials(invisible_key) {
|
function getCredentials(lock_key) {
|
||||||
|
|
||||||
const readSharesFromIDB = indexArr => new Promise((resolve, reject) => {
|
const readSharesFromIDB = indexArr => new Promise((resolve, reject) => {
|
||||||
var promises = []
|
var promises = []
|
||||||
@ -325,10 +332,14 @@
|
|||||||
user_public = floCrypto.getPubKeyHex(privKey);
|
user_public = floCrypto.getPubKeyHex(privKey);
|
||||||
user_id = floCrypto.getFloID(privKey);
|
user_id = floCrypto.getFloID(privKey);
|
||||||
floCloudAPI.user = privKey; //Set user for floCloudAPI
|
floCloudAPI.user = privKey; //Set user for floCloudAPI
|
||||||
if (!invisible_key)
|
user_priv_wrap = () => checkIfPinRequired(key);
|
||||||
user_private = privKey;
|
let n = floCrypto.randInt(12, 20);
|
||||||
|
aes_key = floCrypto.randString(n);
|
||||||
|
user_priv_raw = Crypto.AES.encrypt(privKey, aes_key);
|
||||||
|
if (!lock_key)
|
||||||
|
user_private = user_priv_raw;
|
||||||
else
|
else
|
||||||
user_private = () => checkIfPinRequired(key);
|
user_private = user_priv_wrap;
|
||||||
resolve('Login Credentials loaded successful')
|
resolve('Login Credentials loaded successful')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
@ -388,7 +399,7 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
let p2 = new Promise((res, rej) => {
|
let p2 = new Promise((res, rej) => {
|
||||||
callAndLog(getCredentials(options.invisible_key)).then(r => {
|
callAndLog(getCredentials(options.lock_key)).then(r => {
|
||||||
callAndLog(initUserDB()).then(r => {
|
callAndLog(initUserDB()).then(r => {
|
||||||
callAndLog(loadUserDB())
|
callAndLog(loadUserDB())
|
||||||
.then(r => res(true))
|
.then(r => res(true))
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
//floDapps.addStartUpFunction('Sample', Promised Function)
|
//floDapps.addStartUpFunction('Sample', Promised Function)
|
||||||
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
|
//floDapps.setAppObjectStores({sampleObs1:{}, sampleObs2:{options{autoIncrement:true, keyPath:'SampleKey'}, Indexes:{sampleIndex:{}}}})
|
||||||
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
|
//floDapps.setCustomPrivKeyInput( () => { FUNCTION BODY *must resolve private key* } )
|
||||||
floDapps.launchStartUp( /*{invisible_key: true}*/ ).then(result => {
|
floDapps.launchStartUp( /*{lock_key: true}*/ ).then(result => {
|
||||||
console.log(result)
|
console.log(result)
|
||||||
alert(`Welcome FLO_ID: ${myFloID}`)
|
alert(`Welcome FLO_ID: ${myFloID}`)
|
||||||
//App functions....
|
//App functions....
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user