I am using the Node.js crypto library to encrypt larger files using AES-256-ctr. One problem that I am having right now is verifying if the decryption was successful or not. Currently, if I use the wrong password I have no way of knowing the decryption failed until I look at the text and realize it's unreadable, but this makes it difficult to programmatically check and ask for a password retry.
What I have gathered so far from my research (please correct me if I am wrong):
- I can use HMAC to verify the integrity of the decrypted message
- I should always run the HMAC function after encryption, as hashing anything before encrypting the data and not encrypting the hash itself defeats the purpose of encryption
- Don't use the same secret key for encryption and MAC
My questions: Would it be wrong, and if so why, to just prepend/append a string to the message I want to encrypt then check if it's there when I am decrypting. This seems like a simple check to make, but I can't wrap my head around why it shouldn't be done.
Ex.
Encryption:
- 'hello world'
- (prepend said string) 'ENCRYPTED:hello world'
- (encrypt message)
- 'iv:abc123'
Decryption:
- 'iv:abc123' -> (decrypt)
- decStr = 'ENCRYPTED:hello world' or 'ab/12c879312sc/!/'
- if (decStr.split(':')[0] === 'ENCRYPTED') { correct decryption }
What should I use for the 'secret' in the createHmac() function? I don't want to require the user to hold two passwords. One for encryption and one for verification. Can I use the derived key i get from encrypting the password using scrypt?
I can't tell if this is a stupid question or if I'm just not searching the right thing, but some of the similar questions to this just say to use aes-gcm to avoid having to worry about this. I'm mostly just curious about how to do it.