Both timestamps are separate from the file's contents. They are kept along with other metadata in the inode (most Unix filesystems) or the Windows equivalent – the file's entry in the "master file table". In general, this is very specific to the filesystem being used – FAT and ext4 and btrfs and NTFS do it very differently.
The modification time on Windows is updated when closing the file, if at least one byte has been modified. Whether the new data is the same or different does not matter, as long as WriteFile() or a related function has been called; the new contents can even be an exact match.
The access time is updated when the file is closed after having been opened for reading or writing – even if it hasn't been modified in any way. (This excludes metadata reads, since the metadata is outside the file. On Windows, backup programs can also request the atime to remain unmodified.) Usually there are additional restrictions on when this time is updated: for example, only if old atime was before the modification time (Linux relatime), or only if old atime was more than a hour before now (older Windows), or not updated at all (newer Windows).