When Sha256 and md5 are added together - hash

When Sha256 and md5 are added together include in page
<!--#include file="hash/sha256.asp"-->
<!---#include file="hash/md5.asp"--->
gives this error
Microsoft VBScript derleme hatasý hata '800a0411'
Ad yeniden tanýmlandý
/3wPay/include/hash/md5.asp, satır 3
Private Const BITS_TO_A_BYTE = 8
--------------^
but it works alone when md5 or sha256 is included.
How can I run both together

I don't know what that error says, but I'm assuming that BITS_TO_A_BYTE is already defined. I would clean up both of those files and created a 3rd file with all of your constants, and remove the constants from both of those files.
When you create your 3rd file, only define each constant once.
Then include it whenever you use either md5.asp or sha256.asp

As already mentioned, looks like you have 2 constants with the same name. A more efficient and compact alternative in my opinion would be to use the System.Security.Cryptography.X object, which supports MD5, SHA1, SHA256, SHA384 and SHA512.
The example code below also allows you to encode as Hex or Base64:
<%
Function Hash(ByVal Input, Alg, Encoding)
Dim hAlg, hEnc
Set hAlg = CreateObject("System.Security.Cryptography." & Get_Hash_Obj(Alg))
Set hEnc = CreateObject("System.Text.UTF8Encoding")
Hash = BinaryEncode(hAlg.ComputeHash_2(hEnc.GetBytes_4(Input)),Encoding)
Set hEnc = Nothing
Set hAlg = Nothing
End Function
Function Get_Hash_Obj(Alg)
' Get the cryptography class name for the specified hashing algorithm,
' return the class name for SHA1 if not found
Select Case uCase(Alg)
Case "MD5"
Get_Hash_Obj = "MD5CryptoServiceProvider"
Case "SHA1"
Get_Hash_Obj = "SHA1CryptoServiceProvider"
Case "SHA256"
Get_Hash_Obj = "SHA256Managed"
Case "SHA384"
Get_Hash_Obj = "SHA384Managed"
Case "SHA512"
Get_Hash_Obj = "SHA512Managed"
Case Else
Get_Hash_Obj = "SHA1CryptoServiceProvider"
End Select
End Function
Function BinaryEncode(Binary, Encoding)
Dim Enc
Encoding = lCase(Encoding)
Set Enc = CreateObject("MSXML2.DomDocument").CreateElement("encode")
If Encoding = "base64" OR Encoding = "b64" Then
' base64 string
Enc.DataType = "bin.base64"
Enc.NodeTypedValue = Binary
BinaryEncode = Enc.Text
Else
' Hexadecimal string
Enc.DataType = "bin.hex"
Enc.NodeTypedValue = Binary
BinaryEncode = Enc.Text
End If
Set Enc = Nothing
End Function
%>
Example:
Response.Write Hash("Hello World","SHA256","Hex")
Response.Write Hash("Hello World","SHA256","Base64") ' Or B64
Output:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
pZGm1Av0IEBKARczz7exkNYsZb8LzaMrV7J32a2fFG4=

Related

ColdFusion Hash

