Exemplo n.º 1
0
        public static BodyType readMessage <BodyType>(EncryptedMessage message, RSACryptoServiceProvider sender_rsa)
        {
            //VUNERABILTY
            //IN CASE OF client restart the fake server can resend the message, the token is still valid
            //sol: on boot reset all client token
            //this solve also reply attack as the message would all change token, so I need only 1 session message id
            //if the message id buffer if full receiver shall send an authenticate request along with the correct answer (to avoid answer to be to different from normal message)

            if (message == null)
            {
                return(default(BodyType));
            }
            byte[] signature = message.Signature;

            RSACryptoServiceProvider my_rsa = message.getGlobalObject <IMyRsaProvider>().getMySra();

            //checking unique id
            byte[] message_id_bytes = my_rsa.Decrypt(message.MessageID, false);
            if (!sender_rsa.VerifyData(message_id_bytes, new SHA1CryptoServiceProvider(), message.MessageIDSignaure))
            {
                return(default(BodyType));
            }
            string message_id = message_id_bytes.getString();

            if (message_ids.Contains(message_id))
            {
                return(default(BodyType));
            }
            //replay attack!!!
            if (message_ids.Count > replay_store_size)
            {
                message_ids = new HashSet <string>();
            }
            message_ids.Add(message_id);

            byte[] Key = my_rsa.Decrypt(message.Key, false);
            byte[] IV  = my_rsa.Decrypt(message.IV, false);

            //Create a new instance of the RijndaelManaged class
            //and decrypt the stream.
            RijndaelManaged RMCrypto = new RijndaelManaged();


            //Create an instance of the CryptoStream class, pass it the NetworkStream, and decrypt
            //it with the Rijndael class using the key and IV.
            MemoryStream ms          = new MemoryStream(message.Message);
            CryptoStream CryptStream = new CryptoStream(ms, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read);


            MemoryStream output = new MemoryStream();

            byte[] buffer = new byte[1024];
            int    read   = CryptStream.Read(buffer, 0, buffer.Length);

            while (read > 0)
            {
                output.Write(buffer, 0, read);
                read = CryptStream.Read(buffer, 0, buffer.Length);
            }
            CryptStream.Flush();
            CryptStream.Dispose();
            ms.Dispose();

            byte[] received_message = output.ToArray();

            if (!sender_rsa.VerifyData(received_message, new SHA1CryptoServiceProvider(), signature))
            {
                return(default(BodyType));
            }

            //OK message certificated and decrypted!
            BodyType message_object = sender_rsa.getGlobalObject <IMysteryJsonConverter>().readJson <BodyType>(received_message.getString());


            return(message_object);
        }