|
+5 - To expand on this appraoch, whenever a user logs in successfully you can migrate them silently so that the record is updated to use the new hash, as this is the only time your code would get to see the unhashed value. (I know that you all know this, but it may help someone somewhere to spell it out)
|
|
|
|
|
A good idea, IF you have access to the plaintext credentials. Having such access might create all sorts of security holes, however.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Thanks a lot for your valuable ideas.
The situation is not exactly as described in the scenario above, rather version 2 is available since some time, and now the first customer complained about "lost" passwords - the update script resets them to empty strings.
We do not have a "forgot password" feature which would allow us to generate new passwords and mail them to the users - could be a useful improvement.
I suggested to fix it in a way very similar to your suggestion (an extra column in the user table indicating the method used), and automatically update to the new method as suggested by Reiss.
Thanks also to Luc - his idea could be useful in a future change of password handling.
|
|
|
|
|
If you don't want to do a piecewise migration, which I agree with the above is the best approach, you have to do a mass password reset, using the email for 'forgot password' for all the users.
|
|
|
|
|
if you don't want a gradual migration, do want the better security of SHA-1, and don't mind the extra cost of calculating MD5, then you could store SHA1(MD5(password)) , i.e.:
- for existing passwords perform a one-time conversion: MD5(existing_password) to SHA1(MD5(existing_password)) ;
- for new passwords: store SHA1(MD5(new_password))
|
|
|
|
|
+5 for lateral thinking!
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Thanks a lot for this nice idea.
Hash algorithms are actually optimized for performance, hence the extra cost of chaining the hash functions is in the lines of code only. Indeed I read an article somewhere (can't remember the source) where a low performing hash algorithm was suggested: for a user it doesn't matter if the hash can be calculated in a millionth of a second or in a tenth of a second - for someone trying a brute force attack it does.
|
|
|
|
|
Hi Guys and ladies. I am reading a record into a windows form which works fine. The record structure is: Header details of 463 chars and then a repetative set of records of 276 chars each. Problem is that the string can have anything between 1 and a max of 50 repetative records. On clicking the next button i am trying to display the details from the second record etc. I am trying to figure out how to best acieve this as if I click the button the first time it reads the second block of data fine, if I click it again it reads the second block again instead of reading the third bloack of data.
How do I read the data to be able to get to the third record? Would it be best to load the blocks into a dataset and then maybe read that? Below is the code I currently have.
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Dispose();
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
filepath = txtFileName.Text;
StreamReader sr = new StreamReader(filepath);
string holdLine = sr.ReadLine();
int recLength = holdLine.Length;
int startIndex = 463;
int oneRecLength = 276;
int totalRecs = (recLength - startIndex) / oneRecLength;
int startread = 739;
int lastread = 0;
if ((recLength - 463) > 1015)
{
if((totalRecs - 1) != 0)
{
string nextrec = holdLine.Substring(startread, 276);
HOM_CO_ID = nextrec.Substring(0, 5);
HOM_PROD_CODE = nextrec.Substring(5, 3);
HOM_ACCT_TYPE = nextrec.Substring(8, 1);
HOM_BRANCH = nextrec.Substring(9, 6);
HOM_ACCOUNT_NO = nextrec.Substring(15, 23);
HOM_BUDGET_NO = nextrec.Substring(38, 5);
HOM_ACCOUNT_NAME = nextrec.Substring(43, 30);
HOM_AMOUNT = nextrec.Substring(73, 17);
HOM_REF = nextrec.Substring(90, 20);
HOM_DESCR = nextrec.Substring(110, 47);
HOM_TRAN_CODE = nextrec.Substring(157, 5);
HOM_REVERSAL_DESCR = nextrec.Substring(162, 47);
NOM_REF2 = nextrec.Substring(209, 20);
NOM_DESCRIPTION = nextrec.Substring(229, 47);
txtHomCompId.Text = HOM_CO_ID;
txtHomProdCode.Text = HOM_PROD_CODE;
txtHomAccountType.Text = HOM_ACCT_TYPE;
txtHomBranch.Text = HOM_BRANCH;
txtHomAccNo.Text = HOM_ACCOUNT_NO;
txtHomBudgetNo.Text = HOM_BUDGET_NO;
txtHomAccName.Text = HOM_ACCOUNT_NAME;
txtHomAmount.Text = HOM_AMOUNT;
txtHomRef.Text = HOM_REF;
txtHomDescr.Text = HOM_DESCR;
txtHomTranCode.Text = HOM_TRAN_CODE;
txtHomRevDescr.Text = HOM_REVERSAL_DESCR;
txtNomRef2.Text = NOM_REF2;
txtNomDescr2.Text = NOM_DESCRIPTION;
validateMessage();
totalRecs--;
startread = lastread + 276;
}
}
Excellence is doing ordinary things extraordinarily well.
|
|
|
|
|
I'd create two class members (class variables) of type
- List<String> records
- int recordIndex
In the button2_Click I'd test to see if records collection is null;
If null I'd read the text from file and add each record as a string to the records collection.
I'd then reference the string in the records collection at the recordIndex. Extract the values from the string, set the text control values and increment to recordIndex by one.
You might want to dispose of that Streamreader as well, once finished.
sr.Dispose();
"You get that on the big jobs."
|
|
|
|
|
Well, it seems to me that this line
int startIndex = 463;
is where the problem lies. You should make startIndex a class level variable, then when you finished reading a record you increment this by 276. Personally, I would create a separate class that holds a complete transaction, and then read the file only once, populating a List of such transactions as I went along. Then you can just navigate through the list, backwards and forwards as you wish.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
If it's only 50 records you should parse and read the entire file into a List<Record>, where a Record is a data holding class which is populated in a similar way to your code here, at the start. Working with a proper domain object with properties is much better than working with a string format the whole time.
To read all the records you do something like
List<Record> GetRecords(string s){
List<Record> r = new List<Record>();
ReadHeader(s.Substring(0, HEADER_LENGTH));
s = s.Substring(HEADER_LENGTH);
while(s.Length > 0){
string recordstr = s.Substring(0, RECORD_LENGTH);
s = s.Substring(RECORD_LENGTH);
Record rec = new Record();
rec.CO_ID = recordstr.Substring(0, 5);
r.Add(rec);
}
return r;
}
ed: HEADER_LENGTH = 463 and RECORD_LENGTH = 276.
|
|
|
|
|
I'm trying to have a timer countdown and once it reaches 0 it would move a value from one gridview to another. The build crashes once it reaches 0 and says something about not being able to change controls on different threads. I did some research and they say I need to Invoke? or create a BackgroundWorker?
System.Threading.Timer timer;
int time = 30;
timer = new System.Threading.Timer(new TimerCallback(timerCallback),
null, 0, 1000);
public void timerCallback(Object obj)
{
else
{
timer = 0;
moveToGrid(grid1, grid2);
}
}
The moveToGrid method works fine if I put it in an onClick event but the build crashes when put as shown above. Can anyone point me in the right direction?
|
|
|
|
|
You are going to have to check if invoke is required in the moveToGrid method, something like this:-
void MoveToGrid(DataGridView grid1, DataGridView grid2)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MethodInvoker(() => MoveToGrid(grid1, grid2)));
}
else
{
}
}
Hope this helps
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
That worked great! Thanks a bunch. At first I didn't think it was going to work because the way I have it set up. Just had to check if invoke was required on two separate methods and worked like a charm.
|
|
|
|
|
Glad to help.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
You may want to read this article[^] on GUI Controls and threads.
The easiest approach could be using the right timer: Windows.Forms.Timer s tick on the GUI thread...
|
|
|
|
|
Yes, for this sort of purely UI related thing I recommend using the Windows.Forms.Timer. It is less accurate, but on a level that you don't care about, and its events go through the normal UI thread message queue.
|
|
|
|
|
I'll have to look into this then. Still learning so anything new is good.
|
|
|
|
|
The timer is being executed on a separate thread, no you didn't create one, it was done for you by the Timer object, but the UI can only be updated from the main thread. You need the Invoke to call the main UI thread and update the grids, as Wayne responded.
No comment
|
|
|
|
|
Respected Sir,
Sir tell me the Way that How I can Create Classic Menu in C# desktop apll. Which fell like flash, & application become attractive - Devdatta
|
|
|
|
|
Umm... what? You want a MainMenu (like I do)?
Either add it dynamically or add it to the toolbox (if using VS or whatever).
For VS: right-click the toolbox, select add items (or whatever it is), find the Main Menu, select it.
|
|
|
|
|
hi im building a app for dtg printers to print a white underbase i have built the app in c# i no a bad choice for photo editing but time is the key here
bassicly what i need atm i have a button to invert a png and change the contrast so it changes the hole image to black what im looking to do is to shrink the pixels of the end of the image by one pixel all the way around the image btw its a transparent png so only the vissible pixxels need reducing
i hope you can understand this
|
|
|
|
|
Member 7738561 wrote: i hope you can understand this
You could help that by not using txtspk.
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Peter_in_2780 wrote: You could help that by not using txtspk.
...or by using punctuation.
"I love deadlines. I like the whooshing sound they make as they fly by." (DNA)
|
|
|
|
|
Are you speaking of a situation in which you have a png file with transparency: and you want to produce, for multi-color printing, a separation plate that contains all the 'transparent' pixels in the .png file, with the idea that those transparent pixels will be rendered in white on that plate ?
And then you want to trim the boundaries of that plate only ?
Even if that is the scenario you describe here, it doesn't make a lot of sense to me. By the way, I've written color-separation software for Adobe products in the past, and am quite familiar with what's involved with complex color-separation scenarios involving both CMYK plates, and spot-colors, custom varnish overlay plates, etc.
best, Bill
"I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." Bjarne Stroustrop circa 1990
|
|
|
|