I'm trying to create a password digest with this formula to get the following variables and my code is just not matching. Not sure what I'm doing wrong, but I'll admit when I need help. Hopefully someone is out there who can help.
Formula from documentation: Base64(SHA1(NONCE + TIMESTAMP + SHA1(PASSWORD)))
Correct Password Digest Answer: +LzcaRc+ndGAcZIXmq/N7xGes+k=
ColdFusion Code:
<cfSet PW = "AMADEUS">
<cfSet TS = "2015-09-30T14:12:15Z">
<cfSet NONCE = "secretnonce10111">
<cfDump var="#ToBase64(Hash(NONCE & TS & Hash(PW,'SHA-1'),'SHA-1'))#">
My code outputs:
Njk0MEY3MDc0NUYyOEE1MDMwRURGRkNGNTVGOTcyMUI4OUMxM0U0Qg==
I'm clearly doing something wrong, but for the life of me cannot figure out what. Anyone? Bueller?
The fun thing about hashing is that even if you start with the right string(s), the result can still be completely wrong, if those strings are combined/encoded/decoded incorrectly.
The biggest gotcha is that most of these functions actually work with the binary representation of the input strings. So how those strings are decoded makes a big difference. Notice the same string produces totally different binary when decoded as UTF-8 versus Hex? That means the results of Hash, ToBase64, etcetera will be totally different as well.
// Result: UTF-8: 65-65-68-69
writeOutput("<br>UTF-8: "& arrayToList(charsetDecode("AADE", "UTF-8"), "-"));
// Result: HEX: -86--34
writeOutput("<br>HEX: "& arrayToList(binaryDecode("AADE", "HEX"), "-"));
Possible Solution:
The problem with the current code is that ToBase64 assumes the input string is encoded as UTF-8. Whereas Hash() actually returns a hexadecimal string. So ToBase64() decodes it incorrectly. Instead, use binaryDecode and binaryEncode to convert the hash from hex to base64:
resultAsHex = Hash( NONCE & TS & Hash(PW,"SHA-1"), "SHA-1");
resultAsBase64 = binaryEncode(binaryDecode(resultAsHex, "HEX"), "base64");
writeDump(resultAsBase64);
More Robust Solution:
Having said that, be very careful with string concatenation and hashing. As it does not always yield the expected results. Without knowing more about this specific API, I cannot be completely certain what it expects. However, it is usually safer to only work with the binary values. Unfortunately, CF's ArrayAppend() function lacks support for binary arrays, but you can easily use Apache's ArrayUtils class, which is bundled with CF.
ArrayUtils = createObject("java", "org.apache.commons.lang.ArrayUtils");
// Combine binary of NONCE + TS
nonceBytes = charsetDecode(NONCE, "UTF-8");
timeBytes = charsetDecode(TS, "UTF-8");
combinedBytes = ArrayUtils.addAll(nonceBytes, timeBytes);
// Combine with binary of SECRET
secretBytes = binaryDecode( Hash(PW,"SHA-1"), "HEX");
combinedBytes = ArrayUtils.addAll(combinedBytes, secretBytes);
// Finally, HASH the binary and convert to base64
resultAsHex = hash(combinedBytes, "SHA-1");
resultAsBase64 = binaryEncode(binaryDecode(resultAsHex, "hex"), "base64");
writeDump(resultAsBase64);

Encode Unicode String to Base64 with VBScript

I want to encode a powershell command (a string (get-date).date) to base64 in order to run it via powershell -encodedcommand xxx.
Using the standard VBS methods (or even https://www.base64encode.org/) I get KGdldC1kYXRlKS5kYXRl which does not run.
Using the following powershell script:
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)
I get KABnAGUAdAAtAGQAYQB0AGUAKQAuAGQAYQB0AGUA which works. The difference appears to be that the command is first encoded as Unicode bytes.
Can anyone provide a VBS Function which does this or the VBS equivalent of Unicode.GetBytes() so that we can get the right string encoded?
PowerShell only accepts Base64 encodings of UTF-16 LE-encoded strings with its
-EncodedCommand parameter.
UTF-16 LE is what Unicode stands for in [System.Text.Encoding]::Unicode, and it encodes the vast majority of Unicode characters (code points) as two bytes each; it is also the string encoding used internally by both VBScript and PowerShell.
By contrast, most VBScript solutions out there use the single-byte ASCII encoding, and even the otherwise laudably Unicode-aware https://www.base64encode.org/ only offers UTF-8-based encoding (which is a mostly-single-byte-for-Western-languages encoding with other languages' chars. represented as 2-4 bytes).
Here's a robust UTF-16 LE-based Base64 encoding solution.
I've posted a more modular variant that optionally supports UTF-8 here; the code in both locations builds on this great answer.
Example call:
Base64EncodeUtf16Le("(get-date).date") ' -> "KABnAGUAdAAtAGQAYQB0AGUAKQAuAGQAYQB0AGUA"
Source code:Tip of the hat to MC ND for helping to simplify the solution.
' Base64-encodes the specified string using UTF-16 LE as the underlying text
' encoding.
Function Base64EncodeUtf16Le(ByVal sText)
Dim bytesUtf16Le
' Create an aux. stream from which we can get a binary (byte array)
' representation of the input string in UTF-16 LE encoding.
With CreateObject("ADODB.Stream")
' Create a UTF 16-LE encoded text stream...
.Type = 2 ' adTypeText
.Charset = "utf-16le"
.Open
.WriteText sText
' ... and convert it to a binary stream,
' so we can get the string as a byte array
.Position = 0
.Type = 1 ' adTypeBinary
.Position = 2 ' Skip BOM
bytesUtf16Le = .Read
.Close
End With
' Use an aux. XML document with a Base64-encoded element.
' Assigning a byte stream (array) to .NodeTypedValue
' automatically performs Base64-encoding, whose result can then be accessed
' as the element's text.
With CreateObject("Msxml2.DOMDocument").CreateElement("aux")
.DataType = "bin.base64"
.NodeTypedValue = bytesUtf16Le
Base64EncodeUtf16Le = .Text
End With
End Function
I'm not sure this will handle all your needs, but at least it matches the output indicated in your question
Function ToBase64( ByVal text )
Const adTypeText = 2
Const adTypeBinary = 1
' Right pad each character with a null
With New RegExp
.Pattern = "(.)"
.Global = True
text = .Replace( text, "$1" & Chr(0) )
End With
' Convert String to binary
With WScript.CreateObject("ADODB.Stream")
.Type = adTypeText
.CharSet = "us-ascii"
.Open
.WriteText text
.Position = 0
.Type = adTypeBinary
text = .Read
End With
' Encode binary as Base64
With WScript.CreateObject("Msxml2.DOMDocument.6.0").CreateElement("base64")
.dataType = "bin.base64"
.nodeTypedValue = text
ToBase64 = Replace( .text, vbLf, "" )
End With
End Function
WScript.Echo ToBase64("(get-date).date")
edited just to adapt my previous code to the information in mklement0 answer where you can find the details of the powershell requirements and all the details about how the code works.
Function ToBase64( ByVal text )
Const adTypeText = 2
Const adTypeBinary = 1
' Change string encoding
With WScript.CreateObject("ADODB.Stream")
' Convert input string to UTF-16 LE
.Type = adTypeText
.CharSet = "utf-16le"
.Open
.WriteText text
' Get binary representation of the string
.Position = 0
.Type = adTypeBinary
.Position = 2 ' Skip BOM
text = .Read
End With
' Encode binary as Base64
With WScript.CreateObject("Msxml2.DOMDocument.6.0").CreateElement("base64")
.dataType = "bin.base64"
.nodeTypedValue = text
ToBase64 = Replace( .text, vbLf, "" )
End With
End Function
WScript.Echo ToBase64("(get-date).date")

