base64 encode/decode issue

J

James

Hello,

I am having a problem. I am working on a front end web app that reads data
from a database... the issue is the data is put into the database from some
wsh/vbscripts. One of the fields is encrypted and then base64 encoded using
Mike Shaffer's RC4 code and microsofts base64 vbscript functions
(copy/pasted below). I need to be able to decode/decrypt this data from the
c# web app side. The problem I'm having seems to be related to the base64
encoding/decoding on the c# side... but I'm not sure.

the complete process of encrypting + encoding, then decoding + decrypting,
works fine when done all via the vbscript code. However my c# implementation
is not working. It uses the c# rc4 translation (link below) for the
encryption/decryption, which seems to work by itself, and I have tried both
of the following for the base64 stuff:

private string Base64Encode(string sString)
{
byte[] sString_bytes = UnicodeEncoding.UTF8.GetBytes(sString);
return Convert.ToBase64String(sString_bytes);
}

private string Base64Decode(string sBase64String)
{
byte[] sBase64String_bytes =
Convert.FromBase64String(sBase64String);
return UnicodeEncoding.UTF8.GetString(sBase64String_bytes);
}

AND

public string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes =
System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}

public string DecodeFrom64(string encodedData)

{
byte[] encodedDataAsBytes =
System.Convert.FromBase64String(encodedData);
string returnValue =
System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
return returnValue;
}

neither of which are working...

anyone know why these two functions (above) would not be encoding/decoding
the rc4 text accurately? I don't get errors, the base64 results between the
c# system and the vbscript system just do not match when used on the rc4
ciphertext? BUT, when just encrypting/decrypting, or just encoding/decoding,
the data DOES match... so I believe that narrows it down to the c# base64
routines I'm trying not working on some of the characters returned by the
rc4 encryption... something to do with encoding.. but I believe all the
vbscript code is ascii? Whether or not the vbscript code is itself accurate
is secondary since I need to be able to decode the data it produces.

MS's base64 vbscript code I'm using is copy/pasted below and I have provided
links to the other relevant source code.

Anyone feel like enlightening one in need?

The complete source code to a c# translation of Mike's RC4 code, which I am
using on the web app side, is here:
http://aspnet.4guysfromrolla.com/code/rc4encrypt.cs.htm

original vbscript rc4 code can be found here:
http://www.4guysfromrolla.com/webtech/010100-1.shtml

Microsofts base64 functions below:
'---------------------------------------------------------------------------- 'start: MS's base64 functions (MDT 2008 update 1,ztiutility.vbs)------------ '---------------------------------------------------------------------------- Const BASE64_TABLE ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" Function SafeAsc ( sPlainText, pos ) if VarType(sPlainText) = (vbArray or vbByte) then SafeAsc = cint(midb(sPlainText, pos + 1 , 1)) elseif (pos + 1) <= len(sPlainText) then SafeAsc = asc(mid(sPlainText, pos + 1, 1)) else SafeAsc = 0 end if End Function Function SafeEnc( n, x ) Const BASE64_TABLE ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" SafeEnc = mid(BASE64_TABLE, ((n\(2^x)) and 63) + 1,1) End Function Function base64Encode( sPlainText ) Dim i, n if 0 < len(sPlainText) then for i = 0 to len(sPlainText) - 1 step 3 ' Add a new line ... if i > 0 and i mod 57 = 0 then base64Encode = base64Encode & vbNewLine end if ' three 8-bit characters become one 24-bit number n = (SafeAsc(sPlainText,i)*&h10000 + SafeAsc(sPlainText,i+1)*&h100 +SafeAsc(sPlainText,i+2)) ' the 24-bit number becomes four 6-bit numbers base64Encode = base64Encode & SafeEnc( n, 18 ) & SafeEnc( n, 12 ) &SafeEnc( n, 6 ) & SafeEnc( n, 0 ) next end if ' Pad Text at End of String n = (3-(len(sPlainText)mod 3)) mod 3 base64Encode = left ( base64Encode, len(base64Encode) - n ) + string( n,"=" ) End Function Function SafeDecode( s, i, x ) Const BASE64_TABLE ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" SafeDecode = ( InStr(1, BASE64_TABLE, mid(s,i,1), vbBinaryCompare) - 1) *(2 ^ x) End Function Function base64Decode( sEncodedText ) Dim sEncText Dim regex Dim p, i, n ' Remove all non base64 text set regex = new RegExp regex.pattern = "[^=" & BASE64_TABLE & "]" regex.global = true sEncText = regex.Replace(sEncodedText,"") sEncText = replace( sEncText, vbLF, "") sEncText = replace( sEncText, vbCR, "") ' Verify String is in Base64 format (multiple of 4 chars) if len(sEncText) mod 4 <> 0 then oLogging.CreateEntry "OSDBitLockerStartupKey is not a valid string (notBase64 Format)", LogTypeError exit function end if if right(sEncText,2) = "==" then p = 2 elseif right(sEncText,1) = "=" then p = 1 end if sEncText = left(sEncText,len(sEncText)-p) & string(p,"A") for i = 1 to len(sEncText) step 4 ' Convert four 6-bit numbers into one 24 bit value n = SafeDecode(sEncText,i+3,0) + SafeDecode(sEncText,i+2,6) +SafeDecode(sEncText,i+1,12) + SafeDecode(sEncText,i+0,18) ' Convert the 24-bit value back into three 8-bit values. base64Decode = base64Decode & chr( (n \ (2^16)) and 255 ) & chr( (n \(2^8)) and 255 ) & chr( n and 255 ) next ' Trim off any excess space. base64Decode = left(base64Decode,len(base64Decode)-p) End Function '------------------------------------------------------------------------------ 'END: MS's base64functions --------------------------------------------------- '------------------------------------------------------------------------------
 
