Click here to Skip to main content
15,898,222 members
Home / Discussions / C#
   

C#

 
GeneralThoughts on CrystalReports Pin
SusanP15-Jan-10 14:04
SusanP15-Jan-10 14:04 
GeneralRe: Thoughts on CrystalReports Pin
DaveyM695-Jan-10 14:32
professionalDaveyM695-Jan-10 14:32 
GeneralRe: Thoughts on CrystalReports Pin
SusanP15-Jan-10 14:36
SusanP15-Jan-10 14:36 
QuestionCryptographic Service Provider: How Do I Secure Machine-Level RSA Key Containers? Pin
Skippums5-Jan-10 11:58
Skippums5-Jan-10 11:58 
QuestionFile already Loaded, Save Pin
San245-Jan-10 9:33
San245-Jan-10 9:33 
AnswerRe: File already Loaded, Save Pin
Not Active5-Jan-10 9:45
mentorNot Active5-Jan-10 9:45 
AnswerRe: File already Loaded, Save Pin
Skippums5-Jan-10 12:12
Skippums5-Jan-10 12:12 
QuestionStreams and Cryptography (Padding is invalid and cannot be removed) Pin
Skippums5-Jan-10 9:26
Skippums5-Jan-10 9:26 
I have a cryptography question that is puzzling me. Basically, I am attempting to create an encrypted file that includes a signed hashcode to ensure that it is not tampered with. The procedure to perform this is as follows:

1) Load an asymmetric algorithm (RSACryptoServiceProvider) stored using a CspParameters object
2) Create a symmetric algorithm object (AesCryptoServiceProvider)
3) Encrypt the concatenated key and initialization vector using the RSA encryptor
4) Create a new MemoryStream object (with associated BinaryWriter)
5) Write the following data to the output stream:
   *The size of the encrypted key/IV vector
   *The encrypted key/IV vector
6) Create new CryptoStream and BinaryWriter objects and write my data to the MemoryStream
7) Hash the MemoryStream, and sign the hash
8) Open a file for writing (FileStream)
9) Write the following data
   *Length of the signed hash
   *The signed hash
   *COPY THE CONTENTS OF THE MEMORY STREAM TO THE OUTPUT


I put the last portion of step 9 in bold because this is where something is going terribly wrong. My entire encryption/decryption process works when I copy/paste the code that writes to the MemoryStream object. However, if I simply attempt to copy the contents of the MemoryStream to the FileStream, the decryption process begins, but I get to a point reading the data where I get the error, "Padding is invalid and cannot be removed". Everything up to this point is decrypted correctly, and my file is validated against the signed hash (in both cases... ie, when I rewrite the data to the FileStream, my file has the same signed hash as when I copy the contents of the MemoryStream to the FileStream). What am I missing here? Why is the file validated against the hash in both cases, but is only able to be decrypted when I rewrite the data? I have copied what I think is relevant below:

class ExampleForm : Form {
    private readonly int                      m_SymmetricKeySize = s_KeySizeSym >> 3;
    private readonly int                      m_SymmetricBlockSize;
    private readonly RSACryptoServiceProvider m_AsymmetricAlg;
    private readonly SymmetricAlgorithm       m_SymmetricAlg = new AesCryptoServiceProvider();
    private readonly HashAlgorithm            m_HashAlg      = new MD5CryptoServiceProvider();
    private readonly string                   m_OutFile      =
        Path.Combine(Application.CommonAppDataPath, "Example.dat");

    private static void CopyStream(Stream src, Stream dst) {
        const int bufferSize = 256;
        byte[]    buffer     = new byte[bufferSize];
        int count;
        do {
            count = src.Read(buffer, 0, bufferSize);
            dst.Write(buffer, 0, count);
        } while (count == bufferSize);
    }

