Ejemplo n.º 1
0
        public byte[] EncodeEncryptedMessage(IMessage message, byte[] authKey, ulong salt, ulong sessionId, Sender sender)
        {
            Argument.IsNotNull(() => authKey);
            Argument.IsNotNull(() => message);

            ulong authKeyId = ComputeAuthKeyId(authKey);

            byte[] serBody = _tlRig.Serialize(message.Body, TLSerializationMode.Boxed);

            int serBodyLength   = serBody.Length;
            int innerDataLength = EncryptedInnerHeaderLength + serBodyLength;
            int mod             = innerDataLength % Alignment;
            int paddingLength   = mod > 0 ? Alignment - mod : 0;

            _randomGenerator.FillWithRandom(_alignmentBuffer);
            int innerDataWithPaddingLength = innerDataLength + paddingLength;

            int length = EncryptedOuterHeaderLength + innerDataWithPaddingLength;

            // Writing inner data.
            var innerDataWithPadding = new byte[innerDataWithPaddingLength];

            using (var streamer = new TLStreamer(innerDataWithPadding))
            {
                streamer.WriteUInt64(salt);
                streamer.WriteUInt64(sessionId);
                streamer.WriteUInt64(message.MsgId);
                streamer.WriteUInt32(message.Seqno);
                streamer.WriteInt32(serBodyLength);
                streamer.Write(serBody);
                streamer.Write(_alignmentBuffer, 0, paddingLength);
            }

            Int128 msgKey = ComputeMsgKey(new ArraySegment <byte>(innerDataWithPadding, 0, innerDataLength));

            // Encrypting.
            byte[] aesKey, aesIV;
            ComputeAesKeyAndIV(authKey, msgKey, out aesKey, out aesIV, sender);
            byte[] encryptedData = _encryptionServices.Aes256IgeEncrypt(innerDataWithPadding, aesKey, aesIV);

            Debug.Assert(encryptedData.Length == innerDataWithPaddingLength, "Wrong encrypted data length.");

            var messageBytes = new byte[length];

            using (var streamer = new TLStreamer(messageBytes))
            {
                // Writing header.
                streamer.WriteUInt64(authKeyId);
                streamer.WriteInt128(msgKey);

                // Writing encrypted data.
                streamer.Write(encryptedData, 0, innerDataWithPaddingLength);
            }
            return(messageBytes);
        }