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.