CryptoStream encrypt to MemoryStream problem

G

Gasnic

Hi,

I was doing a proof of concept on encryption and decryption. I tried to use the triple DES algorithm with the CryptoStream to encrypt the data.

I pass a literal string into the CryptoStream to encrypt the data into a MemoryStream. And then decrypt the MemoryStream back. But I am getting CryptographicException with Bad Data.

When I tried to encryption the same data into a FileStream and then decrypt the file, it works.

In short, it works when I use FileStream but not MemoryStream.
Another info I found is that the encrypted file is 16 bytes, and if I encrypt it to MemoryStream, the stream is in length 8.
I used StreamWriter to write data into the CryptoStream but I didn't specify the encoding.
Should I specify an encoding? if so, which encoding should I use?

Thanks first.
 
M

Marc Gravell

I pass a literal string into the CryptoStream to encrypt the data into a MemoryStream. And then decrypt the MemoryStream back. But I am getting CryptographicException with Bad Data.

Did you rewind the stream? Should have something like:

using(MemoryStream memStream = new MemoryStream()) {
// write the values
using([whatever] foo = new [whatever](memStream)) {
// some code to write to foo
foo.Close();
}
// rewind the stream
memStream.Position = 0;
// read the stream to verify
using([wossit] bar = new [wossit](memStream)) {
// some code to read from bar
bar.Close();
}
}
Another info I found is that the encrypted file is 16 bytes, and if I encrypt it to MemoryStream, the stream is in length 8.
[snip] but I didn't specify the encoding.
That *could* be encoding related (as you mention), but I would expect
it to use the same encoding in both directions; but it wouldn't hurt
to be explicit.
if so, which encoding should I use?
UTF8 is a good all-rounder; supports full unicode, and has the
advantage of single-byte for ASCII chars. A bit more expensive if you
are using a lot of "interesting" characters, i.e. a non-latin
language.

Marc
 
G

Gasnic

I did set the stream position to 0.

I also tried to get the encrypted string from the MemoryStream and pass the
string to a new Memory to decrypt.

It still doesn't work.

I just tried to use UTF8, it doesn't work as well.

Any clue?

thanks,



Marc Gravell said:
I pass a literal string into the CryptoStream to encrypt the data into a
MemoryStream. And then decrypt the MemoryStream back. But I am getting
CryptographicException with Bad Data.

Did you rewind the stream? Should have something like:

using(MemoryStream memStream = new MemoryStream()) {
// write the values
using([whatever] foo = new [whatever](memStream)) {
// some code to write to foo
foo.Close();
}
// rewind the stream
memStream.Position = 0;
// read the stream to verify
using([wossit] bar = new [wossit](memStream)) {
// some code to read from bar
bar.Close();
}
}
Another info I found is that the encrypted file is 16 bytes, and if I
encrypt it to MemoryStream, the stream is in length 8.
[snip] but I didn't specify the encoding.
That *could* be encoding related (as you mention), but I would expect
it to use the same encoding in both directions; but it wouldn't hurt
to be explicit.
if so, which encoding should I use?
UTF8 is a good all-rounder; supports full unicode, and has the
advantage of single-byte for ASCII chars. A bit more expensive if you
are using a lot of "interesting" characters, i.e. a non-latin
language.

Marc
 
P

Peter Duniho

I pass a literal string into the CryptoStream to encrypt the data into a
MemoryStream. And then decrypt the MemoryStream back. But I am getting
CryptographicException with Bad Data.

When I tried to encryption the same data into a FileStream and then
decrypt the file, it works.

[...]
I used StreamWriter to write data into the CryptoStream but I didn't
specify the encoding.
Should I specify an encoding? if so, which encoding should I use?

I would not expect how you stream data to the CryptoStream to affect the
encryption. You could very well run into an encoding issue when trying to
reconstitute the text data from the _unencrypted_ stream but a) unless
you're changing the encoding I would expect the default encoding to apply
in both directions, and b) the encoding shouldn't have any effect on the
data after it's encrypted, nor should it affect the decryption of the
previously encrypted data. You might get an exception thrown by a
StreamReader or something trying to read the unencrypted stream, but it
shouldn't affect the encryption itself.

