fix message encryption/decryption

This commit is contained in:
Ivan Socolsky 2015-02-18 18:14:24 -03:00
parent 9b6c5716b4
commit 33800aff7e
5 changed files with 32 additions and 25 deletions

View File

@ -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) {
@ -150,8 +154,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 = {
@ -161,8 +166,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;
};
@ -280,8 +286,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);
});
@ -312,7 +318,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);
@ -417,7 +423,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);
});

View File

@ -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);
};

View File

@ -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();
});

View File

@ -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',

View File

@ -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');