Merge pull request #40 from isocolsky/encryption_key
fix message encryption/decryption
This commit is contained in:
commit
58e4d66901
|
@ -15,7 +15,7 @@ var ServerCompromisedError = require('./servercompromisederror')
|
|||
|
||||
var BASE_URL = 'http://localhost:3001/copay/api';
|
||||
|
||||
var WALLET_CRITICAL_DATA = ['xPrivKey', 'm', 'publicKeyRing'];
|
||||
var WALLET_CRITICAL_DATA = ['xPrivKey', 'm', 'publicKeyRing', 'sharedEncryptingKey'];
|
||||
|
||||
function _encryptProposalMessage(message, encryptingKey) {
|
||||
if (!message) return null;
|
||||
|
@ -24,7 +24,11 @@ function _encryptProposalMessage(message, encryptingKey) {
|
|||
|
||||
function _decryptProposalMessage(message, encryptingKey) {
|
||||
if (!message) return '';
|
||||
return WalletUtils.decryptMessage(message, encryptingKey);
|
||||
try {
|
||||
return WalletUtils.decryptMessage(message, encryptingKey);
|
||||
} catch (ex) {
|
||||
return '<ECANNOTDECRYPT>';
|
||||
}
|
||||
};
|
||||
|
||||
function _parseError(body) {
|
||||
|
@ -161,8 +165,9 @@ API.prototype._doGetRequest = function(url, data, cb) {
|
|||
|
||||
API.prototype._initData = function(network, walletPrivKey, m, n) {
|
||||
var xPrivKey = new Bitcore.HDPrivateKey(network);
|
||||
var signingPrivKey = (new Bitcore.HDPrivateKey(xPrivKey)).derive('m/1/0').privateKey.toWIF();
|
||||
var xPubKey = (new Bitcore.HDPublicKey(xPrivKey)).toString();
|
||||
var signingPrivKey = (new Bitcore.HDPrivateKey(xPrivKey)).derive('m/1/0').privateKey;
|
||||
var sharedEncryptingKey = Bitcore.crypto.Hash.sha256(signingPrivKey.toBuffer()).slice(0, 16).toString('base64');
|
||||
var copayerId = WalletUtils.xPubToCopayerId(xPubKey);
|
||||
|
||||
var data = {
|
||||
|
@ -172,8 +177,9 @@ API.prototype._initData = function(network, walletPrivKey, m, n) {
|
|||
network: network,
|
||||
m: m,
|
||||
n: n,
|
||||
signingPrivKey: signingPrivKey,
|
||||
signingPrivKey: signingPrivKey.toWIF(),
|
||||
walletPrivKey: walletPrivKey.toWIF(),
|
||||
sharedEncryptingKey: sharedEncryptingKey,
|
||||
};
|
||||
return data;
|
||||
};
|
||||
|
@ -291,8 +297,8 @@ API.prototype.getStatus = function(cb) {
|
|||
var url = '/v1/wallets/';
|
||||
self._doGetRequest(url, data, function(err, body) {
|
||||
_.each(body.pendingTxps, function(txp) {
|
||||
txp.message = _decryptProposalMessage(txp.message, data.signingPrivKey);
|
||||
});
|
||||
txp.message = _decryptProposalMessage(txp.message, data.sharedEncryptingKey);
|
||||
});
|
||||
|
||||
return cb(err, body, data.copayerId);
|
||||
});
|
||||
|
@ -323,7 +329,7 @@ API.prototype.sendTxProposal = function(opts, cb) {
|
|||
var args = {
|
||||
toAddress: opts.toAddress,
|
||||
amount: amount,
|
||||
message: _encryptProposalMessage(opts.message, data.signingPrivKey),
|
||||
message: _encryptProposalMessage(opts.message, data.sharedEncryptingKey),
|
||||
};
|
||||
var hash = WalletUtils.getProposalHash(args.toAddress, args.amount, args.message);
|
||||
args.proposalSignature = WalletUtils.signMessage(hash, data.signingPrivKey);
|
||||
|
@ -428,7 +434,7 @@ API.prototype.getTxProposals = function(opts, cb) {
|
|||
if (err) return cb(err);
|
||||
|
||||
_.each(txps, function(txp) {
|
||||
txp.message = _decryptProposalMessage(txp.message, data.signingPrivKey);
|
||||
txp.message = _decryptProposalMessage(txp.message, data.sharedEncryptingKey);
|
||||
});
|
||||
return cb(null, txps);
|
||||
});
|
||||
|
|
|
@ -83,20 +83,18 @@ WalletUtils.fromSecret = function(secret) {
|
|||
};
|
||||
|
||||
|
||||
WalletUtils.encryptMessage = function(message, privKey) {
|
||||
var hash = sjcl.hash.sha256.hash(privKey);
|
||||
var key = sjcl.codec.utf8String.toBits(hash);
|
||||
key = sjcl.bitArray.clamp(key, 128);
|
||||
WalletUtils.encryptMessage = function(message, encryptingKey) {
|
||||
var key = sjcl.codec.base64.toBits(encryptingKey);
|
||||
//key = sjcl.bitArray.clamp(key, 128);
|
||||
return sjcl.encrypt(key, message, {
|
||||
ks: 128,
|
||||
iter: 1
|
||||
});
|
||||
};
|
||||
|
||||
WalletUtils.decryptMessage = function(cyphertextJson, privKey) {
|
||||
var hash = sjcl.hash.sha256.hash(privKey);
|
||||
var key = sjcl.codec.utf8String.toBits(hash);
|
||||
key = sjcl.bitArray.clamp(key, 128);
|
||||
WalletUtils.decryptMessage = function(cyphertextJson, encryptingKey) {
|
||||
var key = sjcl.codec.base64.toBits(encryptingKey);
|
||||
//key = sjcl.bitArray.clamp(key, 128);
|
||||
return sjcl.decrypt(key, cyphertextJson);
|
||||
};
|
||||
|
||||
|
|
|
@ -177,7 +177,7 @@ describe('client API ', function() {
|
|||
statusCode: 200
|
||||
}, TestData.serverResponse.pendingTxs);
|
||||
client.request = request;
|
||||
|
||||
|
||||
client.getTxProposals({}, function(err, x) {
|
||||
should.not.exist(err);
|
||||
x.length.should.equal(1);
|
||||
|
@ -194,6 +194,7 @@ describe('client API ', function() {
|
|||
|
||||
describe('#sendTxProposal ', function() {
|
||||
it('should send tx proposal with encrypted message', function(done) {
|
||||
client.storage.fs.readFile = sinon.stub().yields(null, JSON.stringify(TestData.storage.complete11));
|
||||
var response = {};
|
||||
var request = sinon.mock().yields(null, {
|
||||
statusCode: 200
|
||||
|
@ -210,7 +211,7 @@ describe('client API ', function() {
|
|||
callArgs.toAddress.should.equal(args.toAddress);
|
||||
callArgs.amount.should.equal(20000);
|
||||
callArgs.message.should.not.equal(args.message);
|
||||
var decryptedMsg = WalletUtils.decryptMessage(callArgs.message, '42798f82c4ed9ace4d66335165071edf180e70bc0fc08dacb3e35185a2141d5b');
|
||||
var decryptedMsg = WalletUtils.decryptMessage(callArgs.message, TestData.storage.complete11.sharedEncryptingKey);
|
||||
decryptedMsg.should.equal(args.message);
|
||||
done();
|
||||
});
|
||||
|
|
|
@ -28,17 +28,19 @@ var storage = {
|
|||
"publicKeyRing": ["xpub661MyMwAqRbcGzNFbVQLh6CV6ukHuhBn4Bf4CGrQ6pFfNNdJ3pxrEVDtFHGsTzyz6Py23FhP8GWAqew3PsvnstEs2iayH1PK5Mx1bSVSEAG", "xpub661MyMwAqRbcGH2FXudWPDdrRobZ9XWTGaz18AnN1gkG8QW9ZUcn63RcK5qJJ5DXYXeAWBNqprdvvg8VHA5twmBHCUc6gWygXkwmU1Dohwh"],
|
||||
"copayerId": "020b41cfea5fae42050580474a195a8385b093f291af4079759851d8819383a680",
|
||||
"signingPrivKey": "KyhU3befBaePqHuPQNNyY1XFUgnArR3GUKZpZwV5vS7u1pcR3uzB",
|
||||
"sharedEncryptingKey": "ezDRS2NRchMJLf1IWtjL5A==",
|
||||
"network": "livenet"
|
||||
},
|
||||
complete11: {
|
||||
"copayerId": "02da4d1bd797b41a5565fe54f22583051bd3c29dbbc86eedadb6af6e9200af1048",
|
||||
"xPrivKey": "tprv8ZgxMBicQKsPeCyWCzmvnAkJUBEKpqggFmEmaR6CeyHeJj8oB8uFRWZonK7qLD1ih35tiRr1xnXg9a2rGLiYGQWVgvjhubzuUvVyanPXNuU",
|
||||
"publicKeyRing": ["tpubD6NzVbkrYhZ4Xg1J6eSXBaQR3CkFzAsaq4qYrw8W5F639DPZoXiqc1BfxSR2J1muzEE2qq7rZEDUgwyuwv1nYQgA9uorLghrT76FE5CjAuz"],
|
||||
"copayerId": "036ed70f51adf14e3e55aba727d28adec1851aff6865552aa9ec9b9dbafecd4a87",
|
||||
"xPrivKey": "tprv8ZgxMBicQKsPdjYWSKKh8SuMZAQ6K3J6v5H3A8ZVyyvXk4h1xft3qeRTmCZbxQB77n3ndfF6G4AevqgpiAVuCmZqYURH3wzSQviTvP1nkYN",
|
||||
"publicKeyRing": ["tpubD6NzVbkrYhZ4XCaJKxzHXrZU8Bv2UNV1VNspSeboQFivaYwnb4he293KwLPxnNNSBEj3RAE5EEaHqPWatzexGd613hGMLLQz5BEgjtpgWnZ"],
|
||||
"network": "testnet",
|
||||
"m": 1,
|
||||
"n": 1,
|
||||
"signingPrivKey": "Kzs8tquNTCsxwbEB9RiSNmcti4QXaW1i9UyLBV329VM5zU7o5nGB",
|
||||
"walletPrivKey": "L259i9W123MrrEjBUTzPVvo3ZMoJV26WB7Abr9LcVsiuWpj6sEL1"
|
||||
"signingPrivKey": "KxyNf4A1Td61GMrnC6LNQYsfE9zKvgsFmmgkPYrPoJHva4j9YSL1",
|
||||
"walletPrivKey": "L4JHs2ZggZkEuRLffH2WVe337nwZWMxytxViLLGyAfGREk6bUCXo",
|
||||
"sharedEncryptingKey": "ezDRS2NRchMJLf1IWtjL5A=="
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -141,7 +143,7 @@ var serverResponse = {
|
|||
creatorId: '02da4d1bd797b41a5565fe54f22583051bd3c29dbbc86eedadb6af6e9200af1048',
|
||||
toAddress: 'n2TBMPzPECGUfcT2EByiTJ12TPZkhN2mN5',
|
||||
amount: 10000,
|
||||
message: '{"iv":"Ij6LjNp6Cjlrpx1MklQk9A==","v":1,"iter":1,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","ct":"uyxcL8bBgRS0W2KA"}',
|
||||
message: '{"iv":"vDH4J15lBiokSP+iUS4ofA==","v":1,"iter":1,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","ct":"X/vPh+vh/Qv8IRSx"}',
|
||||
changeAddress: '2Mu4nmHhBWFk766M4yXJi2oyi59HZLKHWqn',
|
||||
inputs: [{
|
||||
address: '2MvBhgsQX6EusXvNGdcjM5dschDkaos1uuk',
|
||||
|
|
|
@ -68,7 +68,7 @@ describe('WalletUtils', function() {
|
|||
|
||||
describe('#encryptMessage #decryptMessage round trip', function() {
|
||||
it('should encrypt and decrypt', function() {
|
||||
var pwd = '0dea92f1df6675085b5cdd965487bb862f84f2755bcb56fa45dbf5b387a6c4a0';
|
||||
var pwd = "ezDRS2NRchMJLf1IWtjL5A==";
|
||||
var ct = WalletUtils.encryptMessage('hello world', pwd);
|
||||
var msg = WalletUtils.decryptMessage(ct, pwd);
|
||||
msg.should.equal('hello world');
|
||||
|
|
Loading…
Reference in New Issue