Byte array to string and back - newbie question

Ask a Question related to ASP.NET Security, Design and Development.

  1. #1

    Default Byte array to string and back - newbie question

    Hi,

    I am trying to implement DES algorithm as described in the Microsoft article at
    [url]http://msdn.microsoft.com/library/en-us/dnnetsec/html/SecNetHT10.asp[/url].

    The problem is that I need to save the data in the database as String, and for that I have to convet from Byte array to string and back.

    When I cast a byte array into a string and then back to a byte array, I don't get the same array. For example:


    Dim SecretText As Byte()
    Dim SecretText1 As Byte()
    Dim Text as string
    ......
    SecretText = enc.Encrypt(Data, Key, Vector) 'returns Byte Array
    Text = Encoding.ASCII.GetString(SecretText) 'convert to string in order to save into the DB
    .....
    .....
    .....
    SecretText1 = Encoding.ASCII.GetBytes(Text) 'prepare for decryption routine



    At the end, SecretText1 does NOT equal to SecretText, and I want it to be. How should I do the conversion correctly?

    Thanks!!!

    Zhenya
    [url]http://www.rusmex.com[/url]
    popsovy@rusmex.com Guest

  2. Similar Questions and Discussions

    1. newbie array question
      Hi All Im new to php and are getting a bit confused about the sybase_fetch_array function (i think that this is the same as mysql_fetch_array?). ...
    2. Last number in the array --- access problem --Newbie question
      Here is the complete problem: I have two files MAER_FILE and EVAL_FILE MAER_FILE contains ITR Max_error Avg_error Min_error...
    3. array access problem - newbie question
      #-------------code----------# open (MAER_FILE, "MAER_output.txt"); while (<MAER_FILE>) { chomp; my @maer_array = split(/\t/); print...
    4. Newbie: How do I return a single/string array?
      I am returning a type-single array (x,y) from a component through a property. I am converting the array to variant before passing it back, using...
    5. Problem converting array string back to numeric
      I'm afraid I don't know enough about your situation to help. How are you sending your values to ASP? It sounds to me like this is more like an ASP...
  3. #2

    Default Re: Byte array to string and back - newbie question


    I suggest you use Convert.ToBase64String instead (and
    Convert.FromBase64String to reverse the process).



    Mattias

    --
    Mattias Sjögren [MVP] mattias @ mvps.org
    [url]http://www.msjogren.net/dotnet/[/url] | [url]http://www.dotnetinterop.com[/url]
    Please reply only to the newsgroup.
    Mattias Sjögren Guest

  4. #3

    Default Re: Byte array to string and back - newbie question

    Actually, this might help you a LOT. I didn't write this, and I don't seem
    to have bookmarked where it came from, but this class works GREAT and it's
    SUPER documented so you can disect what he's doing. It includes functions
    to encode and decode with any options you can dream. Just snip below the
    line and you're set...

    ------------------------------------------------

    using System;

    using System.IO;

    using System.Security.Cryptography;

    namespace perfClientConfig

    {

    /// <summary>

    /// Summary description for EncDec.

    /// </summary>

    //

    // Sample encrypt/decrypt functions

    // Parameter checks and error handling are ommited for better readability

    //

    public class EncDec

    {

    // Encrypt a byte array into a byte array using a key and an IV

    public static byte[] Encrypt(byte[] clearData, byte[] Key, byte[] IV)

    {

    // Create a MemoryStream that is going to accept the encrypted bytes

    MemoryStream ms = new MemoryStream();

    // Create a symmetric algorithm.

    // We are going to use Rijndael because it is strong and available on all
    platforms.

    // You can use other algorithms, to do so substitute the next line with
    something like

    // TripleDES alg = TripleDES.Create();

    Rijndael alg = Rijndael.Create();

    // Now set the key and the IV.

    // We need the IV (Initialization Vector) because the algorithm is operating
    in its default

    // mode called CBC (Cipher Block Chaining). The IV is XORed with the first
    block (8 byte)

    // of the data before it is encrypted, and then each encrypted block is
    XORed with the

    // following block of plaintext. This is done to make encryption more
    secure.

    // There is also a mode called ECB which does not need an IV, but it is much
    less secure.

    alg.Key = Key;

    alg.IV = IV;

    // Create a CryptoStream through which we are going to be pumping our data.

    // CryptoStreamMode.Write means that we are going to be writing data to the
    stream

    // and the output will be written in the MemoryStream we have provided.

    CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(),
    CryptoStreamMode.Write);

    // Write the data and make it do the encryption

    cs.Write(clearData, 0, clearData.Length);

    // Close the crypto stream (or do FlushFinalBlock).

    // This will tell it that we have done our encryption and there is no more
    data coming in,

    // and it is now a good time to apply the padding and finalize the
    encryption process.

    cs.Close();

    // Now get the encrypted data from the MemoryStream.

    // Some people make a mistake of using GetBuffer() here, which is not the
    right way.

    byte[] encryptedData = ms.ToArray();

    return encryptedData;

    }

    // Encrypt a string into a string using a password

    // Uses Encrypt(byte[], byte[], byte[])

    public static string Encrypt(string clearText, string Password)

    {

    // First we need to turn the input string into a byte array.

    byte[] clearBytes = System.Text.Encoding.Unicode.GetBytes(clearText);

    // Then, we need to turn the password into Key and IV

    // We are using salt to make it harder to guess our key using a dictionary
    attack -

    // trying to guess a password by enumerating all possible words.

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65,
    0x64, 0x65, 0x76});

    // Now get the key/IV and do the encryption using the function that accepts
    byte arrays.

    // Using PasswordDeriveBytes object we are first getting 32 bytes for the
    Key

    // (the default Rijndael key length is 256bit = 32bytes) and then 16 bytes
    for the IV.

    // IV should always be the block size, which is by default 16 bytes (128
    bit) for Rijndael.

    // If you are using DES/TripleDES/RC2 the block size is 8 bytes and so
    should be the IV size.

    // You can also read KeySize/BlockSize properties off the algorithm to find
    out the sizes.

    byte[] encryptedData = Encrypt(clearBytes, pdb.GetBytes(32),
    pdb.GetBytes(16));

    // Now we need to turn the resulting byte array into a string.

    // A common mistake would be to use an Encoding class for that. It does not
    work

    // because not all byte values can be represented by characters.

    // We are going to be using Base64 encoding that is designed exactly for
    what we are

    // trying to do.

    return Convert.ToBase64String(encryptedData);

    }

    // Encrypt bytes into bytes using a password

    // Uses Encrypt(byte[], byte[], byte[])

    public static byte[] Encrypt(byte[] clearData, string Password)

    {

    // We need to turn the password into Key and IV.

    // We are using salt to make it harder to guess our key using a dictionary
    attack -

    // trying to guess a password by enumerating all possible words.

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65,
    0x64, 0x65, 0x76});

    // Now get the key/IV and do the encryption using the function that accepts
    byte arrays.

    // Using PasswordDeriveBytes object we are first getting 32 bytes for the
    Key

    // (the default Rijndael key length is 256bit = 32bytes) and then 16 bytes
    for the IV.

    // IV should always be the block size, which is by default 16 bytes (128
    bit) for Rijndael.

    // If you are using DES/TripleDES/RC2 the block size is 8 bytes and so
    should be the IV size.

    // You can also read KeySize/BlockSize properties off the algorithm to find
    out the sizes.

    return Encrypt(clearData, pdb.GetBytes(32), pdb.GetBytes(16));

    }

    // Encrypt a file into another file using a password

    public static void Encrypt(string fileIn, string fileOut, string Password)

    {

    // First we are going to open the file streams

    FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);

    FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate,
    FileAccess.Write);

    // Then we are going to derive a Key and an IV from the Password and create
    an algorithm

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65,
    0x64, 0x65, 0x76});

    Rijndael alg = Rijndael.Create();

    alg.Key = pdb.GetBytes(32);

    alg.IV = pdb.GetBytes(16);

    // Now create a crypto stream through which we are going to be pumping data.

    // Our fileOut is going to be receiving the encrypted bytes.

    CryptoStream cs = new CryptoStream(fsOut, alg.CreateEncryptor(),
    CryptoStreamMode.Write);

    // Now will will initialize a buffer and will be processing the input file
    in chunks.

    // This is done to avoid reading the whole file (which can be huge) into
    memory.

    int bufferLen = 4096;

    byte[] buffer = new byte[bufferLen];

    int bytesRead;

    do

    {

    // read a chunk of data from the input file

    bytesRead = fsIn.Read(buffer, 0, bufferLen);

    // encrypt it

    cs.Write(buffer, 0, bytesRead);

    } while(bytesRead != 0);

    // close everything

    cs.Close(); // this will also close the unrelying fsOut stream

    fsIn.Close();

    }

    // Decrypt a byte array into a byte array using a key and an IV

    public static byte[] Decrypt(byte[] cipherData, byte[] Key, byte[] IV)

    {

    // Create a MemoryStream that is going to accept the decrypted bytes

    MemoryStream ms = new MemoryStream();

    // Create a symmetric algorithm.

    // We are going to use Rijndael because it is strong and available on all
    platforms.

    // You can use other algorithms, to do so substitute the next line with
    something like

    // TripleDES alg = TripleDES.Create();

    Rijndael alg = Rijndael.Create();

    // Now set the key and the IV.

    // We need the IV (Initialization Vector) because the algorithm is operating
    in its default

    // mode called CBC (Cipher Block Chaining). The IV is XORed with the first
    block (8 byte)

    // of the data after it is decrypted, and then each decrypted block is XORed
    with the previous

    // cipher block. This is done to make encryption more secure.

    // There is also a mode called ECB which does not need an IV, but it is much
    less secure.

    alg.Key = Key;

    alg.IV = IV;

    // Create a CryptoStream through which we are going to be pumping our data.

    // CryptoStreamMode.Write means that we are going to be writing data to the
    stream

    // and the output will be written in the MemoryStream we have provided.

    CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(),
    CryptoStreamMode.Write);

    // Write the data and make it do the decryption

    cs.Write(cipherData, 0, cipherData.Length);

    // Close the crypto stream (or do FlushFinalBlock).

    // This will tell it that we have done our decryption and there is no more
    data coming in,

    // and it is now a good time to remove the padding and finalize the
    decryption process.

    cs.Close();

    // Now get the decrypted data from the MemoryStream.

    // Some people make a mistake of using GetBuffer() here, which is not the
    right way.

    byte[] decryptedData = ms.ToArray();

    return decryptedData;

    }

    // Decrypt a string into a string using a password

    // Uses Decrypt(byte[], byte[], byte[])

    public static string Decrypt(string cipherText, string Password)

    {

    // First we need to turn the input string into a byte array.

    // We presume that Base64 encoding was used

    byte[] cipherBytes = Convert.FromBase64String(cipherText);

    // Then, we need to turn the password into Key and IV

    // We are using salt to make it harder to guess our key using a dictionary
    attack -

    // trying to guess a password by enumerating all possible words.

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65,
    0x64, 0x65, 0x76});

    // Now get the key/IV and do the decryption using the function that accepts
    byte arrays.

    // Using PasswordDeriveBytes object we are first getting 32 bytes for the
    Key

    // (the default Rijndael key length is 256bit = 32bytes) and then 16 bytes
    for the IV.

    // IV should always be the block size, which is by default 16 bytes (128
    bit) for Rijndael.

    // If you are using DES/TripleDES/RC2 the block size is 8 bytes and so
    should be the IV size.

    // You can also read KeySize/BlockSize properties off the algorithm to find
    out the sizes.

    byte[] decryptedData = Decrypt(cipherBytes, pdb.GetBytes(32),
    pdb.GetBytes(16));

    // Now we need to turn the resulting byte array into a string.

    // A common mistake would be to use an Encoding class for that. It does not
    work

    // because not all byte values can be represented by characters.

    // We are going to be using Base64 encoding that is designed exactly for
    what we are

    // trying to do.

    return System.Text.Encoding.Unicode.GetString(decryptedDa ta);

    }

    // Decrypt bytes into bytes using a password

    // Uses Decrypt(byte[], byte[], byte[])

    public static byte[] Decrypt(byte[] cipherData, string Password)

    {

    // We need to turn the password into Key and IV.

    // We are using salt to make it harder to guess our key using a dictionary
    attack -

    // trying to guess a password by enumerating all possible words.

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65,
    0x64, 0x65, 0x76});

    // Now get the key/IV and do the Decryption using the function that accepts
    byte arrays.

    // Using PasswordDeriveBytes object we are first getting 32 bytes for the
    Key

    // (the default Rijndael key length is 256bit = 32bytes) and then 16 bytes
    for the IV.

    // IV should always be the block size, which is by default 16 bytes (128
    bit) for Rijndael.

    // If you are using DES/TripleDES/RC2 the block size is 8 bytes and so
    should be the IV size.

    // You can also read KeySize/BlockSize properties off the algorithm to find
    out the sizes.

    return Decrypt(cipherData, pdb.GetBytes(32), pdb.GetBytes(16));

    }

    // Decrypt a file into another file using a password

    public static void Decrypt(string fileIn, string fileOut, string Password)

    {

    // First we are going to open the file streams

    FileStream fsIn = new FileStream(fileIn, FileMode.Open, FileAccess.Read);

    FileStream fsOut = new FileStream(fileOut, FileMode.OpenOrCreate,
    FileAccess.Write);

    // Then we are going to derive a Key and an IV from the Password and create
    an algorithm

    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,

    new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65,
    0x64, 0x65, 0x76});

    Rijndael alg = Rijndael.Create();

    alg.Key = pdb.GetBytes(32);

    alg.IV = pdb.GetBytes(16);

    // Now create a crypto stream through which we are going to be pumping data.

    // Our fileOut is going to be receiving the Decrypted bytes.

    CryptoStream cs = new CryptoStream(fsOut, alg.CreateDecryptor(),
    CryptoStreamMode.Write);

    // Now will will initialize a buffer and will be processing the input file
    in chunks.

    // This is done to avoid reading the whole file (which can be huge) into
    memory.

    int bufferLen = 4096;

    byte[] buffer = new byte[bufferLen];

    int bytesRead;

    do

    {

    // read a chunk of data from the input file

    bytesRead = fsIn.Read(buffer, 0, bufferLen);

    // Decrypt it

    cs.Write(buffer, 0, bytesRead);

    } while(bytesRead != 0);

    // close everything

    cs.Close(); // this will also close the unrelying fsOut stream

    fsIn.Close();

    }

    //

    // Testing function

    // I am sure you will be able to figure out what it does!

    //

    public static void testFunc(string[] args)

    {

    if (args.Length == 0)

    {

    string plainText = "This is some plain text";

    string Password = "Password";

    Console.WriteLine("Plain text: \"" + plainText + "\", Password: \"" +
    Password + "\"");

    string cipherText = Encrypt(plainText, Password );

    Console.WriteLine("Encrypted text: " + cipherText);

    string decryptedText = Decrypt(cipherText, Password);

    Console.WriteLine("Decrypted: " + decryptedText);

    }

    else

    {

    Encrypt(args[0], args[0]+".encrypted", "Password");

    Decrypt(args[0]+".encrypted", args[0]+".decrypted", "Password");

    }

    Console.WriteLine("Done.");

    }

    }

    }


    Craig Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139