Asymmetric decryption in contract

I am fully aware that everything on a blockchain is publicly visible, visibility is not my requirement.
I am looking for the feature that asymmetric keys provide where Alice can decrypt a message with Bob's public key so Alice can know the message came from Bob unmodified.

My goal is to be able to have my server send a message to a user, who can then submit the message to a smart contract but not allow the user to modify the message without it being obvious.

If someone has a better idea of how to implement this solution please let me know!

Do you mean sign and verify the signature ?

You can use a web3 lib to sign a message (something like this on the frontend) and verify the signer address with the OpenZeppelin crypto utility functions

In the OpenZeppelin utility example, it shows that the original signer wallet can be determined (which I do need), but I can't figure out how I could then verify that the message as been unmodified when it reaches the contract.

Can I recreate the signature hash somehow (with the plaintext message?) in the contract to then compare it with the original hash?

It's necessary. The crypto functions only allow to recover the signer address, checking the data or data hash needs to be done by the developer.
Maybe you could add a function to generate the data to be signed? your frontend can all it with the appropriate args, then your contract can call it again with the same args and generate the data again instead of receiving it from the front end.

Yes this is exactly what you have to do.

Thanks for the help, I will figure out how to implement this and confirm!