public byte[] ToBytes() { using (var stream = new MemoryStream()) using (var writer = new TBinaryWriter(stream)) { writer.Write(Id); writer.Write(Sequence); writer.Write(Salt); writer.Write(LastMessageId); writer.Write(TimeOffset); writer.Write(ServerAddress); writer.Write(Port); if (User != null) { writer.Write(true); User.Write(writer); } else { writer.Write(false); } writer.Write(AuthKey.Data); return(stream.ToArray()); } }
public byte[] ToBytes(byte[] nonce, byte[] serverNonce, List <byte[]> fingerprints, BigInteger pq) { new Random().NextBytes(newNonce); var pqPair = Factorizator.Factorize(pq); byte[] reqDhParamsBytes; using (MemoryStream pqInnerData = new MemoryStream(255)) { using (TBinaryWriter pqInnerDataWriter = new TBinaryWriter(pqInnerData)) { pqInnerDataWriter.Write(0x83c95aec); // pq_inner_data pqInnerDataWriter.Write(pq.ToByteArrayUnsigned()); pqInnerDataWriter.Write(pqPair.Min.ToByteArrayUnsigned()); pqInnerDataWriter.Write(pqPair.Max.ToByteArrayUnsigned()); pqInnerDataWriter.WriteBase(nonce); pqInnerDataWriter.WriteBase(serverNonce); pqInnerDataWriter.WriteBase(newNonce); byte[] ciphertext = null; byte[] targetFingerprint = null; foreach (byte[] fingerprint in fingerprints) { ciphertext = RSA.Encrypt(BitConverter.ToString(fingerprint).Replace("-", string.Empty), pqInnerData.GetBuffer(), 0, (int)pqInnerData.Position); if (ciphertext != null) { targetFingerprint = fingerprint; break; } } if (ciphertext == null) { throw new InvalidOperationException( String.Format("not found valid key for fingerprints: {0}", String.Join(", ", fingerprints))); } using (MemoryStream reqDHParams = new MemoryStream(1024)) { using (TBinaryWriter reqDHParamsWriter = new TBinaryWriter(reqDHParams)) { reqDHParamsWriter.Write(0xd712e4be); // req_dh_params reqDHParamsWriter.WriteBase(nonce); reqDHParamsWriter.WriteBase(serverNonce); reqDHParamsWriter.Write(pqPair.Min.ToByteArrayUnsigned()); reqDHParamsWriter.Write(pqPair.Max.ToByteArrayUnsigned()); reqDHParamsWriter.WriteBase(targetFingerprint); reqDHParamsWriter.Write(ciphertext); reqDhParamsBytes = reqDHParams.ToArray(); } } } return(reqDhParamsBytes); } }
public byte[] ToBytes(byte[] nonce, byte[] serverNonce, byte[] newNonce, byte[] encryptedAnswer) { this.newNonce = newNonce; AESKeyData key = AES.GenerateKeyDataFromNonces(serverNonce, newNonce); byte[] plaintextAnswer = AES.DecryptAES(key, encryptedAnswer); // logger.debug("plaintext answer: {0}", BitConverter.ToString(plaintextAnswer)); int g; BigInteger dhPrime; BigInteger ga; using (MemoryStream dhInnerData = new MemoryStream(plaintextAnswer)) { using (TBinaryReader dhInnerDataReader = new TBinaryReader(dhInnerData)) { byte[] hashsum = dhInnerDataReader.ReadBytes(20); uint code = dhInnerDataReader.ReadUInt32(); if (code != 0xb5890dba) { throw new InvalidOperationException($"invalid dh_inner_data code: {code}"); } // logger.debug("valid code"); byte[] nonceFromServer1 = dhInnerDataReader.ReadBytes(16); if (!nonceFromServer1.SequenceEqual(nonce)) { throw new InvalidOperationException("invalid nonce in encrypted answer"); } // logger.debug("valid nonce"); byte[] serverNonceFromServer1 = dhInnerDataReader.ReadBytes(16); if (!serverNonceFromServer1.SequenceEqual(serverNonce)) { throw new InvalidOperationException("invalid server nonce in encrypted answer"); } // logger.debug("valid server nonce"); g = dhInnerDataReader.ReadInt32(); dhPrime = new BigInteger(1, dhInnerDataReader.ReadBytes()); ga = new BigInteger(1, dhInnerDataReader.ReadBytes()); int serverTime = dhInnerDataReader.ReadInt32(); timeOffset = serverTime - (int)(Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds) / 1000); // logger.debug("g: {0}, dhprime: {1}, ga: {2}", g, dhPrime, ga); } } BigInteger b = new BigInteger(2048, new Random()); BigInteger gb = BigInteger.ValueOf(g).ModPow(b, dhPrime); _gab = ga.ModPow(b, dhPrime); // logger.debug("gab: {0}", gab); // prepare client dh inner data byte[] clientDHInnerDataBytes; using (MemoryStream clientDhInnerData = new MemoryStream()) { using (TBinaryWriter clientDhInnerDataWriter = new TBinaryWriter(clientDhInnerData)) { clientDhInnerDataWriter.Write(0x6643b654); // client_dh_inner_data clientDhInnerDataWriter.WriteBase(nonce); clientDhInnerDataWriter.WriteBase(serverNonce); clientDhInnerDataWriter.Write((long)0); // TODO: retry_id clientDhInnerDataWriter.Write(gb.ToByteArrayUnsigned()); using (MemoryStream clientDhInnerDataWithHash = new MemoryStream()) { using (BinaryWriter clientDhInnerDataWithHashWriter = new BinaryWriter(clientDhInnerDataWithHash)) { using (SHA1 sha1 = new SHA1Managed()) { clientDhInnerDataWithHashWriter.Write(sha1.ComputeHash(clientDhInnerData.GetBuffer(), 0, (int)clientDhInnerData.Position)); clientDhInnerDataWithHashWriter.Write(clientDhInnerData.GetBuffer(), 0, (int)clientDhInnerData.Position); clientDHInnerDataBytes = clientDhInnerDataWithHash.ToArray(); } } } } } // logger.debug("client dh inner data papared len {0}: {1}", clientDHInnerDataBytes.Length, BitConverter.ToString(clientDHInnerDataBytes).Replace("-", "")); // encryption byte[] clientDhInnerDataEncryptedBytes = AES.EncryptAES(key, clientDHInnerDataBytes); // logger.debug("inner data encrypted {0}: {1}", clientDhInnerDataEncryptedBytes.Length, BitConverter.ToString(clientDhInnerDataEncryptedBytes).Replace("-", "")); // prepare set_client_dh_params byte[] setclientDhParamsBytes; using (MemoryStream setClientDhParams = new MemoryStream()) { using (TBinaryWriter setClientDhParamsWriter = new TBinaryWriter(setClientDhParams)) { setClientDhParamsWriter.Write(0xf5045f1f); setClientDhParamsWriter.WriteBase(nonce); setClientDhParamsWriter.WriteBase(serverNonce); setClientDhParamsWriter.Write(clientDhInnerDataEncryptedBytes); setclientDhParamsBytes = setClientDhParams.ToArray(); } } // logger.debug("set client dh params prepared: {0}", BitConverter.ToString(setclientDhParamsBytes)); return(setclientDhParamsBytes); }