how these 2 functions may differ?

J

James

Hello,

I'm having an issue that a previously posted on but after re-reading that
post I realize its a mess and it would be a real pain for someone to lend a
hand based on that.. so here is a much more direct question:

could anyone tell just how these .net base64 functions differ from the
vbscript base64 functions? When using them if I encode the text 'test' I get
the same result from them all, however, if I first RC4 encrypt the text
'test' and then encode that, the results differ between the vbscript and
..net functions?

both the .net functions and vbscript code is here:

START .net functions used------------------------

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;
}

OR

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);
}

END: .net functions used -------------------------------

'---------------------------------------------------------------------------- 'START: MS's base64 functions (MDT 2008 update 1, fromztiutility.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 ifEnd FunctionFunction SafeEnc( n, x ) Const BASE64_TABLE ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" SafeEnc = mid(BASE64_TABLE, ((n\(2^x)) and 63) + 1,1)End FunctionFunction 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 FunctionFunction SafeDecode( s, i, x ) Const BASE64_TABLE ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" SafeDecode = ( InStr(1, BASE64_TABLE, mid(s,i,1), vbBinaryCompare) - 1) *(2 ^ x)End FunctionFunction 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(not Base64 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 --------------------------------------------------- '------------------------------------------------------------------------------
 
F

Family Tree Mike

James said:
Hello,

I'm having an issue that a previously posted on but after re-reading that
post I realize its a mess and it would be a real pain for someone to lend a
hand based on that.. so here is a much more direct question:

could anyone tell just how these .net base64 functions differ from the
vbscript base64 functions? When using them if I encode the text 'test' I get
the same result from them all, however, if I first RC4 encrypt the text
'test' and then encode that, the results differ between the vbscript and
..net functions?

Are the encrypted strings in both cases identical?

Mike
 
J

James

yes, I'm pretty sure they are. I am sure that the text representation of
them on screen (displayed in text box control) is identical.

I see the vbscript code formatting was lost in my post... I'll try to attach
in a .txt file (windows notepad.exe)

I'm reading through msdn docs now and I'm thinking this has something to do
with the fact that the rc4 cipher is using ascii characters 0-255 and the
..net asciiEncoding class only uses 0-127.... maybe I need to add a step
where I change the encrypted text to unicode, then base64 it?
 
B

Ben Voigt [C++ MVP]

James said:
yes, I'm pretty sure they are. I am sure that the text representation
of them on screen (displayed in text box control) is identical.

I see the vbscript code formatting was lost in my post... I'll try to
attach in a .txt file (windows notepad.exe)

I'm reading through msdn docs now and I'm thinking this has something
to do with the fact that the rc4 cipher is using ascii characters
0-255 and the .net asciiEncoding class only uses 0-127.... maybe I
need to add a step where I change the encrypted text to unicode, then
base64 it?

Encrypted text is not text. It is binary data. I suggest you stop using a
string to hold it. Doesn't the encryption routine give you a byte[] out?
And the Base-64 encoding functions take a byte[] as input. No Unicode
needed, no encoding needed, just pass the byte[].
 
J

James

Hello Ben,

thanks for the reply. The original encryption and base64 encoding is done
from a Windows Script Host vbscript. The c# end of this is a web app that
must decode/decrypt this data.

I attached vbscript code that does the encryption/encoding if you want to
see. Also, a copy/paste of a c# translation of this, which is what I'm using
on the web app to try to decode/decrypt is below....

public class RC4Utility
{
// This is a translation of Mike Shaffer's vbscript code for RC4
done by Chris Scott.
// From 4guysfromrolla.com

protected int[] sbox = new int[256];
protected int[] key = new int[256];

protected string plaintext, password;

public string PlainText
{
set { plaintext = value; }
get { return plaintext; }
}

public string Password
{
set { password = value; }
get { return password; }
}

private void RC4Initialize(string strPwd)
{

int intLength = strPwd.Length;

for (int a = 0; a <= 255; a++)
{

char ctmp = (strPwd.Substring((a % intLength),
1).ToCharArray()[0]);

key[a] = Microsoft.VisualBasic.Strings.Asc(ctmp);
sbox[a] = a;
}

int x = 0;

for (int b = 0; b <= 255; b++)
{
x = (x + sbox + key) % 256;
int tempSwap = sbox;
sbox = sbox[x];
sbox[x] = tempSwap;
}
}

public string EnDeCrypt()
{
int i = 0;
int j = 0;
string cipher = "";

RC4Initialize(password);

for (int a = 1; a <= plaintext.Length; a++)
{

int itmp = 0;

i = (i + 1) % 256;
j = (j + sbox) % 256;
itmp = sbox;
sbox = sbox[j];
sbox[j] = itmp;

int k = sbox[(sbox + sbox[j]) % 256];

char ctmp = plaintext.Substring(a - 1, 1).ToCharArray()[0];

itmp = Microsoft.VisualBasic.Strings.Asc(ctmp);

int cipherby = itmp ^ k;

cipher += Microsoft.VisualBasic.Strings.Chr(cipherby);
}

return cipher;
}

}


