Hitting the Mailbag

I've gotten quite a few questions from this blog over the past several months.  And although I can't answer all of them, here's some quick answers to some of the more common ones.  If you do have more questions, its usually best to post them in the comments here or in the microsoft.public.dotnet.security newsgroup.  That way if I don't get to them, somebody else may see it and have an answer for you.  (It also prevents my spam filter from snagging them).

Anyway, on to the questions:

Hi,

I just wanted to know what is the purpose of FirstMatchCodeGroup?

For instance one could have guessed that all_code from machine security level would be FirstMatchCodeGroup, but it is not the case.

The FirstMatchCodeGroup is different from the standard UnionCodeGroup (which is what the default policy uses) in how it deals with child code groups.  UnionCodeGroup will merge the permission set associated with itself with the permission sets returned by all of its children code groups.  FirstMatchCodeGroup on the other hand merges its permission set with only the first child code group that matches the evidence being evaluated.

Since FirstMatchCodeGroup stops evaluating its children code groups after it finds one that matches the evidence, it's not what we would want to use for the default policy, where we want all the code groups to have a chance at determining the final permission grant.


My question is how can I sign an assembly I compile myself using the Microsoft.CSharp.Compiler? In an IDE situation, this would obviously be done with the AssemblyInfo.cs file.

I realize I could use CompileAssemblyFromFileBatch and create essentially an AssemblyInfo.cs on the fly. This seems a bit cheesy, and I'd prefer a cleaner way if there is one.

Well, the easiest answer to this is to emit a System.Reflection.AssemblyKeyFileAttribute or System.Reflection.AssemblyKeyNameAttribute into the class you're compiling.  On Whidbey, this will give you warning CS1699, which can be avoided by using the /keyfile or /keycontainer options in the CompilerParameters object you pass to the C# CodeDOM compiler.

Now, that being said, if you're signing assemblies on the fly you'll need access to a private key on the machine.  And if you're making security decisions based entirely upon that key, you're opening a security hole since any other application could also potentially find that key and sign themselves with it.  Once they've done that, they'll match your code groups and get any permissions you grant to that key.


I am trying hard to understand how to sign an xml file using a private key file. I have the private key on windows certificate store but I don't want to use the private key from the store. I can export it as pfx. But I don't know what to do next. Can you assist me on this?

If you need to do this on v1.1 of the framework, you'll need to P/Invoke to the Windows Cryptography API in order to load your certificate back into a cert store, and create an RSACryptoServiceProvider object around it by passing in CspParameters to the constructor which point to the correct key container.  Since you said you already have the key in the store it might be easier to just do this without exporting to PFX first.

With Whidbey, we've enhanced the X.509 certificate support available in the framework, and you can now open an X.509 certificate stored in a file into an X509Certificate2 object directly by passing in the path to the PFX file and a SecureString as a password.  Then you'll be able to use the PrivateKey property of the certificate to get the signing key.  For a sample of what this might look like, check out the section on X.509 Support in the article Mike Downen and I wrote for November's MSDN magazine.


I've just found a very interesting blog post of yours: "Generating a Key from a Password" which is all about PasswordDeriveBytes and CryptDeriveKey.

I'm trying to use this class, but there isn't any support for RipeMD-160 hash algorithm which I have to use in case to decrypt an 2-Key TripleDES encrypted message (the key has been derived from password with RipeMD-160).

My question:
How can I set directly the key for TripleDESCryptoServiceProvider without using the PasswordDeriveBytes class?

The blog post mentioned in the question shows how to use two built in helper classes to generate a key from a password.  PasswordDeriveBytes uses the CryptDeriveKey algorithm exposed by CAPI or PBKDF1.  Whidbey introduces Rfc2898DeriveBytes, which uses PBKDF2 to generate a key from a password.

However, there are other ways to go about generating a key, and if you need to use RIPEMD-160, then you'll find that Whidbey also introduces support for the RIPEMD160 hash algorithm.  Depending on how you're key is to be generated, you'll probably have to do some variation of PBKDF2 substituting HMACRIPEMD160 for HMACSHA1.

Once you've done that, you'll have a byte array to use as a key.  You can then just set the Key property of TripleDESCryptoServiceProvider in order to decrypt your ciphertext.