public static AuthKey Deserialize(Bytes key) => key.ToArrayUnsafe().Apply(Helpers.Sha1).Apply(BtHelpers.Deserialize(br => { var auxHash = br.ReadUInt64(); br.ReadBytes(4); var keyId = br.ReadUInt64(); return(new AuthKey(key, keyId, auxHash)); }));
public async Task Send(byte[] msg) { var session = _session.Get(); var plainText = BtHelpers.UsingMemBinWriter(bw => { bw.Write(session.Salt); bw.Write(session.Id); bw.Write(msg); var bs = bw.BaseStream; var requiredPadding = (16 - (int)bs.Position % 16).Apply(x => x == 16 ? 0 : x); var randomPadding = (Rnd.NextInt32() & 15) * 16; var padding = 16 + requiredPadding + randomPadding; bw.Write(Rnd.NextBytes(padding)); }); var authKey = session.AuthKey.Key.ToArrayUnsafe(); var msgKey = CalcMsgKey(authKey, plainText, true); var aesKey = CalcAesKey(authKey, msgKey, true); var cipherText = Aes.EncryptAES(aesKey, plainText); await BtHelpers.UsingMemBinWriter(bw => { bw.Write(session.AuthKey.KeyId); bw.Write(msgKey); bw.Write(cipherText); }).Apply(_transport.Send); }
public async Task <BinaryReader> Receive() { var plainText = await ReceivePlainText(); return(plainText.Apply(BtHelpers.Deserialize(br => { var remoteSalt = br.ReadUInt64(); var remoteSessionId = br.ReadUInt64(); return br; }))); }
async Task <byte[]> ReceivePlainText() { var body = await _transport.Receive(); return(body.Apply(BtHelpers.Deserialize(br => { var authKeyId = br.ReadUInt64(); // TODO: check auth key id var msgKey = br.ReadBytes(16); // TODO: check msg_key correctness var keyData = CalcAesKey(_session.Get().AuthKey.Key.ToArrayUnsafe(), msgKey, false); var bs = br.BaseStream; var cipherTextLen = (int)(bs.Length - bs.Position); var cipherText = br.ReadBytes(cipherTextLen); var plainText = Aes.DecryptAES(keyData, cipherText); return plainText; }))); }