Skip to content

Commit

Permalink
bump version (2.3.3), fix encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelFedora committed Jul 23, 2019
1 parent c7a282d commit 67850cf
Show file tree
Hide file tree
Showing 10 changed files with 32 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "web-ext",
"version": "2.3.2",
"version": "2.3.3",
"description": "Adds Blockstack support to a web broswer.",
"main": "blockstack-background.js",
"private": true,
Expand Down
7 changes: 4 additions & 3 deletions src/common/components/bs-login/bs-login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as bip32 from 'bip32';
import { BIP32Interface } from 'bip32';
import { randomBytes } from 'crypto';
import { dispatch, commit } from '../../vuex/remote-interface';
import { encrypt } from '../../util';
import { encrypt, createIv } from '../../util';
import { FieldFlags } from 'vee-validate';
import { StateType } from '../../vuex/stores/types/state';

Expand Down Expand Up @@ -85,10 +85,11 @@ export default (Vue as VVue).component('bs-login', {
} else {
throw new Error('Tried to initialize a wallet with a bad phrase');
}
return encrypt(this.phrase, this.pass).then(encryptedBackupPhrase => {
const iv = await createIv();
return encrypt(this.phrase, this.pass, iv).then(encryptedBackupPhrase => {
console.log('Creating account w/ enc phrase: "' + encryptedBackupPhrase + '"!');
return dispatch('account/createAccount',
{ email: this.email, encryptedBackupPhrase, masterKeychain: masterKeychain.toBase58() });
{ email: this.email, encryptedBackupPhrase, iv, masterKeychain: masterKeychain.toBase58() });
});
},
async initializeIdentity(autoGenProfile?: boolean) {
Expand Down
16 changes: 11 additions & 5 deletions src/common/util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { payments, ECPair } from 'bitcoinjs-lib';
import { BIP32Interface } from 'bip32';
import { createCipher, createDecipher, randomBytes } from 'crypto';
import { randomBytes, createDecipheriv, createCipheriv, createHash } from 'crypto';
import { StateType } from './vuex/stores/types/state';
import { TokenSigner } from 'jsontokens';
import { connectToGaiaHub, uploadToGaiaHub } from 'blockstack';
Expand All @@ -11,15 +11,21 @@ export function getAddress(node: BIP32Interface, network?: any) {
return payments.p2pkh({ pubkey: node.publicKey }).address;
}

export async function encrypt(data: string, key: string): Promise<string> {
const cipher = createCipher('aes192', key);
export async function createIv() {
return createHash('sha256').update(randomBytes(16)).digest('hex').slice(0, 16);
}

export async function encrypt(data: string, key: string, iv: string): Promise<string> {
const k = createHash('sha256').update(key).digest();
const cipher = createCipheriv('aes256', k, iv);
let enc = cipher.update(data, 'utf8', 'hex');
enc += cipher.final('hex');
return enc;
}

export async function decrypt(data: string, key: string): Promise<string> {
const decipher = createDecipher('aes192', key);
export async function decrypt(data: string, key: string, iv: string): Promise<string> {
const k = createHash('sha256').update(key).digest();
const decipher = createDecipheriv('aes256', k, iv);
let dec = decipher.update(data, 'hex', 'utf8');
dec += decipher.final('utf8');
return dec;
Expand Down
16 changes: 10 additions & 6 deletions src/common/vuex/stores/account.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Module } from 'vuex';
import { WrappedKeychain } from '../../data/wrapped-keychain';
import { AccountStateType, SATOSHIS_IN_BTC } from './types/account.state';
import { StateType } from './types/state';
import { decrypt, encrypt } from '../../util';
import { decrypt, encrypt, createIv } from '../../util';
import { validateMnemonic, mnemonicToSeed } from 'bip39';
import Axios, { AxiosPromise, AxiosResponse } from 'axios';
import { config, transactions, network } from 'blockstack';
Expand All @@ -13,6 +13,7 @@ function makeState(): AccountStateType {
accountCreated: false,
email: '',
encryptedBackupPhrase: '',
iv: null,
bitcoinAccount: {
publicKeychain: '',
addresses: [] as string[],
Expand Down Expand Up @@ -51,9 +52,10 @@ export const accountModule: Module<AccountStateType, StateType> = {
async reset({ commit }) {
commit('reset');
},
async createAccount({ commit, state }, { email, encryptedBackupPhrase, masterKeychain, identitiesToGenerate }: {
async createAccount({ commit, state }, { email, encryptedBackupPhrase, iv, masterKeychain, identitiesToGenerate }: {
email?: string,
encryptedBackupPhrase: string,
iv: string,
masterKeychain: string,
identitiesToGenerate?: number
}) {
Expand All @@ -72,6 +74,7 @@ export const accountModule: Module<AccountStateType, StateType> = {
email: email || state.email,
accountCreated: true,
encryptedBackupPhrase,
iv,
bitcoinAccount: {
publicKeychain: wrapped.bitcoinPublicKeychain.toBase58(),
addresses: [firstBitcoinAddress],
Expand All @@ -81,10 +84,11 @@ export const accountModule: Module<AccountStateType, StateType> = {
} as Partial<AccountStateType>);
},
async changePassword({ state, commit }, { newpass, oldpass }: { newpass: string, oldpass: string }) {
const phrase = await decrypt(state.encryptedBackupPhrase, oldpass);
const phrase = await decrypt(state.encryptedBackupPhrase, oldpass, state.iv);
if(!validateMnemonic(phrase)) throw new Error('Wrong password!');
const encryptedBackupPhrase = await encrypt(phrase, newpass);
commit('update', { encryptedBackupPhrase });
const iv = await createIv();
const encryptedBackupPhrase = await encrypt(phrase, newpass, iv);
commit('update', { iv, encryptedBackupPhrase });
},
async refreshBalances({ state, commit, rootState }) {
const balances: { [key: string]: number } = { };
Expand All @@ -105,7 +109,7 @@ export const accountModule: Module<AccountStateType, StateType> = {
},
async withdraw({ state, dispatch }, { to, amount, password }: { to: string, amount: number, password: string }) {
if(amount > state.bitcoinAccount.balances[0]) throw new Error('Will not overwithdraw from the account.')
const phrase = await decrypt(state.encryptedBackupPhrase, password);
const phrase = await decrypt(state.encryptedBackupPhrase, password, state.iv);
if(!validateMnemonic(phrase)) throw new Error('Wrong password!');
const seedBuffer = mnemonicToSeed(phrase);
const masterKeychain = WrappedNode.fromSeed(seedBuffer);
Expand Down
2 changes: 1 addition & 1 deletion src/common/vuex/stores/identity.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export const identityModule: Module<IdentityStateType, StateType> = {
commit('reset');
},
async create({ commit, state, rootState }, { password, index }: { password: string, index?: number }) {
const phrase = await decrypt(rootState.account.encryptedBackupPhrase, password);
const phrase = await decrypt(rootState.account.encryptedBackupPhrase, password, rootState.account.iv);
if(!validateMnemonic(phrase)) throw new Error('Wrong password!');
if(!index) {
if(!state.identities.length) index = 0;
Expand Down
1 change: 1 addition & 0 deletions src/common/vuex/stores/types/account.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface AccountStateType {
accountCreated: boolean;
email: string; // dumb =T
encryptedBackupPhrase: string;
iv: string;
bitcoinAccount: {
publicKeychain: string;
addresses: string[];
Expand Down
2 changes: 1 addition & 1 deletion src/main/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export default (Vue as VVue).extend({
type: 'password'
},
onConfirm: (value) => {
decrypt(this.$store.state.account.encryptedBackupPhrase, value).then(phrase => {
decrypt(this.$store.state.account.encryptedBackupPhrase, value, this.$store.state.account.iv).then(phrase => {
this.$dialog.alert({
title: 'Backup Phrase',
message: `<div class='content'>
Expand Down
2 changes: 1 addition & 1 deletion src/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "(Unofficial) Blockstack Extension",
"short_name": "uBlockstack",
"version": "2.3.2",
"version": "2.3.3",
"author": "Michael Fedora",
"homepage_url": "https://github.com/michaelfedora/unofficial-blockstack-extension",

Expand Down
2 changes: 1 addition & 1 deletion src/popup/app/components/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export default (Vue as VVue).component('bs-popup-settings', {
type: 'password'
},
onConfirm: (value) => {
decrypt(this.$store.state.account.encryptedBackupPhrase, value).then(phrase => {
decrypt(this.$store.state.account.encryptedBackupPhrase, value, this.$store.state.account.iv).then(phrase => {
this.$dialog.alert({
title: 'Backup Phrase',
message: `<div class='content'>
Expand Down

0 comments on commit 67850cf

Please sign in to comment.