Skip to content

Commit

Permalink
removed redundant hashing of iv
Browse files Browse the repository at this point in the history
  • Loading branch information
Arlen Anderson committed Jan 26, 2017
1 parent 1535c6f commit 82211d9
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ When it comes time to use your recovery seed, just scan the QR Code with your ph
How secure is it?
-------------

Your recovery seed is encrypted with the [Cipher Block Chaining (CBC)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode of the [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) with a 256 bit key length. Your key is generated using a password of your choice and a [random salt](https://en.wikipedia.org/wiki/Salt_(cryptography)), hashed 1 million times with [pbkdf2](https://en.wikipedia.org/wiki/PBKDF2). The CBC [Initialization Vector](https://en.wikipedia.org/wiki/Initialization_vector) is randomly generated and hashed with the same salt another 1 million times. Encrypting the same data with the same key will yield a different result every time.
Your recovery seed is encrypted with the [Cipher Block Chaining (CBC)](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#CBC) mode of the [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) with a 256 bit key length. Your key is generated using a password of your choice and a [random salt](https://en.wikipedia.org/wiki/Salt_(cryptography)), hashed 1 million times with [pbkdf2](https://en.wikipedia.org/wiki/PBKDF2) (sha512). Encrypting the same data with the same key will yield a different result every time.

**If you forget your password, your seed is lost. There is no recovery.**

Expand Down
File renamed without changes
6 changes: 4 additions & 2 deletions src/components/Input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,11 @@ class Input extends React.Component {
});
}

const [salt, iv, encrypted] = input.split(':');
const
test = input.split('|'),
test2 = input.split(':');

if (!salt || !iv || !encrypted) {
if (test.length !== 3 && test2.length !== 3) {
return this.setState({
inputError: 'Invalid hash'
});
Expand Down
30 changes: 17 additions & 13 deletions src/containers/Application.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,17 @@ class Application extends React.Component {
error: null
});

let key, hashedIv, cipher, encrypted, blob, qrcode;
let key, cipher, encrypted, blob, qrcode;
const
salt = await randomBytes(32),
iv = await randomBytes(32);
iv = await randomBytes(16);


try {
key = await pbkdf2(password, salt, 1000000, 32, 'sha512');
hashedIv = await pbkdf2(iv, salt, 1000000, 16, 'sha512');
cipher = createCipheriv('aes256', key, hashedIv);
cipher = createCipheriv('aes256', key, iv);
encrypted = cipher.update(input, 'utf8', 'base64') + cipher.final('base64');
blob = `${salt.toString('base64')}:${iv.toString('base64')}:${encrypted}`;
blob = `${salt.toString('base64')}|${iv.toString('base64')}|${encrypted}`;
qrcode = qr.imageSync(blob);
} catch (e) {
return this.setState({
Expand Down Expand Up @@ -78,18 +77,23 @@ class Application extends React.Component {
});

let decrypted,
[salt, iv, encrypted] = input.split(':'), //eslint-disable-line prefer-const
key, hashedIv, decipher;
[salt, iv, encrypted] = input.split('|'), //eslint-disable-line prefer-const
key, decipher;

try {

salt = Buffer.from(salt, 'base64');
iv = Buffer.from(iv, 'base64');

try {
if (!(salt && iv && encrypted)) {
[salt, iv, encrypted] = input.split(':');
salt = Buffer.from(salt, 'base64');
iv = await pbkdf2(Buffer.from(iv, 'base64'), salt, 1000000, 16, 'sha512');
} else {
salt = Buffer.from(salt, 'base64');
iv = Buffer.from(iv, 'base64');
}

key = await pbkdf2(password, salt, 1000000, 32, 'sha512');
hashedIv = await pbkdf2(iv, salt, 1000000, 16, 'sha512');
decipher = createDecipheriv('aes256', key, hashedIv);
decipher = createDecipheriv('aes256', key, iv);
decrypted = decipher.update(encrypted, 'base64', 'utf8') + decipher.final('utf8');
} catch (e) {
return this.setState({
Expand All @@ -111,7 +115,7 @@ class Application extends React.Component {

render() {
const {encrypted, decrypted, thinking, qrcode, error} = this.state;

return (
<div>
<div className="row center-xs" style={{margin: 25}}>
Expand Down

0 comments on commit 82211d9

Please sign in to comment.