sigp/ecies-parity

Error - Incorrect HMAC

Closed this issue · 3 comments

Hi - is there any equivalent implementation in javascript?

My requirement is to encrypt a message by using go language and decrypt this on node js/javascript side.
For the moment, I am using “go-ethereum/crypto/ecies/ecies.go” for encryption and a node package “ecies-parity” for decryption but getting error “Incorrect MAC”.

Encryption : (Go)

var privateKey ="54422e4b3278da00c4cc14b31cbbd1a8e047927735be2d1752ac134b7d9a2fef"
prk1, err := HexToECDSA(privateKey)
if err != nil {
	fmt.Println(err)
	os.Exit(1)
}
var pk2 *ecdsa.PublicKey
pk2 = prk1.Public().(*ecdsa.PublicKey)
ct, err := ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(pk2), []byte("hello"), nil, nil)
if err != nil {
	return shim.Error(fmt.Sprintf("Unable to parse certificate %s", err))
}
fmt.Println(ct)

Getting output as byte array:
[4 193 121 113 131 2 85 24 76 223 71 147 19 57 191 250 232 218 155 44 177 23 95 111 64 33 251 231 179 36 226 30 178 131 66 160 71 2 113 6 114 136 106 65 193 85 146 223 207 83 170 111 244 129 67 121 19 163 175 8 197 123 192 2 60 80 48 28 241 11 128 12 164 51 112 193 246 18 103 220 72 137 225 175 78 112 241 174 254 89 226 40 234 137 236 217 250 123 199 67 95 36 117 171 124 113 50 240 108 30 168 84 129 173 39 49 130 164]

For Decryption: (Node.js)
const ecies = require("ecies-parity");
var EC = require('elliptic').ec;
var goBytes="4 193 121 113 131 2 85 24 76 223 71 147 19 57 191 250 232 218 155 44 177 23 95 111 64 33 251 231 179 36 226 30 178 131 66 160 71 2 113 6 114 136 106 65 193 85 146 223 207 83 170 111 244 129 67 121 19 163 175 8 197 123 192 2 60 80 48 28 241 11 128 12 164 51 112 193 246 18 103 220 72 137 225 175 78 112 241 174 254 89 226 40 234 137 236 217 250 123 199 67 95 36 117 171 124 113 50 240 108 30 168 84 129 173 39 49 130 164";
var bytes =[];
var forLoop=goBytes.split(" ")
for (var i = 0; i < forLoop.length; ++i)
{
bytes.push(forLoop[i]);
}
var privateKeyA = Buffer.from("54422e4b3278da00c4cc14b31cbbd1a8e047927735be2d1752ac134b7d9a2fef","hex");
var ec = new EC('secp256k1');
var pk = ec.keyFromPrivate(privateKeyA, 'hex');
ecies.decrypt(pk.getPrivate().toBuffer(), Buffer.from(bytes)).then(function(plaintext) {
console.log("Message to part A:", plaintext.toString());
});

This library I made because Parity (an ethereum client) implemented a specific version of ECIES. This implementation mimics parity.

There are other implementations. Try the ecccrypto library https://github.com/bitchan/eccrypto

There isn't a formal standard for ECIES (that I currently know of). If you give me the source for what is performing your encryption, I could probably make a modified library. I daresay that one of the other ECIES modules will fit with the go encryption.

Thank you for your quick response.
I unsuccessfully tried eccrypto as well. However, Your library looks very close. I am using https://github.com/ethereum/go-ethereum/blob/master/crypto/ecies/ecies.go to encrypt message.

I have checked with library and following is correct:
let metaLength = 1 + 64 + 16 + 32;
assert(encrypted.length > metaLength, "Invalid Ciphertext. Data is too small")
assert(encrypted[0] >= 2 && encrypted[0] <= 4, "Not valid ciphertext.")
// deserialise
let ephemPublicKey = encrypted.slice(0,65);
let cipherTextLength = encrypted.length - metaLength;
let iv = encrypted.slice(65,65 + 16);
let cipherAndIv = encrypted.slice(65, 65+16+ cipherTextLength);
let ciphertext = cipherAndIv.slice(16);
let msgMac = encrypted.slice(65+16+ cipherTextLength);

When I change PARITY_DEFAULT_HMAC and check against hardcoded value it worked.
var PARITY_DEFAULT_HMAC = Buffer.from([]);

I think derive or kdf function seems different here:
let px = await derive(privateKey, ephemPublicKey);
let hash = await kdf(px,32);

This Issue has been solved now. I was missing shared MAC data in encryption.