I am trying to write some symmetric cryptography for holding an FtpCredential in the database, unfortunately I am having a few problems, one of which is getting back gobbley gook from a crypto decoder. I have trimmed it down to just the bare minimum code.
Please look at the SetPassword method and the GetPassword method.

/*Author: Cameron Block*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Configuration;

namespace Reporting.Models {
    /// <summary>
    /// FtpCredential stores passwords in the database, and uploads files to remote FTP sites. 
    /// </summary>
    public class FtpCredential {
        private const int CHARS_AVAILABLE = 32;

        public FtpCredential() {
            PasswordEncrypted = new byte[GetSymmetricAlgorithim().BlockSize * GetEncodingNumBytes() * CHARS_AVAILABLE];
        }

        /// <summary>
        /// The encrypted password of the ftp site. 
        /// </summary>
        public byte[] PasswordEncrypted {
            get; set;
        }

        /// <summary>
        /// Sets the password for this FtpCredential. 
        /// </summary>
        /// <param name="password"></param>
        public void SetPassword(String password) {
            using (SymmetricAlgorithm crypt = Rijndael.Create()) {
                //crypt.Padding = PaddingMode.Zeros;
                int keySize = crypt.LegalKeySizes[0].MinSize / 8;
                int ivSize = crypt.BlockSize / 8;

                byte[] key = Encoding.UTF8.GetBytes(System.Configuration.ConfigurationManager.AppSettings["dEncryptionKey"].PadRight(keySize, '\0').ToCharArray(), 0, keySize);
                byte[] iv = Encoding.UTF8.GetBytes(System.Configuration.ConfigurationManager.AppSettings["EncryptionIV"].PadRight(ivSize, '\0').ToCharArray(), 0, ivSize);

                ICryptoTransform transform = crypt.CreateEncryptor(key, iv);
                MemoryStream ms = new MemoryStream();
                CryptoStream csWriter = new CryptoStream(ms, crypt.CreateEncryptor(), CryptoStreamMode.Write);
                StreamWriter writer = new StreamWriter(csWriter);
                writer.Write(password);
                writer.Flush();
                csWriter.FlushFinalBlock();

                PasswordEncrypted = ms.ToArray();

                writer.Close();
            }
        }//end method

        /// <summary>
        /// Un-encrypts the password for this FtpCredential. 
        /// </summary>
        /// <returns></returns>
        public String GetPassword() {
            using (SymmetricAlgorithm crypt = GetSymmetricAlgorithim()) {
                //crypt.Padding = PaddingMode.Zeros;
                int keySize = crypt.LegalKeySizes[0].MinSize / 8;
                int ivSize = crypt.BlockSize / 8;

                byte[] key = Encoding.UTF8.GetBytes(System.Configuration.ConfigurationManager.AppSettings["EncryptionKey"].PadRight(keySize, '\0').ToCharArray(), 0, keySize);
                byte[] iv = Encoding.UTF8.GetBytes(System.Configuration.ConfigurationManager.AppSettings["EncryptionIV"].PadRight(ivSize, '\0').ToCharArray(), 0, ivSize);

                ICryptoTransform transform = crypt.CreateDecryptor(key, iv);
                MemoryStream ms = new MemoryStream(PasswordEncrypted);
                CryptoStream csReader = new CryptoStream(ms, crypt.CreateDecryptor(), CryptoStreamMode.Read);

                StreamReader reader = new StreamReader(csReader);
                return reader.ReadToEnd();
            }
        }//end method

        /// <summary>
        /// Gets the underlying symmetric algorithim for the object's password capability. 
        /// </summary>
        /// <returns></returns>
        public SymmetricAlgorithm GetSymmetricAlgorithim() {
            return Rijndael.Create();
        }

        /// <summary>
        /// Gets the number of bytes for the encoding used by the credential object. 
        /// </summary>
        /// <returns></returns>
        public int GetEncodingNumBytes() {
            return Encoding.UTF8.GetByteCount("1");
        }
    }//end class

}//end namespace

I have refactored the code based on an online example. I believe the problem with the other code is probably encoding, or something. You switch everything to ASCII and things seem to work better. Also the crypto streams seem to work when both encrypt and decrypt are set to write mode. The following is what works:

/*Author: Cameron Block*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System.Diagnostics;
using System.Configuration;

namespace GadsdenReporting.Models {
    /// <summary>
    /// FtpCredential stores passwords in the database, and uploads files to remote FTP sites. 
    /// </summary>
    public class FtpCredential {
        private const int CHARS_AVAILABLE = 32;

        public FtpCredential() {
            PasswordEncrypted = new byte[GetSymmetricAlgorithim().BlockSize * GetEncodingNumBytes() * CHARS_AVAILABLE];
        }

        /// <summary>
        /// The encrypted password of the ftp site. 
        /// </summary>
        public byte[] PasswordEncrypted {
            get; set;
        }

        /// <summary>
        /// Gets the underlying symmetric algorithim for the object's password capability. 
        /// </summary>
        /// <returns></returns>
        public SymmetricAlgorithm GetSymmetricAlgorithim() {
            return Rijndael.Create();
        }//end method

        /// <summary>
        /// Gets the key from the web config, pads it with null bytes so that it is valid. 
        /// </summary>
        /// <param name="crypt"></param>
        /// <returns></returns>
        public byte[] GetKey(SymmetricAlgorithm crypt) {
            int keySize = crypt.LegalKeySizes[0].MinSize / 8;
            return Encoding.ASCII.GetBytes(System.Configuration.ConfigurationManager.AppSettings["EncryptionKey"].PadRight(keySize, '\0').ToCharArray(), 0, keySize);
        }//end method

        /// <summary>
        /// Gets the initialization vector from the web config, pads it with null bytes so that it is valid. 
        /// </summary>
        /// <param name="crypt"></param>
        /// <returns></returns>
        public byte[] GetIV(SymmetricAlgorithm crypt) {
            int ivSize = crypt.BlockSize / 8;
            return Encoding.ASCII.GetBytes(System.Configuration.ConfigurationManager.AppSettings["EncryptionIV"].PadRight(ivSize, '\0').ToCharArray(), 0, ivSize);
        }//end method

        /// <summary>
        /// Gets the decrypted password. 
        /// </summary>
        /// <returns></returns>
        public String GetPassword() {
            MemoryStream ms = new MemoryStream();
            SymmetricAlgorithm crypt = GetSymmetricAlgorithim();
            crypt.Padding = PaddingMode.PKCS7;
            crypt.Key = GetKey(crypt);
            crypt.IV = GetIV(crypt);
            CryptoStream cs = new CryptoStream(ms,
            crypt.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(PasswordEncrypted, 0, PasswordEncrypted.Length);
            cs.Close();
            byte[] decryptedData = ms.ToArray();
            return Encoding.ASCII.GetString(decryptedData);
        }//end method

        /// <summary>
        /// Sets the byte array containing the encrypted password. 
        /// </summary>
        public void SetPassword(String password) {
            //we only have a specific number of bytes in the database. 
            if (password.Length > CHARS_AVAILABLE)
                throw new ArgumentException("Password text is too big. ");

            byte[] passBytes = Encoding.ASCII.GetBytes(password);
            MemoryStream ms = new MemoryStream();
            SymmetricAlgorithm crypt = GetSymmetricAlgorithim();
            crypt.Padding = PaddingMode.PKCS7;
            crypt.Key = GetKey(crypt);
            crypt.IV = GetIV(crypt);
            CryptoStream cs = new CryptoStream(ms,
            crypt.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(passBytes, 0, passBytes.Length);
            cs.Close();
            byte[] encryptedData = ms.ToArray();
            PasswordEncrypted = encryptedData;
        }//end method

        /// <summary>
        /// Gets the number of bytes for the encoding used by the credential object. 
        /// </summary>
        /// <returns></returns>
        public int GetEncodingNumBytes() {
            return Encoding.ASCII.GetByteCount("1");
        }//end method

    }//end class

}//end namespace
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.