Пример #1
0
        public virtual byte[] Decrypt(ECPrivateKey privateKey, byte[] data)
        {
            using (var stream = new MemoryStream(data))
            {
                //  read the IV
                byte[] iv = new byte[16];
                stream.Read(iv, 0, iv.Length);

                //  read the publickey
                var    pubkeysize = stream.ReadByte();
                byte[] pubkeyraw  = new byte[pubkeysize];
                stream.Read(pubkeyraw, 0, pubkeyraw.Length);
                var pubkey = new ECPublicKey(pubkeyraw);

                //  Do an EC point multiply with this.getPrivateKey() and ephemeral public key. This gives you a point M.
                var m = GetECPoint(pubkey).Multiply(new BigInteger(1, privateKey.Base64Array)).Normalize();

                //  Use the X component of point M and calculate the SHA512 hash H.
                byte[] h = RadixHash.Sha512Of(m.XCoord.GetEncoded()).ToByteArray();

                //  The first 32 bytes of H are called key_e and the last 32 bytes are called key_m.
                byte[] keyE = Arrays.CopyOfRange(h, 0, 32);
                byte[] keyM = Arrays.CopyOfRange(h, 32, 64);

                //  Read encrypted data
                var size = new byte[4];
                stream.Read(size, 0, size.Length);
                byte[] encrypted = new byte[BitConverter.ToInt32(size, 0)];
                stream.Read(encrypted, 0, encrypted.Length);

                //  Read MAC
                byte[] mac = new byte[32];
                stream.Read(mac, 0, mac.Length);

                //  Compare MAC with MAC'. If not equal, decryption will fail.
                byte[] pkMac = CalculateMAC(keyM, iv, pubkey, encrypted);
                if (pkMac.Equals(mac))
                {
                    throw new ApplicationException
                              ($"Decryption failed, mac mismatch , {Convert.ToBase64String(pkMac)} <> {Convert.ToBase64String(mac)}");
                }

                //  Decrypt the cipher text with AES-256-CBC, using IV as initialization vector, key_e as decryption key,
                //  and the cipher text as payload. The output is the padded input text.
                return(Crypt(false, encrypted, iv, keyE));
            }
        }
Пример #2
0
        public virtual byte[] Encrypt(ECPublicKey publicKey, byte[] data)
        {
            Random rand = new SecureRandom();

            byte[] iv = new byte[16];
            // 2. Generate 16 random bytes using a secure random number generator. Call them IV
            rand.NextBytes(iv);

            var randomKeyPair = GetRandomKeyPair();

            //  Do an EC point multiply with publicKey and random keypair. This gives you a point M.
            var m = GetECPoint(publicKey).Multiply(new BigInteger(1, randomKeyPair.PrivateKey.Base64Array)).Normalize();

            //  Use the X component of point M and calculate the SHA512 hash H.
            byte[] h = RadixHash.Sha512Of(m.AffineXCoord.GetEncoded()).ToByteArray();

            //  The first 32 bytes of H are called key_e and the last 32 bytes are called key_m.
            byte[] keyE      = Arrays.CopyOfRange(h, 0, 32);
            byte[] keyM      = Arrays.CopyOfRange(h, 32, 64);
            byte[] encrypted = Crypt(true, data, iv, keyE);

            //  Calculate a 32 byte MAC with HMACSHA256, using key_m as salt and
            //  IV + ephemeral.pub + cipher text as data. Call the output MAC.
            byte[] mac = CalculateMAC(keyM, iv, randomKeyPair.PublicKey, encrypted);

            //  Write out the encryption result IV +ephemeral.pub + encrypted + MAC
            using (var memstr = new MemoryStream())
            {
                memstr.Write(iv, 0, iv.Length);
                memstr.WriteByte((byte)randomKeyPair.PublicKey.Length());
                memstr.Write(randomKeyPair.PublicKey.Base64Array, 0, randomKeyPair.PublicKey.Length());
                memstr.Write(BitConverter.GetBytes(encrypted.Length), 0, 4);
                memstr.Write(encrypted, 0, encrypted.Length);
                memstr.Write(mac, 0, mac.Length);

                return(memstr.ToArray());
            }
        }