Dhivya
Dhivya

Reputation: 9

Convert StringBuilder to Secure String

I am trying to encrypt and decrypt my connection string. Below is the code used to encrypt. When I code underwent SSA Fortify, I get the error as below.

xyz.cs stores sensitive data in an insecure manner, making it possible to extract the data via inspecting the heap.

public static int GetSaltSize(byte[] pBytes)
{
      var key = new Rfc2898DeriveBytes(pBytes, pBytes, 1000);
      byte[] ba = key.GetBytes(2);
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < ba.Length; i++)
      {
        sb.Append(Convert.ToInt32(ba[i]).ToString());
      }
      int saltSize = 0;
      string s = sb.ToString();   // <--- insecure?
      foreach (char c in s)
      {
        int intc = Convert.ToInt32(c.ToString());
        saltSize = saltSize + intc;
      }
      return saltSize;
}

Please let me know if we can convert StringBuilder to SecureString or what can be the solution.

Upvotes: 0

Views: 1164

Answers (2)

Camilo Terevinto
Camilo Terevinto

Reputation: 32068

Your attempt to not have the values in memory is worse than not having tried at all to secure it, since you are not storing the int once in memory but rather three times:

  • First time: sb.Append(Convert.ToInt32(ba[i]).ToString());
  • Second time: sb.ToString();
  • Third time: Convert.ToInt32(c.ToString());

So you have each value twice and the complete sentence once.


Since the salt does not need to be secret, and hence doesn't its length either, your code should only be:

public static int GetSaltSize(byte[] pBytes)
{
    var key = new Rfc2898DeriveBytes(pBytes, pBytes, 1000);
    byte[] ba = key.GetBytes(2);
    return ba.SelectMany(x => ((int)x).ToString().ToCharArray()).Sum();
}

Upvotes: 2

Remus Rusanu
Remus Rusanu

Reputation: 294307

There is the dedicated SecureString class for storing sensitive data in memory. I guess your code is adding salt size as a header to some serialized representation. You should not do this, use instead DPAPI via ProtectedData class, which can store securely your connection strings and other sensitive information.

When it comes to using the sensitive connection string, I will speculate a bit assuming we're talking about a database connection string (eg. SqlConnection). Then the .Net connection API does not expose a secure method to initialize credentials. Username/password must be presented to database connection classes in plain text. If you're talking about a SQL Server connection, you should use integrated authentication, which does not require any sensistive information in the connection string.

Upvotes: 2

Related Questions