Coldfusion 9 Hash Binary SHA-256 [duplicate]

I am using ColdFusion 9
Referencing Ben Nadel's good works on his blog, I tried
ucase(digestUtils.sha512(imageBinary))
For SHA-512 hashing I get that dreaded:
The sha512 method was not found. Either there are no methods with the
specified method name and argument types or the sha512 method is
overloaded with argument types that ColdFusion cannot decipher
reliably. ColdFusion found 0 methods that match the provided
arguments. If this is a Java object and you verified that the method
exists, use the javacast function to reduce ambiguity.
Now I know that sha512 does indeed exist as a method, because I saw it here, but when I perform a
cfdump var="#digestUtils#"
I only get:
md5(byte[]) byte[]
md5(java.lang.String) byte[]
md5Hex(byte[]) java.lang.String
md5Hex(java.lang.String) java.lang.String
sha(java.lang.String) byte[]
sha(byte[]) byte[]
shaHex(java.lang.String) java.lang.String
shaHex(byte[]) java.lang.String
What happened to the other methods? I guess I have to try something else.
Please advise with a ColdFusion solution. A ColdFusion/Java solution would be ok too.
I'm trying to write a SSO application where the 3rd party guys feeds me URL parameters. I have successfully decoded the 1st parameter to get my XML Post. I now need to take the 2nd parameter which is the hash payload and go through the algorithm to ensure my 1st parameter hasn't been tampered with.
=========
Editing begins here: Okay,I tried writing the code again to no avail.
The algorithm sounds simple enough. But trying to implement it is killing me.
1. compute the hash string value of the XMLPost string above:
a. convert the base64 salt string to a UTF-8 byte array.
b. convert the base64 XML payload string to a UTF-8 byte array.
c. create a new byte array consisting of the XML payload bytes from step b, appended with the salt bytes from step a.
d. perform a SHA512 hash on the concatenated byte array from step c, which results in a hashed byte array.
e. create a new byte array consisting of the hashed bytes from step d, appended with the salt bytes from step a.
f. convert the result of step e to a base64-encoded string and should be the value of query string parameter "h" payload hash.
xmlPost was created by my third party guys as such:
This XML payload string was converted to a UTF-8 byte array, which was then converted to a base-64 string. The resulting base-64 string is the value of my xmlPost below.
So I do this:
<code>
<cfset xmlPost = urlDecode("PD94bWwgdmVyc2lvbj0iMS4wIj8%2bPEVzdG9yZVNzb0N1c3RvbWVyIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiPjxDdXN0b21lcklkPjExMjk0MDwvQ3VzdG9tZXJJZD48RGVhbGVyQ29kZT5OODg4ODg8L0RlYWxlckNvZGU%2bPFBvaW50QmFsYW5jZT4yODA8L1BvaW50QmFsYW5jZT48Rmlyc3ROYW1lPkZhaXRoPC9GaXJzdE5hbWU%2bPExhc3ROYW1lPkh1dHVsYTwvTGFzdE5hbWU%2bPC9Fc3RvcmVTc29DdXN0b21lcj4%3d") />
<cfset salt = "3dfjh674!MujErf98344#090" />
<cfset payload_hash = urlDecode("EtLDRJfcRESFKpY4OGZZnRSN2THqT%2bEelzOuXVU06jotd2kE4yKnlYay7BqyAdcUSATRgSMaHxZa6uBqKKd9rjNkZmpoNjc0IU11akVyZjk4MzQ0QDA5MA%3d%3d") />
<cfset strXML = ToString( ToBinary( xmlpost ) ) /> <!--- to get actual XML --->
<!--- base64 encoding returns a byte array --->
<cfset saltByteArray = toBase64( salt, "utf-8" ) />
<cfset xmlpostByteArray = toBase64( xmlPost, "utf-8" ) />
<!--- append salt to xmlpost --->
<cfset xmlpostsaltByteArray = xmlpostByteArray & saltByteArray />
<!--- now let us perform a sha512 hash on this concatenated byte array --->
<cfscript>
// Create an instance of our DigestUtils class
digestUtils = createObject("java","org.apache.commons.codec.digest.DigestUtils");
// I hash a byte array using the given algorithm and return a
// 32-character Hexadecimal string. Home-made hash function for CF9 and earlier
function hashBytes( bytes, algorithm = "SHA-512" ){
// Get our instance of the digest algorithm that we'll use
// to hash the byte array.
var messageDigest = createObject( "java", "java.security.MessageDigest" ).getInstance( javaCast( "string", algorithm ) );
// Get the digest for the given byte array. This returns the
// digest (i.e., hash) in byte-array format.
var digest = messageDigest.digest( bytes );
// Now that we have our digested byte array (i.e., our hash as another byte
// array), we have to convert that into a HEX string. So, we'll need a HEX buffer.
var hexBuffer = [];
// Each integer in the byte digest needs to be converted into
// a HEX character (with possible leading zero).
for (byte =1 ;byte LTE ArrayLen(digest);byte = byte + 1) {
//for ( var byte in digest){
// Get the hex value for this byte. When converting the
// byte, only use the right-most 8 bits (last 8 bits of the integer)
// otherwise the sign of the byte can create oddities
var tail = bitAnd( 255, byte );
// Get the hex-encoding of the byte.
var hex = ucase( formatBaseN( tail, 16 ) );
// In order to make sure that all of the HEX characters
// are two-digits, we have to prepend a zero for any
// value that was originally LTE to 16 (the largest value
// that won't result in two HEX characters).
arrayAppend( hexBuffer, (tail <= 16 ? ("0" & hex) : hex) );
}
// Return the flattened character buffer.
return( arrayToList( hexBuffer, "" ) );
}
// Get the hash of the byte array using our hashBytes() function
hashByteArray = hashBytes( xmlpostsaltByteArray );
</cfscript>
<!--- The hashByteArray is in HEX format now. Convert to binary --->
<!--- You must binary decode the hashed string before converting it to binary --->
<cfset hashByteArray = toBase64( BinaryDecode( hashByteArray, 'HEX' ) ) />
<!--- The final step is to append this new hashbytearray with the salt byte array --->
<cfset hashByteArray = hashByteArray & saltByteArray />
<!--- now convert this value to a base64 encoded string --->
<cfset hashByteArray2 = toBase64( hashByteArray )/>
Here is what I get for my strXML variable:
Actual xml structure converted from base 64 to string:
<?xml version="1.0"?><EstoreSsoCustomer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><CustomerId>112940</CustomerId><DealerCode>N88888</DealerCode><PointBalance>280</PointBalance><FirstName>Faith</FirstName><LastName>Hutula</LastName></EstoreSsoCustomer>
The final value, hasByteArray2 is not even remotely similar to payload_hash
This is my first time doing this and my understanding of hashing, byte arrays and character conversions flew out of the window decades ago.
What am I doing wrong?
Thank you
Faith Sloan
DigestUtils.sha512 was added in version 1.4. ColdFusion 9 uses an older version, 1.3. That is why the method is not found.
Use the other function based on MessageDigest. Just be sure to pass in the correct algorithm ie:
imageHash = hashBytes( imageBinary, "SHA-512" );
UPDATE: Based on the updated code, some of the instructions may be a bit misleading. I believe they just mean decode the xml and salt strings from their given encoding (base64 and utf-8) into byte arrays, not strings:
// note: salt value has invalid characters for base64
// assuming it is a plain utf-8 string
saltArray = charsetDecode(salt, "utf-8");
xmlByteArray = binaryDecode(xmlPost, "base64");
Then merge the two binary arrays (see custom function)
mergedBytes = mergeArrays( xmlByteArray, saltArray );
Calculate the hash of the new byte array:
messageDigest = createObject( "java", "java.security.MessageDigest" );
messageDigest = messageDigest.getInstance( javaCast( "string", "SHA-512") );
hashedByteArray = messageDigest.digest( javacast("byte[]", mergedBytes) );
Merge the arrays again:
mergedBytes = mergeArrays( hashedByteArray, saltArray);
Finally convert the binary to base64 and compare:
calculatedPayload = binaryEncode( javacast("byte[]", mergedBytes), "base64");
// check results
arePayloadsEqual = compare(calculatedPayload, payload_hash) eq 0;
WriteDump("arePayloadsEqual="& arePayloadsEqual);
WriteDump("calculatedPayload="& calculatedPayload);
WriteDump("payload_hash="& payload_hash);
Note: BinaryDecode/CharsetDecode return java arrays. Unlike CF arrays, they are immutable (ie cannot be changed). So the handy addAll(..) trick will not work here.
// merge immutable arrays the long way
function mergeArrays( array1, array2 ){
var i = 0;
var newArray = [];
for (i = 1; i <= arrayLen(arguments.array1); i++) {
arrayAppend(newArray, arguments.array1[i]);
}
for (i = 1; i <= arrayLen(arguments.array2); i++) {
arrayAppend(newArray, arguments.array2[i]);
}
return newArray;
}