    public ExampleForm() {
        // Create the cryptographic data members
        m_SymmetricBlockSize   = m_SymmetricAlg.BlockSize >> 3;
        CspParameters csp      = new CspParameters();
        csp.KeyContainerName   = "Example Container";
        m_AsymmetricAlg        = new RSACryptoServiceProvider(2048, csp);

        // Load the encrypted file
        bool isFileValid = File.Exists(m_OutFile);
        if (isFileValid) {
            // Open the input file, and create a temporary memory stream
            Stream       dataStream   = new MemoryStream();
            Stream       fileStream   = File.OpenRead(m_OutFile);
            BinaryReader binaryReader = new BinaryReader(fileStream);

            // Read the signature
            byte[] sign = new byte[binaryReader.ReadInt32()];
            fileStream.Read(sign, 0, sign.Length);

            // Copy the remaining contents to another stream
            ExampleForm.CopyStream(fileStream, dataStream);

            // Close the input file
            binaryReader.Close();
            fileStream  .Close();

            // Compute and verify the hash value of the new stream
            byte[] hash = m_HashAlg.ComputeHash(dataStream);
            isFileValid = m_AsymmetricAlg.VerifyHash(hash,
                          CryptoConfig.MapNameToOID("MD5"), sign);

            if (isFileValid) {
                // Create the necessary input streams
                dataStream.Seek(0, SeekOrigin.Begin);
                binaryReader = new BinaryReader(dataStream);

                // Load the key and IV vectors
                byte[] encKeyIV = new byte[binaryReader.ReadInt32()];
                dataStream.Read(encKeyIV, 0, encKeyIV.Length);
                byte[] keyAndIV = new byte[m_SymmetricBlockSize + m_SymmetricKeySize];
                keyAndIV = m_AsymmetricAlg.Decrypt(encKeyIV, true);

                // Copy the key and IV to the symmetric algorithm members
                byte[] key = new byte[m_SymmetricKeySize  ];
                byte[] iv  = new byte[m_SymmetricBlockSize];
                for (int idx = 0; idx < m_SymmetricKeySize; ++idx)
                    key[idx] = keyAndIV[idx];
                for (int idx = 0; idx < m_SymmetricBlockSize; ++idx)
                    iv [idx] = keyAndIV[idx + m_SymmetricKeySize];

                // Create the streams for outputting data
                CryptoStream cryptoStream = new CryptoStream(dataStream,
                    m_SymmetricAlg.CreateDecryptor(key, iv), CryptoStreamMode.Read);
                BinaryReader cryptoReader = new BinaryReader(cryptoStream);

                // Read the data, utilizing...
                //   cryptoReader.ReadUInt32();
                //   cryptoReader.ReadString();
                //   cryptoReader.ReadInt64 ();

                // Close the appropriate data streams
                binaryReader.Close();
                cryptoReader.Close();
                cryptoStream.Close();
            } else {
                // The file is corrupt
            }

            // Close the data stream
            dataStream.Close();
        }
    }

    private void ExampleForm_FormClosing(object sender, FormClosingEventArgs e) {
        // Create an array containing the symmetric key and initialization vector
        byte[] keyAndIV = new byte[m_SymmetricBlockSize + m_SymmetricKeySize];
        m_SymmetricAlg.Key.CopyTo(keyAndIV, 0);
        m_SymmetricAlg.IV .CopyTo(keyAndIV, m_SymmetricKeySize);

        // Create the temporary output objects
        Stream       dataStream   = new MemoryStream();
        BinaryWriter binaryWriter = new BinaryWriter(dataStream);
        BinaryWriter cryptoWriter = new BinaryWriter(new CryptoStream(
            dataStream, m_SymmetricAlg.CreateEncryptor(), CryptoStreamMode.Write));

        // Encrypt and write the symmetric key and IV using the asymmetric algorithm
        byte[] encKeyIV = m_AsymmetricAlg.Encrypt(keyAndIV, true);
        binaryWriter.Write(encKeyIV.Length);
        binaryWriter.Flush();
        dataStream.Write(encKeyIV, 0, encKeyIV.Length);


        // Encrypt and write the data utilizing...
        //     cryptoWriter.Write(uint);
        //     cryptoWriter.Write(string);
        //     cryptoWriter.Write(long);
        cryptoWriter.Flush();

        // Compute and sign the hash code for the file
        byte[] hash = m_HashAlg.ComputeHash(dataStream);
        byte[] sign = m_AsymmetricAlg.SignHash(hash, CryptoConfig.MapNameToOID(s_HashName));

#region Option 1 (What I would like to do)
        Stream fileStream = File.OpenWrite(m_OutFile);
        binaryWriter = new BinaryWriter(fileStream);

        // Write the data to the output file
        binaryWriter.Write(sign.Length);
        binaryWriter.Flush();
        fileStream.Write(sign, 0, sign.Length);
        dataStream.Seek(0, SeekOrigin.Begin);
        ExampleForm.CopyStream(dataStream, fileStream);

        // Close the streams
        cryptoWriter.Close();
        binaryWriter.Close();
        fileStream.Close();
        dataStream.Close();
#endregion

#region Option 2 (The option that currently works)
        // Close the streams
        cryptoWriter.Close();
        binaryWriter.Close();
        dataStream  .Close();

        // Create the actual output objects
        Stream fileStream = File.OpenWrite(m_OutFile);
        binaryWriter = new BinaryWriter(fileStream);
        cryptoWriter = new BinaryWriter(new CryptoStream(
            fileStream, m_SymmetricAlg.CreateEncryptor(), CryptoStreamMode.Write));

        // Write the data to the output file
        binaryWriter.Write(sign.Length);
        binaryWriter.Flush();
        fileStream.Write(sign, 0, sign.Length);

        // Rewrite the data already written to the output stream
        binaryWriter.Write(encKeyIV.Length);
        binaryWriter.Flush();
        fileStream.Write(encKeyIV, 0, encKeyIV.Length);

        // Encrypt and write the data utilizing...
        //     cryptoWriter.Write(uint);
        //     cryptoWriter.Write(string);
        //     cryptoWriter.Write(long);

        // Close the output objects
        cryptoWriter.Close();
        binaryWriter.Close();
        fileStream  .Close();
#endregion

    }
}
Again, I am wondering why "Option 1" from above doesn't work. I noticed that the last character written when copying the stream was an "11". Any ideas? Thanks,