J

James

I see my copy/paste of some code lost all white space so the attached file,
which is a fully operational hta app, demonstrates all the vbscript side of
this. This will be much easier to reference rather than going to seperate
links for pieces. Basically, I need my c# app to do this.

I'm stuck and in a bind.

James said:
Hello,

I am having a problem. I am working on a front end web app that reads data
from a database... the issue is the data is put into the database from
some wsh/vbscripts. One of the fields is encrypted and then base64 encoded
using Mike Shaffer's RC4 code and microsofts base64 vbscript functions
(copy/pasted below). I need to be able to decode/decrypt this data from
the c# web app side. The problem I'm having seems to be related to the
base64 encoding/decoding on the c# side... but I'm not sure.

the complete process of encrypting + encoding, then decoding + decrypting,
works fine when done all via the vbscript code. However my c#
implementation is not working. It uses the c# rc4 translation (link below)
for the encryption/decryption, which seems to work by itself, and I have
tried both of the following for the base64 stuff:

private string Base64Encode(string sString)
{
byte[] sString_bytes = UnicodeEncoding.UTF8.GetBytes(sString);
return Convert.ToBase64String(sString_bytes);
}

private string Base64Decode(string sBase64String)
{
byte[] sBase64String_bytes =
Convert.FromBase64String(sBase64String);
return UnicodeEncoding.UTF8.GetString(sBase64String_bytes);
}

AND

public string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes =
System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}

public string DecodeFrom64(string encodedData)

{
byte[] encodedDataAsBytes =
System.Convert.FromBase64String(encodedData);
string returnValue =
System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
return returnValue;
}

neither of which are working...

anyone know why these two functions (above) would not be encoding/decoding
the rc4 text accurately? I don't get errors, the base64 results between
the c# system and the vbscript system just do not match when used on the
rc4 ciphertext? BUT, when just encrypting/decrypting, or just
encoding/decoding, the data DOES match... so I believe that narrows it
down to the c# base64 routines I'm trying not working on some of the
characters returned by the rc4 encryption... something to do with
encoding.. but I believe all the vbscript code is ascii? Whether or not
the vbscript code is itself accurate is secondary since I need to be able
to decode the data it produces.

MS's base64 vbscript code I'm using is copy/pasted below and I have
provided links to the other relevant source code.

Anyone feel like enlightening one in need?

The complete source code to a c# translation of Mike's RC4 code, which I
am using on the web app side, is here:
http://aspnet.4guysfromrolla.com/code/rc4encrypt.cs.htm

original vbscript rc4 code can be found here:
http://www.4guysfromrolla.com/webtech/010100-1.shtml

