1

I am generating an encrypted message using .NET. As part of this process I am generating a salt value that is used in the encryption process and also transmitted to the recipient of the encrypted message so that they may decrypt the message. I want to transmit the salt as a text string but when I try to convert the salt byte array to a String I get each byte separated by a "dash". For example ..

45-A1-99-0C-C0-0C-C2-C2

Here is the method that generates the salt ..

Public Shared Function GenerateSalt() As String
  Dim rng As New RNGCryptoServiceProvider()
  Dim buffer As Byte() = New Byte(7) {}

  rng.GetBytes(buffer)
  Return BitConverter.ToString(buffer)
End Function

My question is this. How do I represent the salt as a string that the recipient can use in their decryption process?

webworm
  • 10,587
  • 33
  • 120
  • 217
  • What format does the recipient need in order to use it in their decryption process? – LukeH Mar 29 '11 at 14:08
  • I cannot say for certain as I do not know what system the recipient is going to be using to decrypt other than it is AES 128 bit. I would like to present them with a salt value as String. – webworm Mar 29 '11 at 14:21
  • 1
    They should be able to deal with pretty-much any standard string: the output of `BitConverter` should be ok, although perhaps `BitConverter.ToString(buffer).Replace("-","").ToLower()` would be more standard. – LukeH Mar 29 '11 at 14:29
  • @LukeH - If I replace the dashes with empty spaces wouldn't that alter the value of the salt? When the recipient goes to convert the string representation of the salt into an array of bytes it would not be the same input I used for encryption. I could be wrong though. – webworm Mar 29 '11 at 14:44

3 Answers3

4

The easiest way is to use Convert.ToBase64String method for converting a byte array to string and Convert.FromBase64String for vise versa, e.g.

var salt = new byte[] { 1, 2, 4, 8, 16, 32, 64, 128, 255 };
var s = Convert.ToBase64String(salt);
var b = Convert.FromBase64String(s);

in this example s variable holds value AQIECBAgQID/, b holds byte array { 1, 2, 4, 8, 16, 32, 64, 128, 255 }, so nothing was lost.

Yes, the length of the s string and the length of the salt array are differs. This is because BASE64 is used here (it has 64 symbol alphabet, although byte may hold 256 different values).

But if you want to convert your byte array to a hexadecimal string and vise versa you could find this question helpful: How do you convert Byte Array to Hexadecimal String, and vice versa, in C#?.

Community
  • 1
  • 1
Oleks
  • 31,955
  • 11
  • 77
  • 132
  • I tried using the Convert.ToBase64String method but I ended up with a String of twelve characters. I was expecting eight, and I always end up with an "=" at the end. Here is an example. Using `BitConverter.ToString` yeilds "34-B4-5B-72-C5-A7-32-51", but using `Convert.ToBase64String` yields "NLRbcsWnMlE=" – webworm Mar 29 '11 at 13:53
  • Since you can go from plain text to bytes using `Encoding.Default.GetBytes()` how does one go from an array of bytes back to plain text? – webworm Mar 29 '11 at 16:24
  • @webworm, yep in most cases. But it would be safer to use `Encoding.GetEncoding(1252)` which represents the code page Western European (Windows). It is because some East Asian codepages use multiple-byte-per-character encoding. – Oleks Mar 29 '11 at 17:31
2

Maybe System.Convert.ToBase64String is a possible option. System.Convert.FromBase64String converts the encoded string back.

lafe
  • 111
  • 1
  • 2
  • That might be my best option. No matter what language they are using it should have way to convert from a Base64 String. I would just have to notify the recipient that the salt is encoded in Base64. – webworm Mar 29 '11 at 14:45
1

This may help:

public static string CreateRandomPassword(int PasswordLength)
{
  String _allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ23456789";
  Byte[] randomBytes = new Byte[PasswordLength];
  RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
  rng.GetBytes(randomBytes);
  char[] chars = new char[PasswordLength];
  int allowedCharCount = _allowedChars.Length;

  for(int i = 0;i<PasswordLength;i++)
  {
    chars[i] = _allowedChars[(int)randomBytes[i] % allowedCharCount];
  }

  return new string(chars);
}
FreeAsInBeer
  • 12,937
  • 5
  • 50
  • 82