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
Post a Comment