c# - Yet Another "The input is not a valid Base-64 string..." -
so i've used aes encrypt/decrypt methods i've seen on net modified little. methods written below.
public void encryptstringaes(object threadcontext) { if (string.isnullorempty(inputdata)) { outputdata = string.empty; doneeventproperty.set(); return; } if (string.isnullorempty(sharedsecretdata)) throw new argumentnullexception("sharedsecret"); string outstr = null; rijndaelmanaged aesalg = null; try { rfc2898derivebytes key = new rfc2898derivebytes(sharedsecretdata, saltdata); aesalg = new rijndaelmanaged(); aesalg.padding = paddingmode.pkcs7; aesalg.key = key.getbytes(aesalg.keysize / 8); icryptotransform encryptor = aesalg.createencryptor(aesalg.key, aesalg.iv); using (memorystream msencrypt = new memorystream()) { msencrypt.write(bitconverter.getbytes(aesalg.iv.length), 0, sizeof(int)); msencrypt.write(aesalg.iv, 0, aesalg.iv.length); using (cryptostream csencrypt = new cryptostream(msencrypt, encryptor, cryptostreammode.write)) { using (streamwriter swencrypt = new streamwriter(csencrypt)) { swencrypt.write(inputdata); } } outstr = convert.tobase64string(msencrypt.toarray()); } } { if (aesalg != null) aesalg.clear(); } outputdata = outstr; doneeventproperty.set(); } public void decryptstringaes(object threadcontext) { if (string.isnullorempty(inputdata)) { outputdata = string.empty; doneeventproperty.set(); return; } if (string.isnullorempty(sharedsecretdata)) throw new argumentnullexception("sharedsecret"); rijndaelmanaged aesalg = null; string plaintext = null; try { rfc2898derivebytes key = new rfc2898derivebytes(sharedsecretdata, saltdata); byte[] bytes = convert.frombase64string(inputdata.tostring()); using (memorystream msdecrypt = new memorystream(bytes)) { aesalg = new rijndaelmanaged(); aesalg.padding = paddingmode.pkcs7; aesalg.key = key.getbytes(aesalg.keysize / 8); aesalg.iv = readbytearray(msdecrypt); icryptotransform decryptor = aesalg.createdecryptor(aesalg.key, aesalg.iv); using (cryptostream csdecrypt = new cryptostream(msdecrypt, decryptor, cryptostreammode.read)) { using (streamreader srdecrypt = new streamreader(csdecrypt)) { plaintext = srdecrypt.readtoend(); } } } } { if (aesalg != null) aesalg.clear(); } outputdata = plaintext; doneeventproperty.set(); }
i modified object these codes used queued on thread pool , make whole encryption/decryption process quicker. before modified code threading, works. after added threading capabilities, encounter error:
the input not valid base-64 string contains non-base 64 character, more 2 padding characters, or illegal character among padding characters.
this happens when decrypt string encrypted. below examples of data encrypted.
eaaaallzu0f1hmtq0pno/xpoobgr4zrjvhiyr43van78dded eaaaaivlxl+vtqhaf3hcfprc6xeb76kfqhfe6tbu1sn7lzh1
i've checked requirements of base64 strings , these pretty comply requirements. tried possible answers saw here in stackoverflow no avail still. what's worse, works, doesn't. i'm running out of options here can me?
update:
below code said methods used.
class aeshandler { private string outputdataproperty; private string inputdataproperty; private byte[] saltdataproperty; private string sharedsecretdataproperty; private manualresetevent doneeventproperty; private guid signaturedataproperty; public string outputdata { { return outputdataproperty; } private set { outputdataproperty = value; } } private string inputdata { { return inputdataproperty; } set { inputdataproperty = value; } } private byte[] saltdata { { return saltdataproperty; } set { saltdataproperty = value; } } private string sharedsecretdata { { return sharedsecretdataproperty; } set { sharedsecretdataproperty = value; } } public manualresetevent doneevent { { return doneeventproperty; } } public guid signaturedata { { return signaturedataproperty; } private set { signaturedataproperty = value; } } private byte[] readbytearray(stream s) { byte[] rawlength = new byte[sizeof(int)]; if (s.read(rawlength, 0, rawlength.length) != rawlength.length) { throw new systemexception("stream did not contain formatted byte array"); } byte[] buffer = new byte[bitconverter.toint32(rawlength, 0)]; if (s.read(buffer, 0, buffer.length) != buffer.length) { throw new systemexception("did not read byte array properly"); } return buffer; } public void encryptstringaes(object threadcontext) { if (string.isnullorempty(inputdata)) { outputdata = string.empty; doneeventproperty.set(); return; } if (string.isnullorempty(sharedsecretdata)) throw new argumentnullexception("sharedsecret"); string outstr = null; rijndaelmanaged aesalg = null; try { rfc2898derivebytes key = new rfc2898derivebytes(sharedsecretdata, saltdata); aesalg = new rijndaelmanaged(); aesalg.padding = paddingmode.pkcs7; aesalg.key = key.getbytes(aesalg.keysize / 8); icryptotransform encryptor = aesalg.createencryptor(aesalg.key, aesalg.iv); using (memorystream msencrypt = new memorystream()) { msencrypt.write(bitconverter.getbytes(aesalg.iv.length), 0, sizeof(int)); msencrypt.write(aesalg.iv, 0, aesalg.iv.length); using (cryptostream csencrypt = new cryptostream(msencrypt, encryptor, cryptostreammode.write)) { using (streamwriter swencrypt = new streamwriter(csencrypt)) { swencrypt.write(inputdata); } } outstr = convert.tobase64string(msencrypt.toarray()); } } { if (aesalg != null) aesalg.clear(); } outputdata = outstr; doneeventproperty.set(); } public void decryptstringaes(object threadcontext) { if (string.isnullorempty(inputdata)) { outputdata = string.empty; doneeventproperty.set(); return; } if (string.isnullorempty(sharedsecretdata)) throw new argumentnullexception("sharedsecret"); rijndaelmanaged aesalg = null; string plaintext = null; try { rfc2898derivebytes key = new rfc2898derivebytes(sharedsecretdata, saltdata); byte[] bytes = convert.frombase64string(inputdata.tostring()); using (memorystream msdecrypt = new memorystream(bytes)) { aesalg = new rijndaelmanaged(); aesalg.padding = paddingmode.pkcs7; aesalg.key = key.getbytes(aesalg.keysize / 8); aesalg.iv = readbytearray(msdecrypt); icryptotransform decryptor = aesalg.createdecryptor(aesalg.key, aesalg.iv); using (cryptostream csdecrypt = new cryptostream(msdecrypt, decryptor, cryptostreammode.read)) { using (streamreader srdecrypt = new streamreader(csdecrypt)) { plaintext = srdecrypt.readtoend(); } } } } { if (aesalg != null) aesalg.clear(); } outputdata = plaintext; doneeventproperty.set(); } public aeshandler(string input, string sharedsecret, guid signature, byte[] salt) { if (!string.isnullorempty(input)) { inputdata = input; } else { inputdata = string.empty; } sharedsecretdata = sharedsecret; signaturedata = signature; saltdata = salt; doneeventproperty = new manualresetevent(false); } }
that's actual code handles encryption/decryption process. code below creates instance of class above , queue in thread pool.
public sealed partial class aescore { private static list<aeshandler> encryptthreadlist = new list<aeshandler>(); public static guid aesqueueencrypt(string input, string sharedsecret) { return aesqueueencrypt(input, sharedsecret, encryptioncore._salt); } public static guid aesqueueencrypt(string input, string sharedsecret, byte[] salt) { guid queueid = guid.newguid(); aeshandler handle = new aeshandler(input, sharedsecret, queueid, encryptioncore._salt); threadpool.queueuserworkitem(handle.encryptstringaes); encryptthreadlist.add(handle); return queueid; } public static guid aesqueuedecrypt(string input, string sharedsecret) { return aesqueuedecrypt(input, sharedsecret, encryptioncore._salt); } public static guid aesqueuedecrypt(string input, string sharedsecret, byte[] salt) { guid queueid = guid.newguid(); aeshandler handle = new aeshandler(input, sharedsecret, queueid, encryptioncore._salt); threadpool.queueuserworkitem(handle.decryptstringaes); encryptthreadlist.add(handle); return queueid; } public static string aesfetchdata(guid signature) { var data = encryptthreadlist.where(s => s.signaturedata == signature).firstordefault(); string output = data.outputdata; encryptthreadlist.remove(data); return output; } public static void aesprocesswait() { foreach (var d in encryptthreadlist) { d.doneevent.waitone(); } } }
usage this:
encryption
guid strnnamelast = encryption.aescore.aesqueueencrypt(user.strnnamelast, publickeytoken); guid strnnamefirst = encryption.aescore.aesqueueencrypt(user.strnnamefirst, publickeytoken); encryption.aescore.aesprocesswait(); string strnnamelastencrypted = encryption.aescore.aesfetchdata(strnnamelast); string strnnamefirstencrypted = encryption.aescore.aesfetchdata(strnnamefirst);
decryption:
guid strnnamelast = encryption.aescore.aesqueuedecrypt(user.strnnamelast, publickeytoken); guid strnnamefirst = encryption.aescore.aesqueuedecrypt(user.strnnamefirst, publickeytoken); encryption.aescore.aesprocesswait(); string strnnamelastdecrypted = convert.tostring(encryption.aescore.aesfetchdata(strnnamelast)); string strnnamefirstdecrypted = convert.tostring(encryption.aescore.aesfetchdata(strnnamefirst));
i've found problem @ last. devised simple blowfish implementation on each string properties. apparently there problems in decryption can't explain of (although output according debugger valid base-64 string). removed encryption , worked.
Comments
Post a Comment