The text does not give us enough details to know exactly why, but I think there are a few things we can conclude from the passage:
- Part of the reason some readers take issue with this passage is that they think Ham is getting off without punishment for his offense. The punishment that fell to Canaan, however, would have felt like a punishment to Ham as well. His line was not blessed and one of his sons was cursed.
- It is not unreasonable to conclude that Noah knew that Canaan had the same attitude as Ham. If this is the case, the punishment should not be viewed as arbitrarily vindicative, but a just focusing of punishment on the guilty parties while excluding Ham’s other children (see Genesis 10:6). By punishing Canaan, Noah may have been sparing Ham’s other sons. It is also possible that Noah had some prophetic revelation by which he knew of the immorality that would come from Canaan.
At the end of the day, we are not given the details of why Noah chooses to curse Canaan rather than Ham, so we don’t know. I think point two above is plausible, but there certainly could be another explanation as well.