Microsofts base64 functions below:
'----------------------------------------------------------------------------
'start: MS's base64 functions (MDT 2008 update
1,ztiutility.vbs)------------
'----------------------------------------------------------------------------
Const BASE64_TABLE
="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
Function SafeAsc ( sPlainText, pos ) if VarType(sPlainText) = (vbArray or
vbByte) then SafeAsc = cint(midb(sPlainText, pos + 1 , 1)) elseif (pos
+ 1) <= len(sPlainText) then SafeAsc = asc(mid(sPlainText, pos + 1, 1))
else SafeAsc = 0 end if End Function Function SafeEnc( n, x ) Const
BASE64_TABLE
="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
SafeEnc = mid(BASE64_TABLE, ((n\(2^x)) and 63) + 1,1) End Function
Function base64Encode( sPlainText ) Dim i, n if 0 < len(sPlainText) then
for i = 0 to len(sPlainText) - 1 step 3 ' Add a new line ... if i >
0 and i mod 57 = 0 then base64Encode = base64Encode & vbNewLine
end if ' three 8-bit characters become one 24-bit number n =
(SafeAsc(sPlainText,i)*&h10000 + SafeAsc(sPlainText,i+1)*&h100
+SafeAsc(sPlainText,i+2)) ' the 24-bit number becomes four 6-bit
numbers base64Encode = base64Encode & SafeEnc( n, 18 ) & SafeEnc( n,
12 ) &SafeEnc( n, 6 ) & SafeEnc( n, 0 ) next end if ' Pad Text at End
of String n = (3-(len(sPlainText)mod 3)) mod 3 base64Encode = left (
base64Encode, len(base64Encode) - n ) + string( n,"=" ) End Function
Function SafeDecode( s, i, x ) Const BASE64_TABLE
="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
SafeDecode = ( InStr(1, BASE64_TABLE, mid(s,i,1), vbBinaryCompare) - 1)
*(2 ^ x) End Function Function base64Decode( sEncodedText ) Dim sEncText
Dim regex Dim p, i, n ' Remove all non base64 text set regex = new RegExp
regex.pattern = "[^=" & BASE64_TABLE & "]" regex.global = true sEncText =
regex.Replace(sEncodedText,"") sEncText = replace( sEncText, vbLF, "")
sEncText = replace( sEncText, vbCR, "") ' Verify String is in Base64
format (multiple of 4 chars) if len(sEncText) mod 4 <> 0 then
oLogging.CreateEntry "OSDBitLockerStartupKey is not a valid string
(notBase64 Format)", LogTypeError exit function end if if
right(sEncText,2) = "==" then p = 2 elseif right(sEncText,1) = "=" then
p = 1 end if sEncText = left(sEncText,len(sEncText)-p) & string(p,"A") for
i = 1 to len(sEncText) step 4 ' Convert four 6-bit numbers into one 24
bit value n = SafeDecode(sEncText,i+3,0) + SafeDecode(sEncText,i+2,6)
+SafeDecode(sEncText,i+1,12) + SafeDecode(sEncText,i+0,18) ' Convert the
24-bit value back into three 8-bit values. base64Decode = base64Decode &
chr( (n \ (2^16)) and 255 ) & chr( (n \(2^8)) and 255 ) & chr( n and 255 )
next ' Trim off any excess space. base64Decode =
left(base64Decode,len(base64Decode)-p) End Function
'------------------------------------------------------------------------------
'END: MS's
base64functions ---------------------------------------------------
'------------------------------------------------------------------------------
 
J

James

thank you for the reply rossum.

My resolution: I assume the vbscript chr and asc functions use the default
codepage just like they do in the microsoft.visualbasic .net namespace
(which was used in c# translation of the vbscript). I was using the
ASCIIEncoding.ASCII class to go from string to bytes and vice versa. That
class only supports real ASCII, chrs 0 - 127, but the rc4 code uses integers
0 - 255, commonly refered to as 'extended ascii', which I know is incorrect,
there is no extended ascii, at least no 'standard' one. So I changed my
base64 functions to the following and all is well (as long as the encryption
and decryption is taking place on systems using the same code page, which in
my case it is).

private string Base64Encode(string sString)
{
byte[] sString_bytes =
Encoding.GetEncoding(Encoding.Default.CodePage).GetBytes(sString);
return Convert.ToBase64String(sString_bytes);
}

private string Base64Decode(string sBase64String)
{
byte[] sBase64String_bytes =
Convert.FromBase64String(sBase64String);
return
Encoding.GetEncoding(Encoding.Default.CodePage).GetString(sBase64String_bytes);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top