locked
.Net Cryptography RRS feed

  • Question

  • Hi guys,

    I was working on the .net AES symmetric encryption sometime last week.
    What I noticed that
    1) I had to create a CryptoStream
    2) I had to create a memory stream
    3) The crypto stream writes the chiper text into the memory stream
    4) The chiper text is read as bytes from the memory stream


    Hear are my questions
    Q1) Why do I need to create a crypto stream and then a memory stream, why cant .Net provide me with a simplfied API that can take in a key and the string that I need to encrypt? (if I am not concerned abt the IV and all and also I know that the Cryptography application block gives me a simplfied API but I my question is on the BCL)

    Q2)  Why did I need to turn my string into BYTES? (I think I know the answer to this but I want the answer from an expert :))

    Q3) If I need to use a string password to use as the key for the algorithm, how do I do that, because there is a restriction on the key size...can some one help me here?

    Thanx in advance
    Nairooz Nilafdeen
    Thursday, July 9, 2009 11:23 AM

Answers

  • 1) Crypto is built on the same philosophy as the rest of the framework.  It generalizes access by using a stream (or layers of streams).  Streams can represent anything: memory, network socket, file, or a string.  While .NET doesn't ship with a string stream they are really easy to create or you can go fetch any # of ones available on the INet.  Alternatively you can just use a memory stream.  The layering allows you to add functionality without modifying large portions of your code.  For example right now you might be passing it a string but later you might be reading that string from a database, passing it through a checksum stream, passing that through an authentication stream and then to the crypto stream for decryption.  That's the nice benefit of streams.

    2) Crypto works against bytes of data and not strings (because most encryption just cares about a single byte value).  Hence you need a byte array.  While you could expect the API to expose a string variant this just adds complexity to the API.  It only requires a couple of extra lines of code to implement this feature.  If it bothers you too much then you might look into creating an extension method that accepts the crypto stream as the extended object.  You can then expose a method off the stream that accepts a string and internally converts it to a byte array (or vice versa).

    3) Most cryptos require a fixed size key.  You can either pad the string in question using some character (space, zero, etc) and then convert it or convert the string to a byte array and then add a fixed byte until you get the appropriate length.  You need to be careful here though because in order to decrypt the key (if you need to) then you have to know when the real string ends and the padding begins.  Personally I find padding the string the easier approach.

    Michael Taylor - 7/9/09
    http://p3net.mvps.org
    Thursday, July 9, 2009 1:56 PM

All replies

  • 1) Crypto is built on the same philosophy as the rest of the framework.  It generalizes access by using a stream (or layers of streams).  Streams can represent anything: memory, network socket, file, or a string.  While .NET doesn't ship with a string stream they are really easy to create or you can go fetch any # of ones available on the INet.  Alternatively you can just use a memory stream.  The layering allows you to add functionality without modifying large portions of your code.  For example right now you might be passing it a string but later you might be reading that string from a database, passing it through a checksum stream, passing that through an authentication stream and then to the crypto stream for decryption.  That's the nice benefit of streams.

    2) Crypto works against bytes of data and not strings (because most encryption just cares about a single byte value).  Hence you need a byte array.  While you could expect the API to expose a string variant this just adds complexity to the API.  It only requires a couple of extra lines of code to implement this feature.  If it bothers you too much then you might look into creating an extension method that accepts the crypto stream as the extended object.  You can then expose a method off the stream that accepts a string and internally converts it to a byte array (or vice versa).

    3) Most cryptos require a fixed size key.  You can either pad the string in question using some character (space, zero, etc) and then convert it or convert the string to a byte array and then add a fixed byte until you get the appropriate length.  You need to be careful here though because in order to decrypt the key (if you need to) then you have to know when the real string ends and the padding begins.  Personally I find padding the string the easier approach.

    Michael Taylor - 7/9/09
    http://p3net.mvps.org
    Thursday, July 9, 2009 1:56 PM
  • The answer to pretty much all your questions is you are too focused on encrypting strings, in the real world that rarely happens its mostly streams of information (any https connection for instance) or big blobs of binary data (complete files for instance) the times that a single string actually needs to be encrypted is relativly low so the majority of scenario's is supported by the framework by default any sidecases you have to do a littlebit of extra work as you have found out.

    For going from password to key you'd want to read this page that explains why and how.
    Thursday, July 9, 2009 2:08 PM