This all assumes, of course, that when you write "I used StreamWriter to
write data into the CryptoStream", you are talking about the encryption
stage and that your data flow looks something like:

StreamWriter --> CryptoStream --> FileStream
and
StreamWriter --> CryptoStream --> MemoryStream

for encryption, and basically the inverse for decryption (with the
appropriate stream classes replaced as necessary of course).

If you're using StreamWriter post-encryption, then yes...that'd be a
problem. :)

Generally speaking, what you're trying to do (if I understand the post
correctly) should work. You should be able to use a MemoryStream and
FileStream essentially interchangeably here and they should work the
same. Since they are not working the same, I suspect that you've got some
sort of simple typographical error or you're not treating the two exactly
the same somehow.

You should look through the code carefully to make sure you're not
treating the two different. You may even want to make sure that the code
doing the encryption only ever uses a Stream that you pass to it for
output and input, and just make the caller aware of the MemoryStream
versus FileStream. That will guarantee that at least the encryption part
isn't depending on the type of the stream used to store the encrypted data.

If after checking all that you still have a problem, you should post a
concise-but-complete code sample that reliably demonstrates the problem.
The exception you describe seems to imply that the data isn't making the
round-trip post-encryption/pre-decryption safely, but if you're really
treating both storage streams the same, it's hard to see how that might
happen.

One final thought (now that I've written all of the above, this occurs to
me :) ): are you sure that in the MemoryStream case, you have reset the
stream position back to the beginning before trying to decrypt the data?

Pete
 
G

Gasnic

Problem sloved.

The problem is I didn't call the CryptoStream.FlushFinalBlock() method
(which is not being called in the MSDN sample code as well, may be becuase
it is using FileStream).

Thanks everyone.

Gasnic

Peter Duniho said:
I pass a literal string into the CryptoStream to encrypt the data into a
MemoryStream. And then decrypt the MemoryStream back. But I am getting
CryptographicException with Bad Data.

When I tried to encryption the same data into a FileStream and then
decrypt the file, it works.

[...]
I used StreamWriter to write data into the CryptoStream but I didn't
specify the encoding.
Should I specify an encoding? if so, which encoding should I use?

I would not expect how you stream data to the CryptoStream to affect the
encryption. You could very well run into an encoding issue when trying to
reconstitute the text data from the _unencrypted_ stream but a) unless
you're changing the encoding I would expect the default encoding to apply
in both directions, and b) the encoding shouldn't have any effect on the
data after it's encrypted, nor should it affect the decryption of the
previously encrypted data. You might get an exception thrown by a
StreamReader or something trying to read the unencrypted stream, but it
shouldn't affect the encryption itself.

This all assumes, of course, that when you write "I used StreamWriter to
write data into the CryptoStream", you are talking about the encryption
stage and that your data flow looks something like:

StreamWriter --> CryptoStream --> FileStream
and
StreamWriter --> CryptoStream --> MemoryStream

for encryption, and basically the inverse for decryption (with the
appropriate stream classes replaced as necessary of course).

If you're using StreamWriter post-encryption, then yes...that'd be a
problem. :)

Generally speaking, what you're trying to do (if I understand the post
correctly) should work. You should be able to use a MemoryStream and
FileStream essentially interchangeably here and they should work the
same. Since they are not working the same, I suspect that you've got some
sort of simple typographical error or you're not treating the two exactly
the same somehow.

You should look through the code carefully to make sure you're not
treating the two different. You may even want to make sure that the code
doing the encryption only ever uses a Stream that you pass to it for
output and input, and just make the caller aware of the MemoryStream
versus FileStream. That will guarantee that at least the encryption part
isn't depending on the type of the stream used to store the encrypted
data.

If after checking all that you still have a problem, you should post a
concise-but-complete code sample that reliably demonstrates the problem.
The exception you describe seems to imply that the data isn't making the
round-trip post-encryption/pre-decryption safely, but if you're really
treating both storage streams the same, it's hard to see how that might
happen.

One final thought (now that I've written all of the above, this occurs to
me :) ): are you sure that in the MemoryStream case, you have reset the
stream position back to the beginning before trying to decrypt the data?

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top