How to stop Server.HtmlEncode to encode UTF8 characters?

How can I stop Server.HtmlEncode to encode UTF8 characters? I set the codepage to UTF8 but didn't help
Here is my test case:
<%#CODEPAGE=65001%>
<%
Response.CodePage = 65001
Response.CharSet = "utf-8"
%>
<%=Server.HtmlEncode("русский stuff <b>bold stuff</b>")%>
It should normally output this:
русский stuff <b>bold stuff</b>
but the output is:
русский stuff <b>bold stuff</b>
Server.HtmlEncode method escapes >,<,&," chars and any ascii code character whose code is greater than or equal to 0x80.You can filter which character will be escaped.
There are generic characters will be encoded in pattern.
If you prefer, you can add some other chars too.
Private Function cb_Escape(ByVal a, ByVal b, ByVal c, ByVal d)
cb_Escape = Server.HTMLEncode(b)
End Function
Private Function HTMLEncode2(ByVal sHTML)
Dim oReg
Set oReg = New RegExp
oReg.Global = True
oReg.Pattern = "([<>""&]+)"
HTMLEncode2 = oReg.Replace(sHTML, GetRef("cb_Escape"))
Set oReg = Nothing
End Function
Response.Write HTMLEncode2("русский stuff <b>bold stuff</b>")

