Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Visual Basic
  4. Securing Local Files [Solved]

Securing Local Files [Solved]

Scheduled Pinned Locked Moved Visual Basic
securitycsharphelp
20 Posts 8 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Saul Johnson

    Very sensible idea there, and very true about the sensitive data. If the point of my application is to search through and display said sensitive data then it would be impossible to completely secure for that very reason. Thank you for your reply, this seems like a better way to go about it and is well worth testing out. :D

    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.

    L Offline
    L Offline
    Lost User
    wrote on last edited by
    #6

    You're welcome :)

    1 Reply Last reply
    0
    • S Saul Johnson

      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. 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.

      J Offline
      J Offline
      James H
      wrote on last edited by
      #7

      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

      S 1 Reply Last reply
      0
      • S Saul Johnson

        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. 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.

        S Offline
        S Offline
        Stephane Rivette At Motion
        wrote on last edited by
        #8

        Why not use Isolated storage, it's encrypted to the user and no one else using the computer can get to it. http://msdn.microsoft.com/en-us/library/3ak841sy%28v=VS.95%29.aspx[^]

        L 1 Reply Last reply
        0
        • A AspDotNetDev

          Not the answer you're going to want to hear, but it can't really be done. If you really want it to be secure, you'll have to require the user to enter a master password. Other popular programs do this too. Typically, you will be given the option of encrypting multiple passwords using one master password (most secure) or encrypting the passwords using a built-in key (which would be stored in plain text somewhere). You could also use multiple layers of indirection (e.g., a config setting that points to a file that stores the path the encryption key is stored in) to make it harder for somebody to obtain the encryption key, but it's not really any more secure (just harder to access).

          Thou mewling ill-breeding pignut!

          D Offline
          D Offline
          dcu lcr
          wrote on last edited by
          #9

          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

          L 1 Reply Last reply
          0
          • S Stephane Rivette At Motion

            Why not use Isolated storage, it's encrypted to the user and no one else using the computer can get to it. http://msdn.microsoft.com/en-us/library/3ak841sy%28v=VS.95%29.aspx[^]

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #10

            If the app can access it (required, otherwise it could not use the data), then so can I :)

            Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]

            1 Reply Last reply
            0
            • D dcu lcr

              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

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #11

              ..and there is me reading the file, and shouting your password in the streets. Any other solutions?

              Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]

              D 1 Reply Last reply
              0
              • S Saul Johnson

                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. 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.

                B Offline
                B Offline
                BrainiacV
                wrote on last edited by
                #12

                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.

                S 1 Reply Last reply
                0
                • L Lost User

                  ..and there is me reading the file, and shouting your password in the streets. Any other solutions?

                  Bastard Programmer from Hell :suss: if you can't read my code, try converting it here[^]

                  D Offline
                  D Offline
                  dcu lcr
                  wrote on last edited by
                  #13

                  ...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

                  L 1 Reply Last reply
                  0
                  • D dcu lcr

                    ...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

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #14

                    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[^]

                    1 Reply Last reply
                    0
                    • S Saul Johnson

                      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. 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.

                      O Offline
                      O Offline
                      ObiWan_MCC
                      wrote on last edited by
                      #15

                      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

                      O S 2 Replies Last reply
                      0
                      • O ObiWan_MCC

                        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

                        O Offline
                        O Offline
                        ObiWan_MCC
                        wrote on last edited by
                        #16

                        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

                        1 Reply Last reply
                        0
                        • O ObiWan_MCC

                          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

                          S Offline
                          S Offline
                          Saul Johnson
                          wrote on last edited by
                          #17

                          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.

                          O 1 Reply Last reply
                          0
                          • B BrainiacV

                            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.

                            S Offline
                            S Offline
                            Saul Johnson
                            wrote on last edited by
                            #18

                            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.

                            1 Reply Last reply
                            0
                            • J James H

                              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

                              S Offline
                              S Offline
                              Saul Johnson
                              wrote on last edited by
                              #19

                              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.

                              1 Reply Last reply
                              0
                              • S Saul Johnson

                                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.

                                O Offline
                                O Offline
                                ObiWan_MCC
                                wrote on last edited by
                                #20

                                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)

                                1 Reply Last reply
                                0
                                Reply
                                • Reply as topic
                                Log in to reply
                                • Oldest to Newest
                                • Newest to Oldest
                                • Most Votes


                                • Login

                                • Don't have an account? Register

                                • Login or register to search.
                                • First post
                                  Last post
                                0
                                • Categories
                                • Recent
                                • Tags
                                • Popular
                                • World
                                • Users
                                • Groups