Sounds like somebody's got a case of the Mondays

-Jeff

GeneralRe: Streams and Cryptography (Padding is invalid and cannot be removed) Pin
Skippums5-Jan-10 9:40
Skippums5-Jan-10 9:40 
GeneralRe: Streams and Cryptography (Padding is invalid and cannot be removed) Pin
Paulo Zemek5-Jan-10 10:09
Paulo Zemek5-Jan-10 10:09 
AnswerRe: Streams and Cryptography (Padding is invalid and cannot be removed) Pin
Skippums5-Jan-10 10:30
Skippums5-Jan-10 10:30 
QuestionNeed help! How to draw waveform of the sound when playing video! Pin
die_for_rock_vn5-Jan-10 7:23
die_for_rock_vn5-Jan-10 7:23 
AnswerRe: Need help! How to draw waveform of the sound when playing video! Pin
Roger Wright5-Jan-10 20:02
professionalRoger Wright5-Jan-10 20:02 
Questionenumerate used com Pin
abalbo5-Jan-10 3:21
abalbo5-Jan-10 3:21 
AnswerRe: enumerate used com Pin
Keith Barrow5-Jan-10 7:15
professionalKeith Barrow5-Jan-10 7:15 
GeneralRe: enumerate used com Pin
abalbo5-Jan-10 16:11
abalbo5-Jan-10 16:11 
QuestionDetecting music keys from keyboard in winform app Pin
Wheels0125-Jan-10 2:22
Wheels0125-Jan-10 2:22 
AnswerRe: Detecting music keys from keyboard in winform app Pin
Covean5-Jan-10 3:11
Covean5-Jan-10 3:11 
GeneralRe: Detecting music keys from keyboard in winform app Pin
Wheels0125-Jan-10 3:18
Wheels0125-Jan-10 3:18 
GeneralRe: Detecting music keys from keyboard in winform app Pin
Covean5-Jan-10 3:51
Covean5-Jan-10 3:51 
GeneralRe: Detecting music keys from keyboard in winform app Pin
Wheels0125-Jan-10 4:09
Wheels0125-Jan-10 4:09 
GeneralRe: Detecting music keys from keyboard in winform app Pin
Covean5-Jan-10 4:16
Covean5-Jan-10 4:16 
GeneralRe: Detecting music keys from keyboard in winform app Pin
Wheels0125-Jan-10 4:58
Wheels0125-Jan-10 4:58 
GeneralRe: Detecting music keys from keyboard in winform app Pin
Saksida Bojan5-Jan-10 6:09
Saksida Bojan5-Jan-10 6:09 
QuestionOutlookAddin Pin
Md. Marufuzzaman5-Jan-10 1:31
professionalMd. Marufuzzaman5-Jan-10 1:31 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.