Calculating SHA1 hash of a 'nvarchar' string using T-SQL

I'm trying to calculate SHA1 hash of a unicode string using T-SQL. The below code works fine with ASCII strings:
declare #input varchar(50)
set #input = 'some text'
print 'SHA1 Hash: ' + UPPER(master.dbo.fn_varbintohexsubstring(0, HashBytes('SHA1', #input), 1, 0))
but it calculates wrong hash when I replace first line of code with declare #input nvarchar(50).
Calculated hash (nvarchar): BBA91B680CE2685E9465DE24967E425CF055B10F
Calculated hash by a tool : 37AA63C77398D954473262E1A0057C1E632EDA77
How can I calculate SHA1 hash of a nvarchar ?
[EDIT]:
Below C# code generate same hash as the tool I use for hashing:
// Computes SHA1 hash of a given string
string ComputeHash(string input)
{
string result = string.Empty;
byte[] hash;
byte[] bytes = Encoding.GetBytes(input);
using (var sha = SHA1Managed.Create())
hash = sha.ComputeHash(bytes);
foreach (var b in hash)
result += b.ToString("X2");
return result;
}
Are you sure that the hash returned by your tool is using UTF16 or Unicode encoding when you compare it with the one returned by SQL Server?...SHA1 (and other encoding formats) depends on the data type, so it should return different values when given as an input. Take a look at this link for a more detailed explanation.