Ben Voigt said:
James said:
yes, I'm pretty sure they are. I am sure that the text representation
of them on screen (displayed in text box control) is identical.

I see the vbscript code formatting was lost in my post... I'll try to
attach in a .txt file (windows notepad.exe)

I'm reading through msdn docs now and I'm thinking this has something
to do with the fact that the rc4 cipher is using ascii characters
0-255 and the .net asciiEncoding class only uses 0-127.... maybe I
need to add a step where I change the encrypted text to unicode, then
base64 it?

Encrypted text is not text. It is binary data. I suggest you stop using
a string to hold it. Doesn't the encryption routine give you a byte[]
out? And the Base-64 encoding functions take a byte[] as input. No
Unicode needed, no encoding needed, just pass the byte[].
 
J

James

missing from previous response: its done in vbscript so there is no byte[],
only 'variants' with subtypes. It uses the vb functions asc and chr which
translate between ascii characters and their integer codes.

Ben Voigt said:
James said:
yes, I'm pretty sure they are. I am sure that the text representation
of them on screen (displayed in text box control) is identical.

I see the vbscript code formatting was lost in my post... I'll try to
attach in a .txt file (windows notepad.exe)

I'm reading through msdn docs now and I'm thinking this has something
to do with the fact that the rc4 cipher is using ascii characters
0-255 and the .net asciiEncoding class only uses 0-127.... maybe I
need to add a step where I change the encrypted text to unicode, then
base64 it?

Encrypted text is not text. It is binary data. I suggest you stop using
a string to hold it. Doesn't the encryption routine give you a byte[]
out? And the Base-64 encoding functions take a byte[] as input. No
Unicode needed, no encoding needed, just pass the byte[].
 
J

James

I'm probably wrong here but I think the problem is that the
ASCIIEncoding.ASCII.GetBytes(string) function does not support the 'ASCII
Extended' characters (128-255).

these characters are here:
http://ascii-table.com/ascii-extended-pc-list.php

is there a way to make it support those? or a different function I could
use? or some kind of intermediate steps to eliminate problem?
 
J

James

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);
}

James said:
Hello,

I'm having an issue that a previously posted on but after re-reading that
post I realize its a mess and it would be a real pain for someone to lend
a hand based on that.. so here is a much more direct question:

could anyone tell just how these .net base64 functions differ from the
vbscript base64 functions? When using them if I encode the text 'test' I
get the same result from them all, however, if I first RC4 encrypt the
text 'test' and then encode that, the results differ between the vbscript
and .net functions?

both the .net functions and vbscript code is here:

START .net functions used------------------------

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;
}

OR

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);
}

END: .net functions used -------------------------------

