adding method to export credentials

This commit is contained in:
El RIDO 2019-06-28 07:14:28 +02:00
parent c707c87cac
commit 9d2d7bde42
No known key found for this signature in database
GPG Key ID: 0F5C940A6BD81F92
6 changed files with 89 additions and 11 deletions

View File

@ -924,6 +924,58 @@ jQuery.PrivateBin = (function($, RawDeflate) {
}; };
} }
/**
* get PBKDF2 protected credentials for server to validate password
*
* @name CryptTool.getCredentials
* @function
* @param {string} key
* @param {string} password
* @return {string} decrypted message, empty if decryption failed
*/
me.getCredentials = async function(key, password)
{
let keyArray = stringToArraybuffer(key);
if (password.length > 0) {
let passwordArray = stringToArraybuffer(password),
newKeyArray = new Uint8Array(keyArray.length + passwordArray.length);
newKeyArray.set(keyArray, 0);
newKeyArray.set(passwordArray, keyArray.length);
keyArray = newKeyArray;
}
// import raw key
const importedKey = await window.crypto.subtle.importKey(
'raw', // only 'raw' is allowed
keyArray.slice(16),
{name: 'PBKDF2'}, // we use PBKDF2 for key derivation
false, // the key may not be exported
['deriveKey'] // we may only use it for key derivation
);
// derive a stronger key for use with AES
const derivedKey = await window.crypto.subtle.deriveKey(
{
name: 'PBKDF2', // we use PBKDF2 for key derivation
salt: keyArray.slice(0, 16), // salt used in HMAC
iterations: 100000, // amount of iterations to apply
hash: {name: 'SHA-256'} // can be "SHA-1", "SHA-256", "SHA-384" or "SHA-512"
},
importedKey,
{
name: 'AES-GCM', // can be any supported AES algorithm ("AES-CTR", "AES-CBC", "AES-CMAC", "AES-GCM", "AES-CFB", "AES-KW", "ECDH", "DH" or "HMAC")
length: 256 // can be 128, 192 or 256
},
true, // the key can be exported
['encrypt'] // we want to export it
);
return btoa(
arraybufferToString(
await window.crypto.subtle.exportKey('raw', derivedKey)
)
);
}
/** /**
* compress, then encrypt message with given key and password * compress, then encrypt message with given key and password
* *

View File

@ -4,9 +4,6 @@ var common = require('../common');
describe('AttachmentViewer', function () { describe('AttachmentViewer', function () {
describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () { describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
this.timeout(30000); this.timeout(30000);
before(function () {
cleanup();
});
jsc.property( jsc.property(
'displays & hides data as requested', 'displays & hides data as requested',

View File

@ -237,19 +237,48 @@ conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
}); });
}); });
describe('getCredentials', function () {
it('generates credentials with password', async function () {
const clean = jsdom();
window.crypto = new WebCrypto();
// choosen by fair dice roll
const key = atob('EqueAutxlrekNNEvJWB1uaaiwbk/GGpn4++cdk+uDMc='),
// -- "That's amazing. I've got the same combination on my luggage."
password = Array.apply(0, Array(6)).map((_,b) => b + 1).join('');
const credentials = await $.PrivateBin.CryptTool.getCredentials(
key, password
);
clean();
assert.strictEqual(credentials, 'JS8bJWFx1bAPI2LMxfWrw4AQ7cedNVl8UmjUd/pW7Yg=');
});
it('generates credentials without password', async function () {
const clean = jsdom();
window.crypto = new WebCrypto();
// choosen by fair dice roll
const key = atob('U844LK1y2uUPthTgMvPECwGyQzwScCwkaEI/+qLfQSE='),
password = '';
const credentials = await $.PrivateBin.CryptTool.getCredentials(
key, password
);
clean();
assert.strictEqual(credentials, 'VfAvY7T9rm3K3JKtiOeb+B+rXnE6yZ4bYQTaD9jwjEk=');
});
});
describe('getSymmetricKey', function () { describe('getSymmetricKey', function () {
this.timeout(30000); this.timeout(30000);
var keys = []; let keys = [];
// the parameter is used to ensure the test is run more then one time // the parameter is used to ensure the test is run more then one time
jsc.property( jsc.property(
'returns random, non-empty keys', 'returns random, non-empty keys',
'integer', 'integer',
function(counter) { function(counter) {
var clean = jsdom(); const clean = jsdom();
window.crypto = new WebCrypto(); window.crypto = new WebCrypto();
var key = $.PrivateBin.CryptTool.getSymmetricKey(), const key = $.PrivateBin.CryptTool.getSymmetricKey(),
result = (key !== '' && keys.indexOf(key) === -1); result = (key !== '' && keys.indexOf(key) === -1);
keys.push(key); keys.push(key);
clean(); clean();
return result; return result;

View File

@ -22,7 +22,7 @@ describe('InitialCheck', function () {
'</body></html>' '</body></html>'
); );
$.PrivateBin.Alert.init(); $.PrivateBin.Alert.init();
window.crypto = null; window.crypto = new WebCrypto();
const result1 = !$.PrivateBin.InitialCheck.init(), const result1 = !$.PrivateBin.InitialCheck.init(),
result2 = !$('#errormessage').hasClass('hidden'); result2 = !$('#errormessage').hasClass('hidden');
clean(); clean();
@ -76,7 +76,7 @@ describe('InitialCheck', function () {
'</body></html>' '</body></html>'
); );
$.PrivateBin.Alert.init(); $.PrivateBin.Alert.init();
window.crypto = null; window.crypto = new WebCrypto();
const result1 = $.PrivateBin.InitialCheck.init(), const result1 = $.PrivateBin.InitialCheck.init(),
result2 = isSecureContext === $('#httpnotice').hasClass('hidden'); result2 = isSecureContext === $('#httpnotice').hasClass('hidden');
clean(); clean();

View File

@ -71,7 +71,7 @@ if ($MARKDOWN):
endif; endif;
?> ?>
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.11.js" integrity="sha512-p7UyJuyBkhMcMgE4mDsgK0Lz70OvetLefua1oXs1OujWv9gOxh4xy8InFux7bZ4/DAZsTmO4rgVwZW9BHKaTaw==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/purify-1.0.11.js" integrity="sha512-p7UyJuyBkhMcMgE4mDsgK0Lz70OvetLefua1oXs1OujWv9gOxh4xy8InFux7bZ4/DAZsTmO4rgVwZW9BHKaTaw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-Yq2HyT+H1PmQxCaDeh6E/ChOrTBSYsu8BuS4yb8UPHlyMVaxqSOtyfy6hx6vAsVT0G3bKeLRAuejhvPTOoz7fQ==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-GNjHU6N7D0xG0WHf1DSrJrGavV+ES+w2t0vgICKD2UJ6g40Y1W+3le0iX7GgC8G6ADBsepMSaEyh47a2adA2HA==" crossorigin="anonymous"></script>
<!--[if IE]> <!--[if IE]>
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style> <style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style>
<![endif]--> <![endif]-->

View File

@ -49,7 +49,7 @@ if ($MARKDOWN):
endif; endif;
?> ?>
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.11.js" integrity="sha512-p7UyJuyBkhMcMgE4mDsgK0Lz70OvetLefua1oXs1OujWv9gOxh4xy8InFux7bZ4/DAZsTmO4rgVwZW9BHKaTaw==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/purify-1.0.11.js" integrity="sha512-p7UyJuyBkhMcMgE4mDsgK0Lz70OvetLefua1oXs1OujWv9gOxh4xy8InFux7bZ4/DAZsTmO4rgVwZW9BHKaTaw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-Yq2HyT+H1PmQxCaDeh6E/ChOrTBSYsu8BuS4yb8UPHlyMVaxqSOtyfy6hx6vAsVT0G3bKeLRAuejhvPTOoz7fQ==" crossorigin="anonymous"></script> <script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-GNjHU6N7D0xG0WHf1DSrJrGavV+ES+w2t0vgICKD2UJ6g40Y1W+3le0iX7GgC8G6ADBsepMSaEyh47a2adA2HA==" crossorigin="anonymous"></script>
<!--[if IE]> <!--[if IE]>
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style> <style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;}</style>
<![endif]--> <![endif]-->