I dont want to use the built in Encode function.
How would i encrypt say a string of data by hashing with SHA-256 algorithm?
Firstly, as Jens said... Hashing <> Encrypting!
If you do want to hash & you’re doing it to hide sensitive data (e.g. passwords) then you should probably be using SHA-512 & a per-data-item salt:
message-digest("SHA-512", cMyPlainText, cMySalt)
The most common reason is to hash passwords so that you can store them in your DB & make the data resistant to attack. When doing this, a decent thing to do is to generate a user-specific random salt value when you create the user record & store that salt in the DB.
e.g.
DEFINE TEMP-TABLE ttUser FIELD id AS CHAR FIELD salt AS RAW FIELD password AS RAW. FUNCTION checkUserPassword RETURNS LOGICAL (ipcId AS CHARACTER , ipcPassword AS CHARACTER): FIND ttUser WHERE ttUser.id = ipcId. RETURN (ttUser.password = MESSAGE-DIGEST("SHA-512", ipcPassword, ttUser.salt)). END. /* Create user john.doe with password = "correct-password" */ RUN createUser("john.doe", "correct-password"). MESSAGE checkUserPassword("john.doe", "correct-password") SKIP checkUserPassword("john.doe", "a-different-password") VIEW-AS ALERT-BOX. /* Change john doe's password */ RUN updateUserPassword ("john.doe", "a-different-password"). MESSAGE checkUserPassword("john.doe", "correct-password") SKIP checkUserPassword("john.doe", "a-different-password") VIEW-AS ALERT-BOX. /*************************************************/ PROCEDURE createUser: DEFINE INPUT PARAMETER ipcId AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER ipcPassword AS CHARACTER NO-UNDO. CREATE ttUser. ttUser.id = ipcId. ttUser.salt = GENERATE-PBE-SALT. ttUser.password = MESSAGE-DIGEST("SHA-512", ipcPassword, ttUser.salt). END. PROCEDURE updateUserPassword: DEFINE INPUT PARAMETER ipcId AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER ipcPassword AS CHARACTER NO-UNDO. FIND ttUser WHERE ttUser.id = ipcId. ttUser.password = MESSAGE-DIGEST("SHA-512", ipcPassword, ttUser.salt). END.
SHA-256 isn't really encryption, it's a hashing algorithm. Nevertheless, here's an example:
DEFINE VARIABLE mHash AS MEMPTR NO-UNDO. DEFINE VARIABLE cLongChar AS LONGCHAR NO-UNDO. SET-SIZE(mHash) = 32. PUT-BYTES(mHash, 1) = MESSAGE-DIGEST("SHA-256", "A string"). COPY-LOB mHash TO cLongChar. SET-SIZE(mHash) = 0. DISP cLongChar VIEW-AS EDITOR LARGE INNER-CHARS 60 INNER-LINES 2.
Unsure if MESSAGE-DIGEST was introduced in 10.2 OR 11.something.
Firstly, as Jens said... Hashing <> Encrypting!
If you do want to hash & you’re doing it to hide sensitive data (e.g. passwords) then you should probably be using SHA-512 & a per-data-item salt:
message-digest("SHA-512", cMyPlainText, cMySalt)
The most common reason is to hash passwords so that you can store them in your DB & make the data resistant to attack. When doing this, a decent thing to do is to generate a user-specific random salt value when you create the user record & store that salt in the DB.
e.g.
DEFINE TEMP-TABLE ttUser FIELD id AS CHAR FIELD salt AS RAW FIELD password AS RAW. FUNCTION checkUserPassword RETURNS LOGICAL (ipcId AS CHARACTER , ipcPassword AS CHARACTER): FIND ttUser WHERE ttUser.id = ipcId. RETURN (ttUser.password = MESSAGE-DIGEST("SHA-512", ipcPassword, ttUser.salt)). END. /* Create user john.doe with password = "correct-password" */ RUN createUser("john.doe", "correct-password"). MESSAGE checkUserPassword("john.doe", "correct-password") SKIP checkUserPassword("john.doe", "a-different-password") VIEW-AS ALERT-BOX. /* Change john doe's password */ RUN updateUserPassword ("john.doe", "a-different-password"). MESSAGE checkUserPassword("john.doe", "correct-password") SKIP checkUserPassword("john.doe", "a-different-password") VIEW-AS ALERT-BOX. /*************************************************/ PROCEDURE createUser: DEFINE INPUT PARAMETER ipcId AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER ipcPassword AS CHARACTER NO-UNDO. CREATE ttUser. ttUser.id = ipcId. ttUser.salt = GENERATE-PBE-SALT. ttUser.password = MESSAGE-DIGEST("SHA-512", ipcPassword, ttUser.salt). END. PROCEDURE updateUserPassword: DEFINE INPUT PARAMETER ipcId AS CHARACTER NO-UNDO. DEFINE INPUT PARAMETER ipcPassword AS CHARACTER NO-UNDO. FIND ttUser WHERE ttUser.id = ipcId. ttUser.password = MESSAGE-DIGEST("SHA-512", ipcPassword, ttUser.salt). END.
Note:
The value returned from the MESSAGE-DIGEST is an arbitraty stream of bytes. If you need to store that in a CHARACTER or LONGCHAR, base64-encode it to avoid errors/corruption due to improper codepage interpretations/conversions
Thanks thats exactly the sort of thing I need.