public byte[] DecryptAES256CBC4Msg(byte[] data)
        {
            //blocksize = OpenSSL.get_cipher(ciphername).get_blocksize()
            const int blocksize = 16;

            //iv = data[:blocksize]
            //i = blocksize
            int pos = 0;
            var iv = data.ReadBytes(ref pos, blocksize);

            //curve, pubkey_x, pubkey_y, i2 = ECC._decode_pubkey(data[i:])
            //i += i2
            UInt16 curve;
            byte[] pubkeyX;
            byte[] pubkeyY;
            ECC._decode_pubkey(data, out curve, out pubkeyX, out pubkeyY, ref pos);

            //ciphertext = data[i:len(data)-32]
            //i += len(ciphertext)
            var ciphertext = data.ReadBytes(ref pos, data.Length - pos - 32);

            //mac = data[i:]
            var mac = data.ReadBytes(ref pos, 32);

            //key = sha512(self.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest()
            byte[] key;
            using (var sha512 = new SHA512Managed())
                key = sha512.ComputeHash(new ECC(null, null, null, null, Wif2PrivateKey(PrivEncryptionKeyWif), ECC.Secp256K1).raw_get_ecdh_key(pubkeyX, pubkeyY));

            //key_e, key_m = key[:32], key[32:]
            byte[] key_e = new byte[32];
            byte[] key_m = new byte[32];
            Buffer.BlockCopy(key, 0, key_e, 0, 32);
            Buffer.BlockCopy(key, 32, key_m, 0, 32);

            //if hmac_sha256(key_m, ciphertext) != mac:
            //	raise RuntimeError("Fail to verify data")
            if (!new HMACSHA256(key_m).ComputeHash(ciphertext).SequenceEqual(mac))
                throw new Exception("Fail to verify data");

            var ctx = new Cipher(key_e, iv, false);
            return ctx.Ciphering(ciphertext);
        }
示例#2
0
        internal static byte[] Encrypt(byte[] data, byte[] pubkey)
        {
            // pyelliptic.ECC(curve='secp256k1').encrypt(msg,hexToPubkey(hexPubkey))
            // curve, pubkey_x, pubkey_y, i = ECC._decode_pubkey(pubkey)
            UInt16 curve = ECC.Secp256K1;
            string ciphername = "aes-256-cbc";
            var ephem = new ECC(null, null, null, null, null, curve);

            byte[] pubkey_x = new byte[32];
            byte[] pubkey_y = new byte[32];
            Buffer.BlockCopy(pubkey, 1, pubkey_x, 0, 32);
            Buffer.BlockCopy(pubkey, 33, pubkey_y, 0, 32);

            //key = sha512(ephem.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest()
            byte[] key;
            using (var sha512 = new SHA512Managed())
                key = sha512.ComputeHash(ephem.raw_get_ecdh_key(pubkey_x, pubkey_y));

            byte[] key_e = new byte[32];
            byte[] key_m = new byte[32];
            Buffer.BlockCopy(key, 0, key_e, 0, 32);
            Buffer.BlockCopy(key, 32, key_m, 0, 32);

            byte[] pubkey4Write = ephem.get_pubkey();
            byte[] iv = new byte[get_blocksize("aes-256-cbc")];
            using (var rnd = new RNGCryptoServiceProvider())
                rnd.GetBytes(iv);

            var ctx = new Cipher(key_e, iv, true, ciphername);
            var ciphertext = ctx.Ciphering(data);
            var mac = new HMACSHA256(key_m).ComputeHash(ciphertext);

            byte[] result = new byte[iv.Length + pubkey4Write.Length + ciphertext.Length + mac.Length];

            Buffer.BlockCopy(iv,           0, result, 0,                                                   iv.Length);
            Buffer.BlockCopy(pubkey4Write, 0, result, iv.Length,                                           pubkey4Write.Length);
            Buffer.BlockCopy(ciphertext,   0, result, iv.Length + pubkey4Write.Length,                     ciphertext.Length);
            Buffer.BlockCopy(mac,          0, result, iv.Length + pubkey4Write.Length + ciphertext.Length, mac.Length);

            //Debug.WriteLine("iv=" + iv.ToHex());
            //Debug.WriteLine("pubkey4Write=" + pubkey4Write.ToHex());

            return result;
        }