I have a ASP.Net C# application that needs to connect to an external API using WebServices every 5 minutes.
The requirements of the External Webservice are as follows:
I have built all of the previous, but I currently have one issue. What is the best practice for storing the current and historical passwords?
Obviously storing the plaintext password is a bad solution. I need to be able to have my webservice read the password and transmit it with each request. I also need to be able to access all of the historical passwords to make sure that my newly generated password is not a duplicate.
Ideally, I would like to store each (encrypted) password in my database and decrypt it whenever I need to call the webservice. Is there a best practice I should be following? Should I encrypt each password using Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Cryptographer.EncryptSymmetric(..)?
Note: Unfortunately, I have no access to change the way the external API functions. I must follow the rules provided.
HMAC Authentication is common for securing public APIs whereas Digital Signature is suitable for server-to-server two way communication. OAuth on the other hand is useful when you need to restrict parts of your API to authenticated users only.
With regard to the password history I would go down one of two routes:
As per your current plan, store passwords in file/db/config - suggest you use a hashing algorithm (as opposed to encryption) to compare the new password with stored password hashes for "equality".
Don't bother storing password history at all - let the first attempt to the password change web service just fail if it chooses too, then resend with an alternative password. This way, you are not duplicating the business rules of the password change web service (for example, lets say they change it to allow you to re-use a password after 6 months time).
With regard to storing the current password: assuming you must send the password as plaintext, then yes, you should store it in encrypted form. There are many articles out there on how to do this. Or you could even encrypt a specific section of your config file such as seen here.
The easiest way... use the ProtectedData class:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.aspx
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(password);
byte[] cypher = ProtectedData.Protect(data, null, DataProtectionScope.CurrentUser);
//... reverse
byte[] bytes = ProtectedData.Unprotect(cypher, null, DataProtectionScope.CurrentUser);
string password = System.Text.Encoding.UTF8.GetString(bytes);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With