Securing Local Files [Solved]
-
actually you can. The solution, however, is in using a .NET secure string for the password and store the secure string in a file. Take a look(bing it) at how to use secure strings with powershell, if you're using win 7 then it should be a piece of cake.
L. Carlos Rodriguez DCU, LLC Braselton, GA 30517
-
Hello, My VB.NET application currently securely downloads a username and password required to access a web service that contains sensitive data. The problem I face now is storing that username and password on-disk in a secure manner for future use. I've looked into various encryption algorithms etc. but all involve storing some kind of key for decryption locally (rendering the encryption a bit of a joke) or hard-coding the key into the application (difficult-to-maintain and just about as useful as the last option). I welcome any suggestions as to how relatively secure local storage of a username and password might be accomplished. Despite hours of wracking my brains poking about in the
System.Security.Cryptography
namespace I'm no closer to finding a solution than I was at the start. SixOfTheClockA programming language is to a programmer what a fine hat is to one who is fond of fancy garden parties. Just don't try wearing any .NET language on your head. Some of them are sharp.
Not sure if this will help, Back in the early days of microcomputers, some publishers tried to encrypt their programs to keep them from being pirated. After you entered a key, a subroutine would be called to decrypt the code. The sneaky bit was that right after the subroutine call, there was additional code, but, the program never reached it. Part of the decryption overlaid the system stack and so the subroutine return went someplace else, rather than the legitimate looking code that followed the decryption. So I guess in a long winded way, I am suggesting the use of misdirection in addition to the indirection that has been suggested above. And then repeat. It won't stop them, but it could really slow them down.
Psychosis at 10 Film at 11 Those who do not remember the past, are doomed to repeat it. Those who do not remember the past, cannot build upon it.
-
...there's nothing better than making passwords public so you can shout them to the world, that's why we use the.NET secure string functionality for batch files protections at both the DOL and Treasury. But then again, this is the government and we don't know what we're doing.... :doh: Sorry I led you in the wrong path.... :(( Good luck
-
...there's nothing better than making passwords public so you can shout them to the world, that's why we use the.NET secure string functionality for batch files protections at both the DOL and Treasury. But then again, this is the government and we don't know what we're doing.... :doh: Sorry I led you in the wrong path.... :(( Good luck
dcu.lcr wrote:
...there's nothing better than making passwords public so you can shout them to the world, that's why we use the.NET secure string functionality for batch files protections at both the DOL and Treasury.
For batch files? :doh: Let me rephrase that; any secret that's stored, isn't.
dcu.lcr wrote:
But then again, this is the government and we don't know what we're doing.... :doh:
You working for the government is not an argument, nor does it validate your statement.
Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]
-
Hello, My VB.NET application currently securely downloads a username and password required to access a web service that contains sensitive data. The problem I face now is storing that username and password on-disk in a secure manner for future use. I've looked into various encryption algorithms etc. but all involve storing some kind of key for decryption locally (rendering the encryption a bit of a joke) or hard-coding the key into the application (difficult-to-maintain and just about as useful as the last option). I welcome any suggestions as to how relatively secure local storage of a username and password might be accomplished. Despite hours of wracking my brains poking about in the
System.Security.Cryptography
namespace I'm no closer to finding a solution than I was at the start. SixOfTheClockA programming language is to a programmer what a fine hat is to one who is fond of fancy garden parties. Just don't try wearing any .NET language on your head. Some of them are sharp.
I think you're approaching the issue the wrong way, see, you DON'T need to know the password (nor to store it); all you need to do is checking that it is correct For such a task, all you'll need will be using an MD5 "salted" hash; just to be clear, let's say you have the following code
// generates the unique (salted) hash of a string
private static string getKey(string sSalt, string sKey)
{
Byte[] originalBytes, encodedBytes;
MD5 hash = new MD5CryptoServiceProvider();
// or: SHA256 hash = new SHA256CryptoServiceProvider();// generate the hash value originalBytes = ASCIIEncoding.Default.GetBytes(sSalt + "." + sKey); encodedBytes = hash.ComputeHash(originalBytes); // turn the hash to a string and return it string sResult = BitConverter.ToString(encodedBytes).Replace("-", ""); // or: string sResult = Convert.ToBase64String(encodedBytes); return sResult;
}
now, in your login form, you ask to enter a username and a password, let's say you get back "jdoe" and "supersecret", at this point, you just call the above function this way
string hashValue = getKey(userName, userPass);
and the hashvalue will now contain something like "752dcc62c07fb4652981add596e1427b" now, with this value in your hands, you run a query on your database user table seeking for the user name (jdoe) and, if found, you compare the salted MD5 hash stored as the password with the one you just generated and, if they match, you grant access to the user. At this point, in case you need to use the password "in clear", you may just encrypt the password you received and store it into a session cookie, this will give you VOLATILE (temporary) storage and, while it will allow you to retrieve the password for the session lifetime, you won't in reality store the password anywhere on your server and... retrieving a password from a salted hash isn't exactly an easy task, believe me :) HTH
-
I think you're approaching the issue the wrong way, see, you DON'T need to know the password (nor to store it); all you need to do is checking that it is correct For such a task, all you'll need will be using an MD5 "salted" hash; just to be clear, let's say you have the following code
// generates the unique (salted) hash of a string
private static string getKey(string sSalt, string sKey)
{
Byte[] originalBytes, encodedBytes;
MD5 hash = new MD5CryptoServiceProvider();
// or: SHA256 hash = new SHA256CryptoServiceProvider();// generate the hash value originalBytes = ASCIIEncoding.Default.GetBytes(sSalt + "." + sKey); encodedBytes = hash.ComputeHash(originalBytes); // turn the hash to a string and return it string sResult = BitConverter.ToString(encodedBytes).Replace("-", ""); // or: string sResult = Convert.ToBase64String(encodedBytes); return sResult;
}
now, in your login form, you ask to enter a username and a password, let's say you get back "jdoe" and "supersecret", at this point, you just call the above function this way
string hashValue = getKey(userName, userPass);
and the hashvalue will now contain something like "752dcc62c07fb4652981add596e1427b" now, with this value in your hands, you run a query on your database user table seeking for the user name (jdoe) and, if found, you compare the salted MD5 hash stored as the password with the one you just generated and, if they match, you grant access to the user. At this point, in case you need to use the password "in clear", you may just encrypt the password you received and store it into a session cookie, this will give you VOLATILE (temporary) storage and, while it will allow you to retrieve the password for the session lifetime, you won't in reality store the password anywhere on your server and... retrieving a password from a salted hash isn't exactly an easy task, believe me :) HTH
forgot; as for encrypting/decrypting, you may use the following code (not mine, but I'm sorry to say I don't remember where I found it)
// Encrypt the given string using AES. The string can be decrypted using
// DecryptString(). The sharedSecret parameters must match.
public string EncryptString(string plainText, string sharedSecret)
{
if (string.IsNullOrEmpty(plainText))
throw new ArgumentNullException("plainText");
if (string.IsNullOrEmpty(sharedSecret))
throw new ArgumentNullException("sharedSecret");string outStr = null; // Encrypted string to return RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data. try { // generate the key from the shared secret and the salt Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, this.\_salt); // Create a RijndaelManaged object aesAlg = new RijndaelManaged(); aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); // Create a decrytor to perform the stream transform. ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new MemoryStream()) { // prepend the IV 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)) { //Write all data to the stream. swEncrypt.Write(plainText); } } outStr = Convert.ToBase64String(msEncrypt.ToArray()); } } finally { // Clear the RijndaelManaged object. if (aesAlg != null) aesAlg.Clear(); } // Return the encrypted bytes from the memory stream. return outStr;
}
// Decrypt the given string. Assumes the string was encrypted using
// EncryptString(), using an identical sharedSecret.
public string DecryptString(string cipherText, string sharedSecret)
{
if (string.IsNullOrEmpty(cipherText))
throw new ArgumentNullException("cipherText");
if (string.IsNullOrEmpty(sharedSecret))
throw new ArgumentNullException("shar -
I think you're approaching the issue the wrong way, see, you DON'T need to know the password (nor to store it); all you need to do is checking that it is correct For such a task, all you'll need will be using an MD5 "salted" hash; just to be clear, let's say you have the following code
// generates the unique (salted) hash of a string
private static string getKey(string sSalt, string sKey)
{
Byte[] originalBytes, encodedBytes;
MD5 hash = new MD5CryptoServiceProvider();
// or: SHA256 hash = new SHA256CryptoServiceProvider();// generate the hash value originalBytes = ASCIIEncoding.Default.GetBytes(sSalt + "." + sKey); encodedBytes = hash.ComputeHash(originalBytes); // turn the hash to a string and return it string sResult = BitConverter.ToString(encodedBytes).Replace("-", ""); // or: string sResult = Convert.ToBase64String(encodedBytes); return sResult;
}
now, in your login form, you ask to enter a username and a password, let's say you get back "jdoe" and "supersecret", at this point, you just call the above function this way
string hashValue = getKey(userName, userPass);
and the hashvalue will now contain something like "752dcc62c07fb4652981add596e1427b" now, with this value in your hands, you run a query on your database user table seeking for the user name (jdoe) and, if found, you compare the salted MD5 hash stored as the password with the one you just generated and, if they match, you grant access to the user. At this point, in case you need to use the password "in clear", you may just encrypt the password you received and store it into a session cookie, this will give you VOLATILE (temporary) storage and, while it will allow you to retrieve the password for the session lifetime, you won't in reality store the password anywhere on your server and... retrieving a password from a salted hash isn't exactly an easy task, believe me :) HTH
Hello, Thank you for your answer. This is undoubtedly how I would go about authenticating passwords in any other circumstances but these, generating hashes using MD5 or (my personal preference) SHA-256. I am working with a web service from a Windows Forms application, and a password is required to work with this web service. Usually, I'd show a prompt and ask the user to input the password to authenticate when it starts, but the user requirements state that users must not need to enter any sort of authentication information in order to work with the application in the interest of ease-of-use. What I was looking for was a way to store this username and password locally in such a way that only my application would be able to access and use them. As it seems that this isn't really possible, I've put in place stricter controls and guidelines for where and when the software can be used and used misdirection and obfuscation as suggested by previous answers to make it more difficult for these credentials to be stolen. However, as you correctly say, the only way to really keep a password safe it to authenticate against its hash. SixOfTheClock
A programming language is to a programmer what a fine hat is to one who is fond of fancy garden parties. Just don't try wearing any .NET language on your head. Some of them are sharp.
-
Not sure if this will help, Back in the early days of microcomputers, some publishers tried to encrypt their programs to keep them from being pirated. After you entered a key, a subroutine would be called to decrypt the code. The sneaky bit was that right after the subroutine call, there was additional code, but, the program never reached it. Part of the decryption overlaid the system stack and so the subroutine return went someplace else, rather than the legitimate looking code that followed the decryption. So I guess in a long winded way, I am suggesting the use of misdirection in addition to the indirection that has been suggested above. And then repeat. It won't stop them, but it could really slow them down.
Psychosis at 10 Film at 11 Those who do not remember the past, are doomed to repeat it. Those who do not remember the past, cannot build upon it.
Hello, That's a very clever suggestion that I certainly wouldn't have thought of, and I'll undoubtedly be looking into it. Thank you very much indeed. SixOfTheClock
A programming language is to a programmer what a fine hat is to one who is fond of fancy garden parties. Just don't try wearing any .NET language on your head. Some of them are sharp.
-
Whatever method you use I also like to have a set of "red herring" credentials - that looks likes a password, - e.g. config setting Password with some cyrptic looking string that could be an encrypted string - sends the b'rs of on a wild goose chase
Another way to make things that little bit more difficult to figure out for anyone with mischief on their mind. Excellent thank you. SixOfTheClock
A programming language is to a programmer what a fine hat is to one who is fond of fancy garden parties. Just don't try wearing any .NET language on your head. Some of them are sharp.
-
Hello, Thank you for your answer. This is undoubtedly how I would go about authenticating passwords in any other circumstances but these, generating hashes using MD5 or (my personal preference) SHA-256. I am working with a web service from a Windows Forms application, and a password is required to work with this web service. Usually, I'd show a prompt and ask the user to input the password to authenticate when it starts, but the user requirements state that users must not need to enter any sort of authentication information in order to work with the application in the interest of ease-of-use. What I was looking for was a way to store this username and password locally in such a way that only my application would be able to access and use them. As it seems that this isn't really possible, I've put in place stricter controls and guidelines for where and when the software can be used and used misdirection and obfuscation as suggested by previous answers to make it more difficult for these credentials to be stolen. However, as you correctly say, the only way to really keep a password safe it to authenticate against its hash. SixOfTheClock
A programming language is to a programmer what a fine hat is to one who is fond of fancy garden parties. Just don't try wearing any .NET language on your head. Some of them are sharp.
I see; given your situation there may be another possible solution; assuming that the webservice you're calling is hosted on a different box (or instance), and given that you don't have the code for the service, you may create your own webservice app, embed the user credentials into such an app and install it on the same (or another) box/instance where the regular webservice lives, this way, your webservice will act as a "proxy" so that your winforms app will call your webservice w/o any credentials and the latter will act as a "proxy" to the real webservice (and will pass it the needed credentials)