'----------------------------------------------------------------------------
'START: MS's base64 functions (MDT 2008 update 1,
fromztiutility.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 ifEnd FunctionFunction SafeEnc( n, x )
Const BASE64_TABLE
="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
SafeEnc = mid(BASE64_TABLE, ((n\(2^x)) and 63) + 1,1)End FunctionFunction
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 FunctionFunction SafeDecode( s, i, x ) Const BASE64_TABLE
="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
SafeDecode = ( InStr(1, BASE64_TABLE, mid(s,i,1), vbBinaryCompare) - 1)
*(2 ^ x)End FunctionFunction 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(not Base64 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 ---------------------------------------------------
'------------------------------------------------------------------------------
 
B

Ben Voigt [C++ MVP]

James said:
Hello Ben,

thanks for the reply. The original encryption and base64 encoding is
done from a Windows Script Host vbscript. The c# end of this is a web
app that must decode/decrypt this data.

I attached vbscript code that does the encryption/encoding if you
want to see. Also, a copy/paste of a c# translation of this, which is
what I'm using on the web app to try to decode/decrypt is below....

You were already told (correctly) that this code is trash. Why are you not
using the encryption functions built in to Windows?

public class RC4Utility
{
// This is a translation of Mike Shaffer's vbscript code for
RC4 done by Chris Scott.
// From 4guysfromrolla.com

protected int[] sbox = new int[256];
protected int[] key = new int[256];

protected string plaintext, password;

public string PlainText
{
set { plaintext = value; }
get { return plaintext; }
}

public string Password
{
set { password = value; }
get { return password; }
}

private void RC4Initialize(string strPwd)
{

int intLength = strPwd.Length;

for (int a = 0; a <= 255; a++)
{

char ctmp = (strPwd.Substring((a % intLength),
1).ToCharArray()[0]);

key[a] = Microsoft.VisualBasic.Strings.Asc(ctmp);
sbox[a] = a;
}

int x = 0;

for (int b = 0; b <= 255; b++)
{
x = (x + sbox + key) % 256;
int tempSwap = sbox;
sbox = sbox[x];
sbox[x] = tempSwap;
}
}

public string EnDeCrypt()
{
int i = 0;
int j = 0;
string cipher = "";

RC4Initialize(password);

for (int a = 1; a <= plaintext.Length; a++)
{

int itmp = 0;

i = (i + 1) % 256;
j = (j + sbox) % 256;
itmp = sbox;
sbox = sbox[j];
sbox[j] = itmp;

int k = sbox[(sbox + sbox[j]) % 256];

char ctmp = plaintext.Substring(a - 1,
1).ToCharArray()[0];

itmp = Microsoft.VisualBasic.Strings.Asc(ctmp);

int cipherby = itmp ^ k;

cipher += Microsoft.VisualBasic.Strings.Chr(cipherby);
}

return cipher;
}

}


Ben Voigt said:
James said:
yes, I'm pretty sure they are. I am sure that the text
representation of them on screen (displayed in text box control) is
identical.

I see the vbscript code formatting was lost in my post... I'll try
to attach in a .txt file (windows notepad.exe)

I'm reading through msdn docs now and I'm thinking this has
something to do with the fact that the rc4 cipher is using ascii
characters 0-255 and the .net asciiEncoding class only uses
0-127.... maybe I need to add a step where I change the encrypted
text to unicode, then base64 it?

Encrypted text is not text. It is binary data. I suggest you stop
using a string to hold it. Doesn't the encryption routine give you
a byte[] out? And the Base-64 encoding functions take a byte[] as
input. No Unicode needed, no encoding needed, just pass the byte[].

in message


:

Hello,

I'm having an issue that a previously posted on but after
re-reading that post I realize its a mess and it would be a real
pain for someone to lend a
hand based on that.. so here is a much more direct question:

could anyone tell just how these .net base64 functions differ from
the vbscript base64 functions? When using them if I encode the
text 'test' I get
the same result from them all, however, if I first RC4 encrypt the
text 'test' and then encode that, the results differ between the
vbscript and ..net functions?


Are the encrypted strings in both cases identical?

Mike
 
J

James

You were already told (correctly) that this code is trash. Why are you
not using the encryption functions built in to Windows?

as for using rc4, its a requirement since what I'm putting together reads
data from an existing system that is already storing the data in this way,
as far as I know there isn't any .net builtin RC4 encryption... as for
writting my own translation using more appropriate methods, well, what I got
from the 4guysfromrolla.com site works and I don't program enough to do it
myself in a timely manner, and this is the last piece I need to finish this,
which is long overdue. I'm confident its ok for my scenario.

by the way this is what worked for me:

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);
}
 
B

Ben Voigt [C++ MVP]

James said:
as for using rc4, its a requirement since what I'm putting together
reads data from an existing system that is already storing the data
in this way, as far as I know there isn't any .net builtin RC4
encryption... as for writting my own translation using more

Windows has RC4 builtin.
http://msdn.microsoft.com/en-us/library/aa375549(VS.85).aspx
CALG_RC40x00006801RC4 stream encryption algorithm. This algorithm is
supported by the Microsoft Base Cryptographic Provider.

As for .NET, it should have been as simple as calling new CryptoAPITransform
and passing the right algid. But that constructor is marked internal. So
you'd have to p/invoke the Windows Cryptography functions directly.


appropriate methods, well, what I got from the 4guysfromrolla.com
site works and I don't program enough to do it myself in a timely
manner, and this is the last piece I need to finish this, which is
long overdue. I'm confident its ok for my scenario.

You're right that crypto is not something you want to do yourself. In a
similar vein, it's not something you want to trust to whatever poorly
written code you found with google.
 
J

James

thanks for the info... I was thinking of turning the windows forms app I
used as a test harness into a little general purpose encryption/decryption
utility for the supported .net algorithms... I'm interested in learning
about encryption/decryption but I am definitely not experienced at coding
for it at this point.

thanks again. I appreciate it.
 

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

Similar Threads


Top