Ejemplo n.º 1
0
    public static object readMessage(WebMessage 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 authentication request along with the correct answer (to avoid answer to be to different from normal message)

        if (message == null)
        {
            return(null);
        }
        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(null);
        }
        string message_id = message_id_bytes.getString();

        if (message_ids.Contains(message_id))
        {
            return(null);
        }
        //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(null);
        }

        //OK message verified and decrypted!
        IFormatter formatter = new BinaryFormatter();

        ms = new MemoryStream(received_message);
        object message_object = formatter.Deserialize(ms);

        ms.Dispose();

        return(message_object);
    }