encryption - Blowfish Results different between C# and Classic ASP -


i need encrypt value in c# , decrypt in classic asp. closest i've come getting work @ blowfish. problem 2 implementations produce different results , i'm not sure why.

implementations in use:

c#: https://defuse.ca/blowfish.htm

vbscript: http://www.di-mgt.com.au/cryptoblowfishasp.html

c# code:

var input = "hello world"; var key = "04b915ba43feb5b6"; blowfish b = new blowfish(key);  string enc, dec;  enc = b.encrypt_ecb(input); dec = b.decrypt_ecb(enc); 

vbscript:

dim akey() dim nkeylen, sztxtkey, sztxtplain, sztxtkeyasstring, sztxtcipher, sztxtcipherhex, sztxtcipher64, sztxtdecrypt  sztxtkey = "04b915ba43feb5b6" sztxtplain = "hello world"  redim akey((len(sztxtkey) \ 2) - 1) nkeylen = bu_hexstr2bytes(sztxtkey, akey) call blf_key(akey, nkeylen) sztxtkeyasstring = bu_bytes2hexstr(akey, nkeylen)   sztxtcipher = blf_stringenc(sztxtplain) sztxtcipherhex = bu_str2hex(sztxtcipher)  

c# output:

819dd50a925a5eb83ed723bea6d84984 

vbscript output:

819dd50a925a5eb8cabe974a654a18a8 

the first half of output same: "819dd50a925a5eb8"

an funny thing is, if decrypt vbscript output c# library this: hello world♣♣♣♣♣

so...it works there's sort of padding or going on. don't know how fix though.

as @artjom-b has already mentioned in comments, culprit different padding.

there explanation of different padding methods here.

analysing blowfish.cs file shows it's using null padding (note snippet file);

/// <summary> /// decrypts string (ecb) /// </summary> /// <param name="ct">hhex string of ciphertext</param> /// <returns>plaintext ascii string</returns> public string decrypt_ecb(string ct) {     return encoding.ascii.getstring(decrypt_ecb(hextobyte(ct))).replace("\0", ""); } 

in contrast classic asp implementation uses pkcs5 padding (snippet basblowfishfns.asp shows pkcs5 method)

from using padding in encryption
pad bytes of same value number of padding bytes (pkcs5 padding)

' # of padding bytes last char npad = asc(right(strdata, 1)) if npad > 8 npad = 0   ' in case invalid strdata = left(strdata, nlen - npad) 

the fix apply workaround null padding used c# library.

here modified basblowfishfns.asp (just showing modified functions);

public function blf_stringenc(strdata, padmethod) ' encrypts plaintext strdata after adding rfc 2630 padding ' returns encrypted string. ' requires key , boxes set up. ' version 5. revised. ' speed improvement here due robert garofalo.     dim strin     dim strout     dim nlen     dim spad     dim npad     dim nblocks     dim     dim j     dim abytes(7)     dim sblock     dim iindex      ' pad data string multiple of 8 bytes     strin = padstring(strdata, padmethod)     ' calc number of 8-byte blocks     nlen = len(strin)     nblocks = nlen \ 8     ' allocate output string here can use mid($ below     ' strout = string(nlen, " ")     strout = ""     ' fix vbscript      ' work through string in blocks of 8 bytes     iindex = 0     = 1 nblocks         sblock = mid(strin, iindex + 1, 8)         ' convert bytes         ' abytes() = strconv(sblock, vbfromunicode)         call bu_string2bytes(sblock, abytes)         ' encrypt block         call blf_encryptbytes(abytes)         ' convert string         ' sblock = strconv(abytes(), vbunicode)         sblock = bu_bytes2string(abytes, 8)         ' copy output string         ' mid(strout, iindex + 1, 8) = sblock         strout = strout & sblock         iindex = iindex + 8     next      blf_stringenc = strout  end function  public function blf_stringdec(strdata, padmethod) ' decrypts ciphertext strdata , removes rfc 2630 padding ' returns decrypted string. ' requires key , boxes set up. ' version 5. revised. ' speed improvement here due robert garofalo.     dim strin     dim strout     dim nlen     dim spad     dim npad     dim nblocks     dim     dim j     dim abytes(7)     dim sblock     dim iindex      strin = strdata     ' calc number of 8-byte blocks     nlen = len(strin)     nblocks = nlen \ 8     ' allocate output string here can use mid($ below     'strout = string(nlen, " ")     strout = ""      ' work through string in blocks of 8 bytes     iindex = 0     = 1 nblocks         sblock = mid(strin, iindex + 1, 8)         ' convert bytes         ' abytes() = strconv(sblock, vbfromunicode)         call bu_string2bytes(sblock, abytes)         ' encrypt block         call blf_decryptbytes(abytes)         ' convert string         'sblock = strconv(abytes(), vbunicode)         sblock = bu_bytes2string(abytes, 8)         ' copy output string         ' mid(strout, iindex + 1, 8) = sblock         strout = strout & sblock         iindex = iindex + 8     next      ' strip padding, if valid     strout = unpadstring(strout, padmethod)      blf_stringdec = strout  end function  public function padstring(strdata, method) ' pad data string next multiple of 8 bytes per rfc 2630     dim nlen     dim spad     dim npad     nlen = len(strdata)     npad = ((nlen \ 8) + 1) * 8 - nlen     select case method     case "pkcs5"         spad = string(npad, chr(npad))  ' pad # of pads (1-8)     case "null"         spad = string(npad, chr(0))  ' pad # of null characters     end select     padstring = strdata & spad  end function  public function unpadstring(strdata, method) ' strip rfc 2630-style padding     dim nlen     dim npad     nlen = len(strdata)     if nlen = 0 exit function     select case method     case "pkcs5"         ' # of padding bytes last char         npad = asc(right(strdata, 1))         if npad > 8 npad = 0   ' in case invalid         strdata = left(strdata, nlen - npad)     case "null"         'remove null characters, obviously, method isn't ideal if         'the data contains valid nulls. shouldn't issue         'ascii text.         strdata = replace(strdata, chr(0), "")     end select     unpadstring = strdata end function 

the key modifications padstring() , unpadstring() functions. i've added parameter method allowing pass identifier null or pkcs5 determine how pad / unpad data. these functions existed reason not used blf_stringenc() , blf_stringdec() functions in interests of dry principle i've modified them used.

with modifications (which quick stab @ making code more flexible) using following code;

dim akey() dim nkeylen, sztxtkey, sztxtplain, sztxtkeyasstring, sztxtcipher, sztxtcipherhex, sztxtcipher64, sztxtdecrypt  sztxtkey = "04b915ba43feb5b6" sztxtplain = "hello world"  redim akey((len(sztxtkey) \ 2) - 1) nkeylen = bu_hexstr2bytes(sztxtkey, akey) call blf_key(akey, nkeylen) sztxtkeyasstring = bu_bytes2hexstr(akey, nkeylen)   'encrypt using null padding method. sztxtcipher = blf_stringenc(sztxtplain, "null") sztxtcipherhex = bu_str2hex(sztxtcipher)  call response.write(sztxtcipherhex) 

will result in;

819dd50a925a5eb83ed723bea6d84984 

as expected.


Comments

Popular posts from this blog

Command prompt result in label. Python 2.7 -

javascript - How do I use URL parameters to change link href on page? -

amazon web services - AWS Route53 Trying To Get Site To Resolve To www -