Convert string to SHA256 hash presented as string

Dear forum members,

I'm struggling to convert a password to a SHA256 hash presented as string. I keep ending up with this error: 

Error: System Error
Details: Failed invoking <symbol>

The goal is to hash a password string and represent that as a string again. Example: The SHA256 hash for "password" should result in: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8". In the Javascript world the following function does the job (docs): 

var sha256Hash =  CryptoJS.SHA256("password").toString();
console.log("sha256Hash :: " + sha256Hash)

Using the tips mentioned in this article I got to the following code in MonkeyC, but that fails to work:

function encoding_utf8_getbytes(plain_text) {
    return StringUtil.convertEncodedString(plain_text, {
        :fromRepresentation => StringUtil.REPRESENTATION_STRING_PLAIN_TEXT,
        :toRepresentation => StringUtil.REPRESENTATION_BYTE_ARRAY,
        :encoding => StringUtil.CHAR_ENCODING_UTF8
    });
}

function new_sha256hash() {
    return new Cryptography.Hash({
        :algorithm => Cryptography.HASH_SHA256
    });
}

function computehash(hash, byte_array) {
    hash.update(byte_array);
    return hash.digest();
}

function convert_bytearray_tostring(byte_array) {
    return StringUtil.convertEncodedString(byte_array, {
        :fromRepresentation => StringUtil.REPRESENTATION_BYTE_ARRAY,
        :toRepresentation => StringUtil.REPRESENTATION_STRING_PLAIN_TEXT,
        :encoding => StringUtil.CHAR_ENCODING_UTF8
    });
}

function convert_bytearray_tostringbase64(byte_array) {
    return StringUtil.convertEncodedString(byte_array, {
        :fromRepresentation => StringUtil.REPRESENTATION_BYTE_ARRAY,
        :toRepresentation => StringUtil.REPRESENTATION_STRING_BASE64,
        :encoding => StringUtil.CHAR_ENCODING_UTF8
    });
}

// hash password to SHA256
var pwrd = "password";
var pwrd_byte_array = encoding_utf8_getbytes(pwrd);
var sha256hash = new_sha256hash();
var sha256hash_bytes = computehash(sha256hash,pwrd_byte_array);
var hashedpasswordbase64 = convert_bytearray_tostringbase64(sha256hash_bytes);
System.println("hashedpasswordbase64: " + hashedpasswordbase64);
var hashedpassword = convert_bytearray_tostring(sha256hash_bytes);
System.println("hashedpassword: " + hashedpassword);

As an aditional example I've added the conversion of the same "sha256hash_bytes" variable to a base64 string. That is working fine, but converting it to a character encoding REPRESENTATION_STRING_PLAIN_TEXT fails with the error above. 

 

  • I tried your code and the System Error happens in the call to convert_bytearray_tostringbase64.

    :toRepresentation => StringUtil.REPRESENTATION_STRING_PLAIN_TEXT won't do what you want anyway. It will try to convert the sequence of bytes as if it represents a string of UTF-8 characters (e.g. 0x5e => "^"), instead of converting each byte to its corresponding hex representation (e.g. 0x5e => "5e").

    I made the following change and it now works as expected:

    function convert_bytearray_tostring(byte_array) {
      return StringUtil.convertEncodedString(byte_array, {
        :fromRepresentation => StringUtil.REPRESENTATION_BYTE_ARRAY,
        :toRepresentation => StringUtil.REPRESENTATION_STRING_HEX,
        :encoding => StringUtil.CHAR_ENCODING_UTF8
      });
    }

    Output:

    hashedpasswordbase64: XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=
    hashedpassword: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

    The original code crashed because the sequence of bytes in sha256hash_bytes isn't a valid UTF-8 string.

    e.g. Paste your data into https://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder and set Input Type to "hexadecimal":

    5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

    You'll see a ton of errors (which is to be expected).

    Decoder output:

    Byte number 1 is decimal 94, hex 0x5E, octal \136, binary 01011110
    
    U+005E	CIRCUMFLEX ACCENT
    	* this is a spacing character
    	x (modifier letter up arrowhead - 02C4)
    	x (modifier letter circumflex accent - 02C6)
    	x (combining circumflex accent - 0302)
    	x (caret - 2038)
    	x (up arrowhead - 2303)
    
    
    Byte number 2 is decimal 136, hex 0x88, octal \210, binary 10001000
    Unexpected continuation byte.
    ...
  • Thanks allot! This is working great! I think I misinterpreted the string representation somehow and somehow missed the STRING_HEX option.