<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>.NET Security Blog : Cryptography</title><link>http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx</link><description>Tags: Cryptography</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Authenticated Symmetric Encryption in .NET</title><link>http://blogs.msdn.com/shawnfa/archive/2009/03/17/authenticated-symmetric-encryption-in-net.aspx</link><pubDate>Tue, 17 Mar 2009 23:48:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9484740</guid><dc:creator>shawnfa</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/9484740.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=9484740</wfw:commentRss><description>&lt;p&gt;Over the last week, we've made a couple of updates to our Codeplex projects to add authenticated symmetric encryption to the managed cryptography surface area for the first time.&amp;nbsp; Since we've never supported authenticated symmetric algorithms in managed code before, I thought I'd run though some basics about what they are and how to use them.&lt;/p&gt; &lt;p&gt;For starters, in order to use the authenticated symmetric encryption classes, you'll need a few prerequisites:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Windows Vista SP 1, Windows Server 2008, or higher  &lt;li&gt;.NET framework v3.5 SP 1 or higher  &lt;li&gt;Security.Cryptography.dll 1.3 or higher (from &lt;a title="http://codeplex.com/clrsecurity" href="http://codeplex.com/clrsecurity"&gt;http://codeplex.com/clrsecurity&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Authenticated symmetric cryptography differs from the symmetric cryptography that the .NET framework has traditionally supported in that it produces an authentication tag in addition to ciphertext when encrypting data.&amp;nbsp; This authentication tag can be used to verify that the ciphertext has not been tampered with between when it was encrypted and decrypted.&lt;/p&gt; &lt;p&gt;For example, imagine you encrypted a message using the AES class:&lt;/p&gt; &lt;p&gt; &lt;div style="border-bottom: black thin inset; border-left: black thin inset; padding-bottom: 1em; margin: 1em 1em 1em 2em; padding-left: 1em; padding-right: 1em; font-family: monospace; background: lightgrey; color: black; font-size: 10pt; border-top: black thin inset; border-right: black thin inset; padding-top: 1em"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Aes&lt;/span&gt; aes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;AesCng&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.Key = key;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.IV = iv;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; ms = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt; cs = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt;(ms, aes.CreateEncryptor(), &lt;span style="color: #2b91af"&gt;CryptoStreamMode&lt;/span&gt;.Write))&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] plaintext = &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetBytes(&lt;span style="color: #a31515"&gt;"Secret data to be encrypted."&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.Write(plaintext, 0, plaintext.Length);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.FlushFinalBlock();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;return&lt;/span&gt; ms.ToArray();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;While an attacker cannot read the data encrypted by this operation without knowing the encryption key, they can modify the ciphertext bytes themselves which will result in corruption of the decrypted message on the receiving end:&lt;/p&gt; &lt;p&gt; &lt;div style="border-bottom: black thin inset; border-left: black thin inset; padding-bottom: 1em; margin: 1em 1em 1em 2em; padding-left: 1em; padding-right: 1em; font-family: monospace; background: lightgrey; color: black; font-size: 10pt; border-top: black thin inset; border-right: black thin inset; padding-top: 1em"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: green"&gt;// The ciphertext is protected from being decrypted without knowledge of the key, however it&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: green"&gt;// is not protected from being tampered with:&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;ciphertext[5] = 0x21;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Aes&lt;/span&gt; aes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;AesCng&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.Key = key;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.IV = iv;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; ms = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt; cs = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt;(ms, aes.CreateDecryptor(), &lt;span style="color: #2b91af"&gt;CryptoStreamMode&lt;/span&gt;.Write))&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.Write(ciphertext, 0, ciphertext.Length);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.FlushFinalBlock();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] decrypted = ms.ToArray();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;string&lt;/span&gt; message = &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetString(decrypted);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(message);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Which produces output such as:&lt;/p&gt; &lt;div style="border-bottom: black thin inset; border-left: black thin inset; padding-bottom: 1em; margin: 1em 1em 1em 2em; padding-left: 1em; padding-right: 1em; font-family: monospace; background: lightgrey; color: black; font-size: 10pt; border-top: black thin inset; border-right: black thin inset; padding-top: 1em"&gt;? ]\??e enc?ypted.&lt;/div&gt; &lt;p&gt;This can be solved by signing the ciphertext, and having the receiving party verify the signature before decrypting the secret message.&lt;/p&gt; &lt;p&gt;Authenticated symmetric algorithms solve this problem by creating an authentication tag which can be used to verify that the ciphertext has not been tampered with since it was generated.&lt;/p&gt; &lt;p&gt;In addition to verifying that the ciphertext has not been modified, the authenticated symmetric algorithms that we have in managed code also take additional authenticated data as an input.&amp;nbsp; This data is not included in the ciphertext itself - so when decrypting a message that was created with additional authenticated data, the output will not contain the authenticated data.&amp;nbsp; Instead, the authenticated data is only used in generating the authentication tag.&amp;nbsp; This means that much like the key and IV, both the encrypting and decrypting parties need to know what the additional authenticated data is otherwise the authentication tag will not verify.&lt;/p&gt; &lt;h2&gt;&lt;/h2&gt; &lt;h2&gt;Authenticated Symmetric Algorithm Type Hierarchy&lt;/h2&gt; &lt;p&gt;This functionality is exposed in managed code via the AuthenticatedSymmetricAlgorithm base class.&amp;nbsp; Much like the SymmetricAlgorithm base class, AuthenticatedSymmetricAlgorithm is an abstract class for actual authenticated symmetric algorithms to derive from.&lt;/p&gt; &lt;p&gt;Currently, the only authenticated symmetric algorithm is an authenticated version of AES, which is represented by the AuthenticatedAes abstract base class.&amp;nbsp; Again, mirroring the symmetric algorithm type hierarchy, AuthenticatedAes is an abstract base class that concrete authenticated AES implementations derive from.&amp;nbsp; (Much like Aes serves as the base class for AesManaged, AesCryptoServiceProvider and AesCng).&lt;/p&gt; &lt;p&gt;The concrete implementation of AuthenticatedAesCng which is in Security.Cryptography.dll 1.3 is built on top of&amp;nbsp; CNG, and follows our traditional naming scheme: AuthenticatedAesCng.&lt;/p&gt; &lt;h2&gt;Setting up an Authenticated AES Encryptor&lt;/h2&gt; &lt;p&gt;The authentication tag is generated by an authenticated chaining algorithm, which is used in place of the standard chaining modes that AES can use (such as CBC or ECB).&amp;nbsp; Currently CNG supports two algorithms for generating an authentication tag with AES:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Galois/Counter Mode - this is the default, and is represented by CngChainingMode.Gcm.&amp;nbsp; (&lt;a title="http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf" href="http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf"&gt;http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf&lt;/a&gt;)  &lt;li&gt;Coutner with CBC-MAC - this is selected by using CngChainingMode.Ccm.&amp;nbsp; (&lt;a title="http://www.ietf.org/rfc/rfc3610.txt" href="http://www.ietf.org/rfc/rfc3610.txt"&gt;http://www.ietf.org/rfc/rfc3610.txt&lt;/a&gt;)&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Since neither of these chaining modes are supported by the standard CipherMode enumeration, AuthenticatedAesCng adds a new property called CngMode which allows you to specify a CngChainingMode rather than a standard CipherMode.&amp;nbsp; Trying to use the traditional Mode property when the CngChainingMode is set to one of these new values will result in an exception.&lt;/p&gt; &lt;p&gt;The IV property is used to setup what the two algorithm specifications above refer to as a nonce.&amp;nbsp; Unlike traditional AES, the IV size does not match the block size, but is instead specified by the chaining mode.&amp;nbsp; For instance, both GCM and CCM can work with an IV of 12 bytes.&lt;/p&gt; &lt;p&gt;AuthenticatedSymmetricAlgorithms also have an AuthenticatedData byte array property which is used to setup the additional authentication data being used in the tag generation.&amp;nbsp; This property is optional - leaving the value null means that the authentication tag is generated only from the plaintext.&lt;/p&gt; &lt;p&gt;The last interesting property on the encryption side is the TagSize property.&amp;nbsp; This property specifies the size (in bits) of the authentication tag to generate.&amp;nbsp; The LegalTagSizes property contains information about which sizes are valid for the current chaining mode (and the ValidTagSize method allows you to quickly test to see if a tag size is valid).&lt;/p&gt; &lt;p&gt;Once the AuthenticatedAesCng object is setup, we'll need to create an encryptor to do the actual encryption operation.&amp;nbsp; This can be done by calling the CreateAuthenticatedEncryptor method.&amp;nbsp; CreateAuthenticatedEncryptor returns an IAuthenticatdCryptoTransform rather than an ICryptoTransform since IAuthenticatedCryptoTransform allows us access to the authentication tag after the encryption is done.&amp;nbsp; The CreateEncryptor overloads also return IAuthenticatedCryptoTransforms, however they are typed as ICryptoTransform because they're defined on the SymmetricAlgorithm base type.&amp;nbsp; If you call one of the these methods, then you'll have to manually cast to IAuthenticatedCryptoTransform.&lt;/p&gt; &lt;p&gt;Putting this all together, code to encrypt and generate an authentication tag using AuthenticatedAesCng would look something like this:&lt;/p&gt; &lt;p&gt; &lt;div style="border-bottom: black thin inset; border-left: black thin inset; padding-bottom: 1em; margin: 1em 1em 1em 2em; padding-left: 1em; padding-right: 1em; font-family: monospace; background: lightgrey; color: black; font-size: 10pt; border-top: black thin inset; border-right: black thin inset; padding-top: 1em"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;AuthenticatedAesCng&lt;/span&gt; aes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;AuthenticatedAesCng&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Setup an authenticated chaining mode - The two current CNG options are&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// CngChainingMode.Gcm and CngChainingMode.Ccm.&amp;nbsp; This should be done before setting up&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// the other properties, since changing the chaining mode can update things such as the&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// valid and current tag sizes.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.CngMode = &lt;span style="color: #2b91af"&gt;CngChainingMode&lt;/span&gt;.Ccm;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Keys work the same as standard AES&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.Key = key;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// The IV (called the nonce in many of the authenticated algorithm specs) is not sized for&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// the input block size. Instead its size depends upon the algorithm.&amp;nbsp; 12 bytes works&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// for both GCM and CCM. Generate a random 12 byte nonce here.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nonce = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[12];&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rng.GetBytes(nonce);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.IV = nonce;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Authenticated data becomes part of the authentication tag that is generated during&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// encryption, however it is not part of the ciphertext.&amp;nbsp; That is, when decrypting the&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// ciphertext the authenticated data will not be produced.&amp;nbsp; However, if the&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// authenticated data does not match at encryption and decryption time, the&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// authentication tag will not validate.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.AuthenticatedData = &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetBytes(&lt;span style="color: #a31515"&gt;"Additional authenticated data"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Perform the encryption - this works nearly the same as standard symmetric encryption,&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// however instead of using an ICryptoTransform we use an IAuthenticatedCryptoTrasform&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// which provides access to the authentication tag.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; ms = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;IAuthenticatedCryptoTransform&lt;/span&gt; encryptor = aes.CreateAuthenticatedEncryptor())&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt; cs = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt;(ms, encryptor, &lt;span style="color: #2b91af"&gt;CryptoStreamMode&lt;/span&gt;.Write))&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Encrypt the secret message&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] plaintext = &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetBytes(&lt;span style="color: #a31515"&gt;"Secret data to be encrypted and authenticated."&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.Write(plaintext, 0, plaintext.Length);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Finish the encryption and get the output authentication tag and ciphertext&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.FlushFinalBlock();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tag = encryptor.GetTag();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ciphertext = ms.ToArray();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Notice how the tag is accessed by calling GetTag on the IAuthenticatedCryptoTransform after we've completed all encryption and flushed the final block.&amp;nbsp; If GetTag is called before this, it will throw an InvalidOperaitonException as AuthenticatedAesCng does not support generating partial tags for partially encrypted data.&amp;nbsp; Also, encryption will notably not set the Tag property of the AuthenticatedAesCng object which was used to create the encryptor.&amp;nbsp; (The tag is an output, not an input, and therefore does not get propagated back to the AuthenticatedAesCng object which acts like a crypto transform factory).&lt;/p&gt; &lt;h2&gt;Setting up an Authenticated AES Decryptor&lt;/h2&gt; &lt;p&gt;Setting up an authenticated AES object to do decryption is very similar to setting one up to do encryption.&amp;nbsp; The Key, IV, AuthenticationData, and CngMode all need to be setup to match the parameters in place when the ciphertext being decrypted was encrypted.&amp;nbsp; The only additional property that needs to be set is the Tag property.&amp;nbsp; Unsurprisingly, this should be set to be the output of the GetTag call on the encryptor.&lt;/p&gt; &lt;p&gt;We'll end up with decryption code along the lines of:&lt;/p&gt; &lt;p&gt; &lt;div style="border-bottom: black thin inset; border-left: black thin inset; padding-bottom: 1em; margin: 1em 1em 1em 2em; padding-left: 1em; padding-right: 1em; font-family: monospace; background: lightgrey; color: black; font-size: 10pt; border-top: black thin inset; border-right: black thin inset; padding-top: 1em"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: green"&gt;// To decrypt, we need to know the nonce, key, additional authenticated data, and&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: green"&gt;// authentication tag.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;AuthenticatedAesCng&lt;/span&gt; aes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;AuthenticatedAesCng&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;{&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Chaining modes, keys, and IVs must match between encryption and decryption&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.CngMode = &lt;span style="color: #2b91af"&gt;CngChainingMode&lt;/span&gt;.Ccm;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.Key = key;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.IV = nonce;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// If the authenticated data does not match between encryption and decryption, then the&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// authentication tag will not match either, and the decryption operation will fail.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.AuthenticatedData = &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetBytes(&lt;span style="color: #a31515"&gt;"Additional authenticated data"&lt;/span&gt;);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// The tag that was generated during encryption gets set here as input to the decryption&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// operation.&amp;nbsp; This is in contrast to the encryption code path which does not use the&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Tag property (since it is an output from encryption).&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; aes.Tag = tag;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// Decryption works the same as standard symmetric encryption&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt; ms = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MemoryStream&lt;/span&gt;())&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt; cs = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CryptoStream&lt;/span&gt;(ms, aes.CreateDecryptor(), &lt;span style="color: #2b91af"&gt;CryptoStreamMode&lt;/span&gt;.Write))&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.Write(ciphertext, 0, ciphertext.Length);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// If the authentication tag does not match, we'll fail here with a&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: green"&gt;// CryptographicException, and the ciphertext will not be decrypted.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cs.FlushFinalBlock();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] plaintext = ms.ToArray();&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;"Decrypted and authenticated message: {0}"&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Encoding&lt;/span&gt;.UTF8.GetString(plaintext));&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt; &lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;If the authentication tag generated while decrypting the ciphertext (taking into account any optional authenticated data provided), then an exception will be thrown when decryption is completed.&amp;nbsp; The decryptor will also not produce any plaintext until the authentication tag is verified - this way partial plaintext cannoot be used if the authentication tag does not match.&lt;/p&gt; &lt;p&gt;Now that we're using AuthenticatedAesCng to do our encryption, the scenario where someone tampers the ciphertext no longer works.&amp;nbsp; While we won't be able to access the corrupted plaintext anymore, we also will be unable to mistake it for valid plaintext.&amp;nbsp; If the authentication tag does not match while decrypting (most commonly because the ciphertext was tampered with or the authenticated data was not correct), the following exception is thrown:&lt;/p&gt; &lt;p&gt; &lt;div style="border-bottom: black thin inset; border-left: black thin inset; padding-bottom: 1em; margin: 1em 1em 1em 2em; padding-left: 1em; padding-right: 1em; font-family: monospace; background: lightgrey; color: black; font-size: 10pt; border-top: black thin inset; border-right: black thin inset; padding-top: 1em"&gt;Unhandled Exception: System.Security.Cryptography.CryptographicException: The computed authentication tag did not match the input authentication tag.&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; at Security.Cryptography.BCryptNative.SymmetricDecrypt(SafeBCryptKeyHandle key, Byte[] input, Byte[] chainData, BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO&amp;amp; authenticationInfo)&lt;br&gt;&amp;nbsp;&amp;nbsp; at Security.Cryptography.BCryptAuthenticatedSymmetricCryptoTransform.CngTransform(Byte[] input, Int32 inputOffset, Int32 inputCount)&lt;br&gt;&amp;nbsp;&amp;nbsp; at Security.Cryptography.BCryptAuthenticatedSymmetricCryptoTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Security.Cryptography.CryptoStream.FlushFinalBlock()&lt;/div&gt; &lt;h2&gt;Security.Cryptography.Debug Support&lt;/h2&gt; &lt;p&gt;The Security.Cryptography.Debug library has also been updated on the Codeplex in order to support the same type of debugging of AuthenicatedSymmetricAlgorithm objects that was already supported for SymmetricAlgorithm objects.&amp;nbsp; This support is enabled in the v1.1 release and higher of Security.Cryptography.Debug.dll - but since it requires a dependency on the Security.Cryptography.dll library, it is not enabled in the FxOnly builds.&amp;nbsp; Instead, you'll need to download the full binary package or build the sources manually to get the AuthenticatedSymmetricAlgorithm debugging support.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9484740" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CNG/default.aspx">CNG</category></item><item><title>MD5 on Silverlight</title><link>http://blogs.msdn.com/shawnfa/archive/2008/12/09/md5-on-silverlight.aspx</link><pubDate>Wed, 10 Dec 2008 04:39:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9188680</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/9188680.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=9188680</wfw:commentRss><description>&lt;p&gt;Reid Borsuk, an SDE/T on the CLR security team, has released &lt;a href="http://code.msdn.microsoft.com/SilverlightMD5"&gt;a fully transparent implementation of the MD5 hash algorithm to the MSDN Code Gallery&lt;/a&gt;.&amp;#160; Since the code is entirely transparent, it can be used as part of a Silverlight application that needs to compute MD5 hashes in order to interop with existing code or file formats that requires MD5.&lt;/p&gt;  &lt;p&gt;He's also released an MD5Managed type to wrap around his implementation, in case you want to plug the algorithm into the standard .NET hash object model.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9188680" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>CryptoConfig</title><link>http://blogs.msdn.com/shawnfa/archive/2008/12/02/cryptoconfig.aspx</link><pubDate>Wed, 03 Dec 2008 01:26:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9166558</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/9166558.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=9166558</wfw:commentRss><description>&lt;p&gt;The crypto config schema has been a bit of a hot topic around here lately, specifically around how to modify the CLR's machine.config to get custom crypto types registered with CryptoConfig.&lt;/p&gt; &lt;p&gt;Let's take a quick look at what CryptoConfig is first, and then we'll see how to customize its behavior.&amp;nbsp; &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptoconfig.aspx"&gt;CryptoConfig&lt;/a&gt; is a type in mscorlib which allows cryptography classes to be created from a string rather than using a hard coded type.&amp;nbsp; For instance, you can say:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;HashAlgorithm&lt;/span&gt; hashAlgorithm = &lt;span style="color: #2b91af"&gt;CryptoConfig&lt;/span&gt;.CreateFromName(&lt;span style="color: #a31515"&gt;"SHA256Managed"&lt;/span&gt;) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;HashAlgorithm&lt;/span&gt;;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;to create instances of crypto types. This means that rather than having to hard code algorithms and implementations into your assembly itself, you can accept the name of the algorithm as a configuration parameter to achieve some measure of crypto agility.&amp;nbsp; CryptoConfig is also the underlying mechanism that allows the algorithm factory methods to work.&amp;nbsp; For instance, the above snippet is more commonly written as:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;HashAlgorithm&lt;/span&gt; hashAlgorithm = &lt;span style="color: #2b91af"&gt;HashAlgorithm&lt;/span&gt;.Create(&lt;span style="color: #a31515"&gt;"SHA256Managed"&lt;/span&gt;);&lt;/p&gt;&lt;/div&gt; &lt;p&gt;CryptoConfig comes built in with names of algorithms that ship with the .NET Framework (with the exception of the &lt;a href="http://blogs.msdn.com/shawnfa/archive/2007/01/17/new-crypto-algorithms-in-orcas.aspx"&gt;new algorithms introduced in .NET 3.5&lt;/a&gt; due to red bits / green bits restrictions).&amp;nbsp; You can also extend the names that CryptoConfig understands if you have your own algorithms that you would like to be createable by name.&amp;nbsp; In fact, you can even do this to get the .NET 3.5 algorithms registered.&lt;/p&gt; &lt;p&gt;The customizable algorithm name mappings are setup in the machine.config file in the config subdirectory of the CLR installation directory.&amp;nbsp; For instance, for the 32 bit .NET 2.0, 3.0, and 3.5 releases you would register your types in the %WINDIR%\Microsoft.NET\Framework\v2.0.50727\config\machine.config file.&amp;nbsp; (For the 64 bit versions, you would also need to modify the equivalent file in Framework64).&lt;/p&gt; &lt;p&gt;CryptoConfig looks for information in the configuration/mscorlib/cryptographySettings element of machine.config. If there are multiple mscorlib sections, then crypto config prefers one with a version attribute that matches the current runtime -- however, in general there is only one mscorlib element.&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mscorlib&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptographySettings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoNameMapping&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green"&gt; name mappings &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoNameMapping&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;oidMap&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green"&gt; OID mappings &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;oidMap&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptographySettings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;mscorlib&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Name mappings are created in a nameMappings element under cryptographySettings.&amp;nbsp; In order to setup a name mapping, two steps are required:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Map the implementation type to an alias by registering it as a crypto class  &lt;li&gt;Map the alias to the name that you wish to use in CryptoConfig to create an instance of the class.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;For example, imagine that you want to register the SHA256CryptoServiceProvider type that shipped in .NET 3.5 to be able to be created with the strings "SHA256", "SHA256CryptoServiceProvider", and "System.Security.Cryptography.SHA256ServiceProvider".&amp;nbsp; The first step is to register SHA256CryptoServiceProvider as a crypto class.&amp;nbsp; We can do this by creating a cryptoClasses node within the cryptoNameMapping element:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoClasses&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoClass&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;SHA256CSP&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Security.Cryptography.SHA256CryptoServiceProvider, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoClasses&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;This creates an alias of SHA256CSP that refers to the SHA256CryptoServiceProvier type in System.Core.dll.&amp;nbsp; Note that the assemblies used in CryptoConfig must reside in the GAC; in this case System.Core.dll is in the GAC so registering SHA256CryptoServiceProvider is valid.&lt;/p&gt; &lt;p&gt;Now that we have created an alias we need to setup some names to create it with at runtime.&amp;nbsp; These names are created using nameEntry elements in the cryptoNameMapping element:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;nameEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CSP&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;nameEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CryptoServiceProvider&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CSP&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;nameEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Security.Cryptography.SHA256CryptoServiceProvider&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CSP&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Each nameEntry element maps a string which CryptoConfig will accept to the alias for the type that it will create.&amp;nbsp; Here, we've setup entries that allow CryptoConfig to create a SHA256CryptoServiceProvier object via the names "SHA256", "SHA256CryptoServiceProvider", and "System.Security.Cryptography.SHA256CryptoServiceProvider".&lt;/p&gt; &lt;p&gt;If you're paying close attention, you'll notice that I mapped SHA256 to the .NET 3.5 SHA256CryptoServiceProvider class, even though the CLR already has a built in mapping for SHA256 to the SHA256Managed class.&amp;nbsp; In the case of a collision like this, machine.config entries take precedence over the built in mappings so these entries have the effect of changing the result of HashAlgorithm.Create("SHA256") from being a SHA256Managed object to being a SHA256CryptoServiceProvider object.&lt;/p&gt; &lt;p&gt;The final XML we ended up with for this example looks like this:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green"&gt; ... other configuration data ... &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mscorlib&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="color: green"&gt; ... other configuration data ... &lt;/span&gt;&lt;span style="color: blue"&gt;--&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptographySettings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoNameMapping&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoClasses&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoClass&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;SHA256CSP&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Security.Cryptography.SHA256CryptoServiceProvider, System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoClasses&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;nameEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CSP&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;nameEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CryptoServiceProvider&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CSP&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;nameEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;System.Security.Cryptography.SHA256CryptoServiceProvider&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;class&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256CSP&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptoNameMapping&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;cryptographySettings&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;mscorlib&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;A couple of other small crypto config notes:&lt;/p&gt; &lt;p&gt;Above I mentioned that there is the ability to setup OID mappings - this allows you to add entries to the results returned from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptoconfig.mapnametooid.aspx"&gt;CryptoConfig.MapNameToOid&lt;/a&gt; API.&amp;nbsp; These entries go in the oidMap element and are simple name -&amp;gt; OID pairs.&amp;nbsp; Like name map entries above, machine.config values take precedence over built-in values:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;oidMap&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;oidEntry&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;OID&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;2.16.840.1.101.3.4.2.1&lt;/span&gt;"&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;SHA256&lt;/span&gt;"&lt;span style="color: blue"&gt; /&amp;gt;&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;oidMap&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Generally this is much less useful than the name mappings, since it really only allows you to access your custom OIDs via MapNameToOid -- however it's there if you do want to add custom name-&amp;gt;OID pairs.&lt;/p&gt; &lt;p&gt;A final note is that although CryptoConfig itself doesn't have an API to modify the mappings at runtime, it is sometimes a lot more convenient to programmatically add crypto name mappings for your application at runtime than to worry about getting all the machine.config XML correctly added at installation time.&amp;nbsp; This can be done with the &lt;a href="http://www.codeplex.com/clrsecurity/Wiki/View.aspx?title=Security.Cryptography.CryptoConfig2"&gt;CryptoConfig2&lt;/a&gt; class from the &lt;a href="http://www.codeplex.com/clrsecurity/Wiki/View.aspx?title=Security.Cryptography.dll"&gt;Security.Cryptography library&lt;/a&gt; on CodePlex.&lt;/p&gt; &lt;p&gt;CryptoConfig2 already has mappings for the .NET 3.5 types, but for the sake of an example the registration from the XML above could be done via code such as:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;CryptoConfig2&lt;/span&gt;.AddAlgorithm(&lt;span style="color: blue"&gt;typeof&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;SHA256CryptoServiceProvider&lt;/span&gt;),&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515"&gt;"SHA256"&lt;/span&gt;,&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515"&gt;"SHA256CryptoServiceProvider"&lt;/span&gt;,&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: #a31515"&gt;"System.Security.Cryptography.SHA256CryptoServiceProvider"&lt;/span&gt;);&lt;/p&gt;&lt;/div&gt; &lt;p&gt;Since CryptoConfig2 does not modify the built-in CryptoConfig mappings, these aliases would be used like this:&lt;/p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: #2b91af"&gt;HashAlgorithm&lt;/span&gt; hashAlgorithm = &lt;span style="color: #2b91af"&gt;CryptoConfig2&lt;/span&gt;.CreateFromName(&lt;span style="color: #a31515"&gt;"SHA256"&lt;/span&gt;) &lt;span style="color: blue"&gt;as&lt;/span&gt; &lt;span style="color: #2b91af"&gt;HashAlgorithm&lt;/span&gt;;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;instead of going through the built in CryptoConfig or Create methods.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9166558" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item><item><title>Using RSACryptoServiceProvider for RSA-SHA256 signatures</title><link>http://blogs.msdn.com/shawnfa/archive/2008/08/25/using-rsacryptoserviceprovider-for-rsa-sha256-signatures.aspx</link><pubDate>Mon, 25 Aug 2008 21:09:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8894546</guid><dc:creator>shawnfa</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/8894546.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=8894546</wfw:commentRss><description>&lt;p&gt;Earlier this month, &lt;a href="http://blogs.msdn.com/somasegar/archive/2008/08/11/service-pack-1-for-vs-2008-and-net-fx-3-5-released.aspx"&gt;we released .NET 3.5 SP 1&lt;/a&gt;.&amp;#160; One of the new features available in this update is that RSACryptoServiceProvider has gained the ability to create and verify RSA-SHA256 signatures.&lt;/p&gt;  &lt;p&gt;Since RSACryptoServiceProvider relies on the underlying CAPI APIs to do its work, this feature will only be enabled on versions of Windows which support SHA-256 algorithms in CAPI.&amp;#160; At this point, that translates to Windows Server 2003 and higher.&lt;/p&gt;  &lt;p&gt;The code to create and verify a signature is basically the same as it was for doing RSA-SHA1:&lt;/p&gt;  &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt;   &lt;pre style="margin: 0px"&gt;&lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;byte&lt;/span&gt;[] data = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] { 0, 1, 2, 3, 4, 5 };&lt;/p&gt;&lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;using&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;RSACryptoServiceProvider&lt;/span&gt; rsa = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;RSACryptoServiceProvider&lt;/span&gt;())&lt;/p&gt;&lt;p style="margin: 0px"&gt;{&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;byte&lt;/span&gt;[] signature = rsa.SignData(data, &lt;span style="color: #a31515"&gt;&amp;quot;SHA256&amp;quot;&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; (rsa.VerifyData(data, &lt;span style="color: #a31515"&gt;&amp;quot;SHA256&amp;quot;&lt;/span&gt;, signature))&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;RSA-SHA256 signature verified&amp;quot;&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: #2b91af"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color: #a31515"&gt;&amp;quot;RSA-SHA256 signature failed to verify&amp;quot;&lt;/span&gt;);&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;&lt;p style="margin: 0px"&gt;}&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The second parameter should be either the string &amp;quot;SHA256&amp;quot;, the type of the SHA256Managed object, or an instance of a SHA256Managed object.&lt;/p&gt;

&lt;p&gt;Note that this means, somewhat counter-intuitively, that passing either the type of or an instance of the SHA256CryptoServiceProvider object will not work.&amp;#160; If you do use the SHA256CryptoServiceProvider type, you'll end up with an error like this:&lt;/p&gt;

&lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt;
  &lt;pre style="margin: 0px"&gt;&lt;p style="margin: 0px"&gt;Unhandled Exception: System.ArgumentException: Value was invalid.&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160; at System.Security.Cryptography.Utils.ObjToOidValue(Object hashAlg)&lt;/p&gt;&lt;p style="margin: 0px"&gt;&amp;#160;&amp;#160; at System.Security.Cryptography.RSACryptoServiceProvider.SignData(Byte[] buffer, Object halg)&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The reason for this is the same reason that CryptoConfig does not understand SHA256CryptoServiceProvider - it was added as &lt;a href="http://blogs.msdn.com/shawnfa/archive/2007/01/17/new-crypto-algorithms-in-orcas.aspx"&gt;part of the green bits in .NET 3.5&lt;/a&gt;, and due to layering restrictions the red bits (such as mscorlib.dll where RSACryptoServiceProvider lives) does not know about its existence.&lt;/p&gt;

&lt;p&gt;Also note that this functionality was added only to the RSACryptoServiceProvider type, so upstack functionality such as XML digital signatures are not yet enabled for RSA-SHA256 digital signatures.&amp;#160; However, this does provide the base building block for those upstack crypto technologies, so that they can begin adding support in the future.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8894546" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item><item><title>CLR Security Team CodePlex Site</title><link>http://blogs.msdn.com/shawnfa/archive/2008/07/10/clr-security-team-codeplex-site.aspx</link><pubDate>Thu, 10 Jul 2008 22:20:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8718287</guid><dc:creator>shawnfa</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/8718287.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=8718287</wfw:commentRss><description>&lt;p&gt;The CLR Security Team just launched our CodePlex site: &lt;a href="http://www.codeplex.com/clrsecurity"&gt;http://www.codeplex.com/clrsecurity&lt;/a&gt;.&amp;#160; Currently, it contains two assemblies that provide additional functionality to the security APIs shipped in v3.5 of the .NET Framework.&lt;/p&gt;  &lt;p&gt;We'd love your feedback on the currently offered libraries, and also welcome ideas for other libraries you'd like to see on our CodePlex site.&amp;#160; &lt;/p&gt;  &lt;p&gt;From the description page on the site, the two current libraries are:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codeplex.com/clrsecurity/Wiki/View.aspx?title=Security.Cryptography.dll&amp;amp;referringTitle=Home"&gt;&lt;strong&gt;Security.Cryptography.dll&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Security.Cryptography.dll provides a new set of algorithm implementations to augment the built in .NET framework supported algorithms. It also provides some APIs to extend the existing framework cryptography APIs. Within this project you will find:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;A CNG implementation of the AES, RSA, and TripleDES encryption algorithms &lt;/li&gt;    &lt;li&gt;A CNG implementation of a random number generator &lt;/li&gt;    &lt;li&gt;A class that allows dynamically creating algorithms both from this library as well as all of the algorithms that ship with .NET 3.5 &lt;/li&gt;    &lt;li&gt;An enumerator over all of the installed CNG providers on the current machine &lt;/li&gt;    &lt;li&gt;Extension methods that allow access to all of the keys installed in a CNG provider, as well as all of the algorithms the provider supports &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;a href="http://www.codeplex.com/clrsecurity/Wiki/View.aspx?title=Security.Cryptography.Debug.dll&amp;amp;referringTitle=Home"&gt;&lt;strong&gt;Security.Cryptography.Debug.dll&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Have you ever run into an indecipherable cryptographic exception complaining about &amp;quot;Padding is invalid and cannot be removed&amp;quot; when using the .NET Framework's symmetric algorithms? Since nearly all bugs relating to symmetric algorithms tend to result in this same exception, it can be incredibly difficult to track down exactly what went wrong to cause the exception. Security.Cryptography.Debug.dll is a tool that can be used in these circumstances in order to help you figure out the root cause of your cryptographic exception.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8718287" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Debugging/default.aspx">Debugging</category></item><item><title>Disabling the FIPS Algorithm Check</title><link>http://blogs.msdn.com/shawnfa/archive/2008/03/14/disabling-the-fips-algorithm-check.aspx</link><pubDate>Fri, 14 Mar 2008 17:00:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8191587</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/8191587.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=8191587</wfw:commentRss><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx"&gt;.NET 2.0 introduced a check for FIPS certified algorithms&lt;/a&gt; if your local security policy was configured to require them.&amp;nbsp; This resulted in algorithms which are not FIPS compliant (or implementations which were not FIPS certified) throwing an InvalidOperationException from their constructors.&lt;/p&gt; &lt;p&gt;In some cases this isn't a desirable behavior.&amp;nbsp; For instance, some applications need to use the MD5 hashing algorithm for compatibility with an older communication protocol or file format.&amp;nbsp; Prior to .NET 3.5, the AES algorithm was only available in an implementation which was not FIPS certified, and if you needed to use that algorithm the FIPS check could also block you.&lt;/p&gt; &lt;p&gt;To help these cases, we added a configuration file switch to .NET 2.0 SP 1 (and therefore .NET 3.5) which allows an application to say "I know what I'm doing, please don't enforce FIPS for me".&amp;nbsp; For these applications, they can setup a configuration file similar to:&lt;/p&gt; &lt;p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: monospace"&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;runtime&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;enforceFIPSPolicy&lt;/span&gt;&lt;span style="color: blue"&gt; &lt;/span&gt;&lt;span style="color: red"&gt;enabled&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;false&lt;/span&gt;"&lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;runtime&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;configuration&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Which will prevent the CLR from throwing InvalidOperationExceptions from the constructor of uncertified algorithms and implementations.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8191587" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Windows/default.aspx">Windows</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Orcas/default.aspx">Orcas</category></item><item><title>CLR Inside Out: Digging into IDisposable</title><link>http://blogs.msdn.com/shawnfa/archive/2007/06/20/clr-inside-out-digging-into-idisposable.aspx</link><pubDate>Wed, 20 Jun 2007 19:10:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:3427140</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/3427140.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=3427140</wfw:commentRss><description>&lt;p&gt;My third MSDN magazine article, &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/07/CLRInsideOut/default.aspx"&gt;Digging into IDisposable&lt;/a&gt;,&amp;nbsp;appeared in &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/07/default.aspx"&gt;this month's issue&lt;/a&gt;&amp;nbsp;in the CLR Inside Out Column.&amp;nbsp; It's a bit of a departure from my usual security fare; this time looking at how to best handle writing class libraries that must manage resources.&lt;/p&gt; &lt;p&gt;Also in this month's issue, &lt;a href="http://weblogs.asp.net/kennykerr/"&gt;Kenny Kerr&lt;/a&gt; provides a good &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/07/Security/default.aspx"&gt;introduction to the new CNG APIs available on Vista&lt;/a&gt;.&amp;nbsp; Especially interesting is the code snippets he provides translating from CNG RSA keys to RSAParameters for use with RSACryptoServiceProvider.&amp;nbsp; (And for a quick rundown of the managed CNG classes Kenny mentions in the v3.5 framework, you can see the posts in my &lt;a href="http://blogs.msdn.com/shawnfa/archive/tags/CNG/default.aspx"&gt;CNG category&lt;/a&gt;).&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=3427140" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Other/default.aspx">Other</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CNG/default.aspx">CNG</category></item><item><title>Please do not use the .NET 2.0 HMACSHA512 and HMACSHA384 Classes</title><link>http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-hmacsha512-and-hmacsha384-classes.aspx</link><pubDate>Wed, 31 Jan 2007 21:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1566561</guid><dc:creator>shawnfa</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/1566561.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=1566561</wfw:commentRss><description>&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;We’ve recently discovered a bug in the HMACSHA512 and HMACSHA384 classes which shipped in the .NET Framework 2.0.&amp;nbsp; This bug will cause&amp;nbsp;these algorithms to produce incorrect results&amp;nbsp;which are not consistent with other implementations of HMAC-SHA-512 and HMAC-SHA-384.&amp;nbsp; Unfortunately, we did not discover this bug until recently, and the shipping .NET Framework 2.0 on all platforms is affected by it.&amp;nbsp; The only two affected algorithms are the HMAC-SHA-512 and HMAC-SHA-384; other HMAC algorithms do produce correct values. 
&lt;P&gt;The next service pack to the .NET Framework will contain a fix for this bug, which will cause the HMACSHA384 and HMACSHA512 classes to produce correct HMAC values.&amp;nbsp; However, this will cause their output to be inconsistent with the output of&amp;nbsp;the unserviced .NET Framework 2.0 classes.&amp;nbsp; In order to allow applications running on serviced framework to interact with applications running on the unserviced version, we will introduce two compatibility switches in the service pack. 
&lt;P&gt;First, both the HMACSHA512 and HMACSHA384 classes will have a new Boolean property, ProduceLegacyHmacValues.&amp;nbsp; By setting this property to true, the object will produce values which match what the unserviced .NET Framework would have produced.&amp;nbsp; You should set this property only once after you’ve created your HMAC object, and you will need to reset your key afterwards: 
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; Test()&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: #2b91af"&gt;HMACSHA512&lt;/SPAN&gt; hmac = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;HMACSHA512&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; hmac.ProduceLegacyHmacValues = &lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; hmac.Key = &lt;SPAN style="COLOR: green"&gt;// ... get the hmac key&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// ...&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// use the hmac algorithm&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// ...&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In order to help applications where it is expensive or impossible to change the code, we’ve added a new configuration switch for the application’s .exe.config file which will cause all HMAC objects created within the application to use the unserviced calculation. 
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;runtime&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;legacyHMACMode&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;enabled&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;1&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;runtime&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Finally, in order to help debug any issues that arise when upgrading to the service pack, the first time an instance of either class is created, we will log a warning message to the event log and to any attached debugger.&amp;nbsp; The message text (which will hopefully help to point search engine results here as well) will be: 
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;"This application is using the HMAC-SHA-384 or HMAC-SHA-512 keyed hash algorithm. The implementation of these algorithms were updated in service pack 1 of .NET Framework 2.0 and by default do not produce results consistent with the unserviced versions of the classes. For more information about the changes to the algorithms and how to disable this warning message please see the release notes for service pack 1."&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This warning will only be produced the first time an instance of either object is created in a process.&amp;nbsp; If the configuration switch to enable process-wide legacy mode is set, then we will suppress the message.&amp;nbsp; We’ve also provided a second configuration switch which will let you manually suppress the warning message for your application. 
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;runtime&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;legacyHMACWarning&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: red"&gt;enabled&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;=&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt;0&lt;/SPAN&gt;"&lt;SPAN style="COLOR: blue"&gt; /&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;runtime&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #a31515"&gt;configuration&lt;/SPAN&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you need a replacement class for HMACSHA512 before the next service pack ships, then you can roll your own relatively easily.&amp;nbsp; Some code to do this would look like this: 
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;sealed&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; MyHmacSha512 : System.Security.Cryptography.&lt;SPAN style="COLOR: #2b91af"&gt;HMAC&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; MyHmacSha512(&lt;SPAN style="COLOR: blue"&gt;byte&lt;/SPAN&gt;[] key)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (key == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"key"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; HashName = &lt;SPAN style="COLOR: #a31515"&gt;"SHA512"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; HashSizeValue = 512;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BlockSizeValue = 128;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Key = key;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Similarly, a substitute class can be derived for HMACSHA384: 
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;internal&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;sealed&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;class&lt;/SPAN&gt; MyHmacSha384 : System.Security.Cryptography.&lt;SPAN style="COLOR: #2b91af"&gt;HMAC&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;{&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; MyHmacSha384(&lt;SPAN style="COLOR: blue"&gt;byte&lt;/SPAN&gt;[] key)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (key == &lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: #2b91af"&gt;ArgumentNullException&lt;/SPAN&gt;(&lt;SPAN style="COLOR: #a31515"&gt;"key"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; HashName = &lt;SPAN style="COLOR: #a31515"&gt;"SHA384"&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; HashSizeValue = 384;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; BlockSizeValue = 128;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; Key = key;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;}&lt;/P&gt;&lt;/DIV&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This change will start to appear in future CTPs.&amp;nbsp; Again, I personally, and the CLR security team in general, are very sorry for any problems this may have caused in your applications.&amp;nbsp; Please feel free to ask any questions in the comments for this post, and I’ll make sure that they get answered as soon as possible.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1566561" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item><item><title>Elliptic Curve Diffie-Hellman</title><link>http://blogs.msdn.com/shawnfa/archive/2007/01/22/elliptic-curve-diffie-hellman.aspx</link><pubDate>Tue, 23 Jan 2007 00:58:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1509885</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/1509885.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=1509885</wfw:commentRss><description>&lt;p&gt;The second elliptic curve algorithm added to Orcas is elliptic curve Diffie-Hellman, as the ECDiffieHellmanCng class.&lt;/p&gt; &lt;p&gt;This is the first time Diffie-Hellman is available as part of the .NET Framework, so lets take a quick look at what it is and what it does.&amp;nbsp; Diffie-Hellman is one of the oldest asymmetric algorithms, however unlike the other asymmetric algorithms in the framework today, it does not perform encryption or digital signatures.&amp;nbsp; Instead it allows two parties to exchange private key material even if they only can communicate through a completely public channel.&amp;nbsp; (In &lt;em&gt;&lt;a href="http://www.amazon.com/Network-Security-Private-Communication-Public/dp/0130614661"&gt;Network Security: Private Communication in a Public World&lt;/a&gt;&lt;/em&gt;, an amusing example is given where Diffie-Hellman is performed by two parties taking out ads in the local newspaper).&lt;/p&gt; &lt;p&gt;Key exchange is somewhat of a misleading term, since it implies that one party to the communication generates a key and via the communication protocol lets the other party know what that key is.&amp;nbsp; Instead what really happens is that Diffie-Hellman allows both parties to calculate the same secret value, which is referred to as the secret agreement in the managed Diffie-Hellman classes.&amp;nbsp; This secret agreement can then be used for any number of purposes, including being used as a symmetric key.&lt;/p&gt; &lt;p&gt;Instead of exposing the secret agreement directly however, the ECDiffieHellmanCng class does some post-processing on the agreement before letting the value out.&amp;nbsp; We refer to this post processing as the key derivation function; you can select which KDF you want to use and set its parameters via a set of properties on the instance of the Diffie-Hellman object:&lt;/p&gt; &lt;p&gt; &lt;table border="2"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;&lt;b&gt;Key Derivation Function&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Properties&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Meaning&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td rowspan="3"&gt;Hash&lt;/td&gt; &lt;td&gt;HashAlgorithm&lt;/td&gt; &lt;td&gt;Hash algorithm to process the secret agreement with&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SecretPrepend&lt;/td&gt; &lt;td&gt;Optional byte array to prepend to the secret agreement before hashing it&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SecretAppend&lt;/td&gt; &lt;td&gt;Optional byte array to append to the secret agreement before hashing it&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td rowspan="4"&gt;Hmac&lt;/td&gt; &lt;td&gt;HashAlgortihm&lt;/td&gt; &lt;td&gt;Hash algorithm to process the secret agreement with (using the HMAC version of the algorithm).&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;HmacKey&lt;/td&gt; &lt;td&gt;Key used for the HMAC operation&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SecretPrepend&lt;/td&gt; &lt;td&gt;Optional byte array to prepend to the secret agreement before hashing it&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;SecretAppend&lt;/td&gt; &lt;td&gt;Optional byte array to append to the secret agreement before hashing it&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td rowspan="2"&gt;Tls&lt;/td&gt; &lt;td&gt;Label&lt;/td&gt; &lt;td&gt;&lt;a href="http://www.ietf.org/rfc/rfc2246.txt?number=2246"&gt;TLS PRF Label&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Seed&lt;/td&gt; &lt;td&gt;&lt;a href="http://www.ietf.org/rfc/rfc2246.txt?number=2246"&gt;TLS PRF Seed&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt; &lt;p&gt;The result of passing the secret agreement through the key derivation function is a byte array that may be used as key material for your application.&amp;nbsp; The number of bytes of key material generated is dependent on the key derivation function, for instance SHA-256 will generate 256 bits of key material, while SHA-512 will generate 512 bits of key material.&lt;/p&gt; &lt;p&gt;The basic flow of an elliptic curve Diffie-Hellman key exchange is:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Alice and Bob create a key pair to use&amp;nbsp;for the Diffie-Hellman key exchange operation  &lt;li&gt;Alice and Bob configure the KDF using agreed upon parameters  &lt;li&gt;Alice sends Bob her public key  &lt;li&gt;Bob sends Alice his public key  &lt;li&gt;Using each other's public keys, the secret agreement is generated, and the KDF is applied to the secret agreement generating key material.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In code, this looks basically as you would expect:&lt;/p&gt; &lt;p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: consolas"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: teal"&gt;ECDiffieHellmanCng&lt;/span&gt; alice = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;ECDiffieHellmanCng&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px"&gt;alice.KeyDerivationFunction = &lt;span style="color: teal"&gt;ECDiffieHellmanKeyDerivationFunction&lt;/span&gt;.Hash;&lt;/p&gt; &lt;p style="margin: 0px"&gt;alice.HashAlgorithm = &lt;span style="color: teal"&gt;CngAlgorithm&lt;/span&gt;.Sha256;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: teal"&gt;ECDiffieHellmanCng&lt;/span&gt; bob = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;ECDiffieHellmanCng&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px"&gt;bob.KeyDerivationFunction = &lt;span style="color: teal"&gt;ECDiffieHellmanKeyDerivationFunction&lt;/span&gt;.Hash;&lt;/p&gt; &lt;p style="margin: 0px"&gt;bob.HashAlgorithm = &lt;span style="color: teal"&gt;CngAlgorithm&lt;/span&gt;.Sha256;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&amp;nbsp;&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;byte&lt;/span&gt;[]&amp;nbsp;bobKey = bob.DeriveKeyMaterial(alice.PublicKey);&lt;/p&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;byte&lt;/span&gt;[]&amp;nbsp;aliceKey = alice.DeriveKeyMaterial(bob.PublicKey);&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;After running this code, aliceKey and&amp;nbsp;bobKey are both 32 bytes long and match each other.&amp;nbsp; Now, Alice could use this as a symmetric key:&lt;/p&gt; &lt;p&gt; &lt;div style="border-right: black thin inset; padding-right: 1em; border-top: black thin inset; padding-left: 1em; font-size: 10pt; background: lightgrey; padding-bottom: 1em; margin: 1em 1em 1em 2em; border-left: black thin inset; color: black; padding-top: 1em; border-bottom: black thin inset; font-family: consolas"&gt; &lt;p style="margin: 0px"&gt;&lt;span style="color: teal"&gt;AesCryptoServiceProvider&lt;/span&gt; aes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: teal"&gt;AesCryptoServiceProvider&lt;/span&gt;();&lt;/p&gt; &lt;p style="margin: 0px"&gt;aes.Key = aliceKey;&lt;/p&gt;&lt;/div&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;Obviously, this example is simplified as both Alice and Bob are unlikely to be running in the same process.&amp;nbsp; ECDiffieHellmanPublicKey, which is the class returned by the PublicKey property is Serializable, so that it may be sent across any remoting channel.&amp;nbsp; It also can be manually converted to and from a byte array and XML, allowing for manual serialization in advanced use cases.&lt;/p&gt; &lt;p&gt;One thing to note about Diffie-Hellman is that it only guarantees that both parties are generating a secret that nobody else knows about.&amp;nbsp; It does not let either party know the identity of the other.&amp;nbsp; For instance, in the above code, Alice cannot be sure that the other person in the conversation is Bob; there could potentially be a man-in-the-middle attack here.&lt;/p&gt; &lt;p&gt;In order to solve that, Alice or Bob could use a well-known public key that is distributed by PKI (you can pass a CngKey to the DeriveKeyMaterial API in this case).&amp;nbsp; You could also use HMAC as the KDF and a key that you know only Alice and Bob share to solve this problem.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1509885" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Orcas/default.aspx">Orcas</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CNG/default.aspx">CNG</category></item><item><title>Elliptic Curve DSA</title><link>http://blogs.msdn.com/shawnfa/archive/2007/01/18/elliptic-curve-dsa.aspx</link><pubDate>Thu, 18 Jan 2007 23:05:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1490163</guid><dc:creator>shawnfa</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/1490163.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=1490163</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://blogs.msdn.com/shawnfa/archive/2007/01/17/new-crypto-algorithms-in-orcas.aspx" mce_href="http://blogs.msdn.com/shawnfa/archive/2007/01/17/new-crypto-algorithms-in-orcas.aspx"&gt;Yesterday I gave a quick rundown of all the new cryptographic algorithms available in the Orcas January CTP&lt;/A&gt;.&amp;nbsp; Today, let's dive in a little deeper to the first of the elliptic curve algorithms, ECDSA.&amp;nbsp; (ECDSA, along with the rest of the CNG classes in the .NET Framework, is only available on Windows Vista).&lt;/P&gt;
&lt;P&gt;ECDSA is an implementation of the &lt;A href="http://csrc.nist.gov/cryptval/dss.htm" mce_href="http://csrc.nist.gov/cryptval/dss.htm"&gt;digital signature standard&lt;/A&gt; using elliptic curves, which makes the ECDsaCng class a sort of cousin of the DSACryptoServiceProvider class.&amp;nbsp; Because&amp;nbsp;DSA and ECDSA&amp;nbsp;are cousins rather than just different implementations of the same algorithm, there is a new base class ECDsa that elliptic curve DSA implementations derive from.&amp;nbsp; You also cannot sign some data with DSACryptoServiceProvider and then verify that signature with ECDsaCng.&lt;/P&gt;
&lt;P&gt;Let's take a look at a basic example of using ECDSA:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; FONT-SIZE: 10pt; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: teal"&gt;ECDsaCng&lt;/SPAN&gt; dsa = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: teal"&gt;ECDsaCng&lt;/SPAN&gt;();&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;dsa.HashAlgorithm = &lt;SPAN style="COLOR: teal"&gt;CngAlgorithm&lt;/SPAN&gt;.Sha256;&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;byte&lt;/SPAN&gt;[] data = &lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;byte&lt;/SPAN&gt;[] { 21, 5, 8, 12,&amp;nbsp;2007 };&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;byte&lt;/SPAN&gt;[] signature = dsa.SignData(data);&lt;/P&gt;
&lt;P style="MARGIN: 0px" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (dsa.VerifyData(data, signature))&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: teal"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Verified"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&lt;SPAN style="COLOR: blue"&gt;else&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: teal"&gt;Console&lt;/SPAN&gt;.WriteLine(&lt;SPAN style="COLOR: maroon"&gt;"Not verified"&lt;/SPAN&gt;);&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;First we create a new ECDsaCng object, which will generate a random key for us to use.&amp;nbsp; Next, we setup the hash algorithm to use on the input data when creating the signature.&amp;nbsp; Finally, we can call SignData to create a signature over a blob of data, and VerifyData to verify that the signature is correct.&lt;/P&gt;
&lt;P&gt;There are also SignHash/VerifyHash APIs available -- SignData will essentially just hash the data with the hash algorithm specified on the ECDsaCng object (defaulting to SHA-256) and then do a SignHash on the resulting hash value.&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 1em; BACKGROUND: lightgrey; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; COLOR: black; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset"&gt;&lt;A class="" title=PseudoEnums name=PseudoEnums&gt;&lt;/A&gt;&lt;B&gt;Sidebar: CNG Pseudo-Enums&lt;/B&gt; 
&lt;P&gt;I showed the HashAlgorithm property in the example, even though I was setting it back to the default value, because it uses the CngAlgorithm class which is the first of several pseudo-enums that will show up when you play with the CNG classes.&amp;nbsp; &lt;A href="http://msdn2.microsoft.com/en-us/library/bb204774.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/bb204774.aspx"&gt;CNG itself is very configurable&lt;/A&gt;, and it takes most of its configuration options as strings.&amp;nbsp; With our managed APIs, we didn't want to limit the set of parameters you can pass to CNG to the set that we had predefined a mapping from a traditional enum to a CNG string for.&amp;nbsp; We also wanted to preserve type safety (having everything be a string makes it unclear which strings can go where), and provide pre-defined values for the common cases.&lt;/P&gt;
&lt;P&gt;The result is a set of pseudo-enumerations like CngAlgorithm.&amp;nbsp; CngAlgorithm isn't an enum, it's a class.&amp;nbsp; We've provided a set of CngAlgorithms representing the common algorithm names as static properties, which allow you to use it with enum-like syntax.&amp;nbsp; There's also a CngAlgorithm constructor which takes a string, which means that if you need to use a CNG algorithm that isn't in the list you can construct a CngAlgorithm&amp;nbsp;to reference&amp;nbsp;that algorithm.&lt;/P&gt;
&lt;P&gt;Each of the pseudo enums also behave just as you would expect when dealing with them directly.&amp;nbsp; You can compare them with your language of choice's equality comparison operators, get their hash code, and convert them to their underlying strings.&amp;nbsp; In addition to CngAlgorithm other pseudo-enums you'll find are CngAlgorithmGroup, CngKeyFormat, and CngProvider.&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;The default constructor generates a random key for use with the P-521 curve, described in &lt;A href="http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf" mce_href="http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf"&gt;appendix 6 of FIPS 186-2&lt;/A&gt;.&amp;nbsp; There is also a constructor which accepts the curve you wish to work with; currently ECDsaCng supports P-192, P-256 and P-521. Or, if you don't want to generate a random key&amp;nbsp;you can pass in an existing key to the constructor&amp;nbsp;and it will work with that.&lt;/P&gt;
&lt;P&gt;Incidentally, the CngKey class is your one stop shop for anything to do with CNG keys (stored by NCrypt).&amp;nbsp; You can use this class to create a new random key, open or delete an existing key, get the properties of a key, import / export the key, etc.&amp;nbsp; We also expose a SafeNCryptKeyHandle which represents&amp;nbsp;the underlying NCRYPT_KEY_HANDLE, allowing you to easily P/Invoke for any other functionality not exposed in the CngKey class itself.&lt;/P&gt;
&lt;P&gt;In addition to exporting the ECDSA key&amp;nbsp;via the CngKey&amp;nbsp;property of the&amp;nbsp;ECDsaCng object, you can also export the key into XML.&amp;nbsp; However, since there is currently no standard format for elliptic curve XML, you need to specify which format you want the XML to appear in (not specifying a format will cause an exception).&amp;nbsp; Currently, we only support one option which is the format described in &lt;A href="http://www.ietf.org/rfc/rfc4050.txt" mce_href="http://www.ietf.org/rfc/rfc4050.txt"&gt;RFC 4050&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;So that concludes&amp;nbsp;our whirlwind tour of the ECDsaCng class.&amp;nbsp; Next time we'll take a look at the elliptic curve Diffie-Hellman support in Orcas.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1490163" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Orcas/default.aspx">Orcas</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CNG/default.aspx">CNG</category></item><item><title>New Crypto Algorithms in Orcas</title><link>http://blogs.msdn.com/shawnfa/archive/2007/01/17/new-crypto-algorithms-in-orcas.aspx</link><pubDate>Wed, 17 Jan 2007 21:21:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1484417</guid><dc:creator>shawnfa</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/1484417.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=1484417</wfw:commentRss><description>&lt;P&gt;The &lt;A title="Orcas January CTP" href="http://www.microsoft.com/downloads/details.aspx?familyid=69055927-458B-4129-9047-FCC4FACAE96C&amp;amp;displaylang=en&amp;amp;displaylang=en" mce_href="http://www.microsoft.com/downloads/details.aspx?familyid=69055927-458B-4129-9047-FCC4FACAE96C&amp;amp;displaylang=en&amp;amp;displaylang=en"&gt;January CTP of Orcas is now available&lt;/A&gt;, and with it comes a total of&amp;nbsp;12 new cryptography algorithm implementation classes, which include 2.5 new algorithms.&amp;nbsp; (I'll count AES as 0.5 since we did already have Rijndael :-) ).&amp;nbsp; These classes also are the first set of managed wrappers around the &lt;A title="CNG Reference" href="http://msdn2.microsoft.com/en-us/library/aa376210.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/aa376210.aspx"&gt;new CNG APIs in Windows Vista&lt;/A&gt;, which will use the Cng suffix on the implementation classes.&lt;/P&gt;
&lt;P&gt;Dividing the new algorithms up into their types (all in the System.Security.Cryptography namespace in System.Core.dll), this CTP has:&lt;/P&gt;
&lt;H2&gt;Hash Algorithms&lt;/H2&gt;
&lt;P&gt;
&lt;TABLE class="" border=2&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;Algorithm&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;Class&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;OS Required&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;MD5&lt;/TD&gt;
&lt;TD class=""&gt;MD5Cng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;SHA-1&lt;/TD&gt;
&lt;TD class=""&gt;SHA1Cng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" rowSpan=2&gt;SHA-256&lt;/TD&gt;
&lt;TD class=""&gt;SHA256CryptoServiceProvider&lt;/TD&gt;
&lt;TD class=""&gt;Windows 2003&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;SHA256Cng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" rowSpan=2&gt;SHA-384&lt;/TD&gt;
&lt;TD class=""&gt;SHA384CryptoServiceProvider&lt;/TD&gt;
&lt;TD class=""&gt;Windows 2003&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;SHA384Cng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" rowSpan=2&gt;SHA-512&lt;/TD&gt;
&lt;TD class=""&gt;SHA512CryptoServiceProvider&lt;/TD&gt;
&lt;TD class=""&gt;Windows 2003&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;SHA512Cng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;The hash algorithms work just as you would expect, and should function as simple drop-in replacements for corresponding algorithms that have already shipped in v2.0 of the .NET Framework.&amp;nbsp;&amp;nbsp;The big advantage here is that these hash algorithms are just wrappers around the Windows implementations of the algorithms, and therefore are &lt;A href="http://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx" mce_href="http://blogs.msdn.com/shawnfa/archive/2005/05/16/417975.aspx"&gt;FIPS compliant versions of the SHA-2 algorithms&lt;/A&gt; which had only managed versions in v2.0.&amp;nbsp; For applications targeting Vista which must use CNG, this set of algorithms also provides CNG wrappers for all of our hashing algorithms.&lt;/P&gt;
&lt;H2&gt;Symmetric Algorithms&lt;/H2&gt;
&lt;P&gt;
&lt;TABLE class="" border=2&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;Algorithm&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;Class&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;OS Required&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class="" rowSpan=2&gt;AES&lt;/TD&gt;
&lt;TD class=""&gt;AesCryptoServiceProvider&lt;/TD&gt;
&lt;TD class=""&gt;Windows XP SP2&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;AesManaged&lt;/TD&gt;
&lt;TD class=""&gt;All Supported Platforms&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;We've provided a new Aes base class for implementations of AES (&lt;A href="http://blogs.msdn.com/shawnfa/archive/2006/10/09/The-Differences-Between-Rijndael-and-AES.aspx" mce_href="http://blogs.msdn.com/shawnfa/archive/2006/10/09/The-Differences-Between-Rijndael-and-AES.aspx"&gt;rather than Rijndael which allows some parameters to be set differently than AES&lt;/A&gt;).&amp;nbsp; Two implementations of this base class are shipping with the Orcas January CTP, once which wraps the CAPI implementation of AES and a managed implementation of the algorithm which should run on any platform the CLR supports.&lt;/P&gt;
&lt;P&gt;AesManaged is actually just a wrapper around RinjdaelManaged with some code added to make sure that you do not setup the algorithm to operate in a non-AES compatible way.&amp;nbsp; For instance, AesManaged does not allow you to change the block size.&amp;nbsp; (It will also disallow the use of CFB and OFB mode because of the way that RijndaelManaged works with those modes).&amp;nbsp;&lt;/P&gt;
&lt;H2&gt;Asymmetric Algorithms&lt;/H2&gt;
&lt;P&gt;
&lt;TABLE class="" border=2&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;Algorithm&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;Class&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD class=""&gt;&lt;STRONG&gt;OS Required&lt;/STRONG&gt;&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Elliptic Curve DSA&lt;/TD&gt;
&lt;TD class=""&gt;ECDSACng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;Elliptic Curve Diffie-Hellman&lt;/TD&gt;
&lt;TD class=""&gt;ECDiffieHellmanCng&lt;/TD&gt;
&lt;TD class=""&gt;Windows Vista&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;These are the really interesting additions to the cryptography libraries in this CTP, the first appearance of elliptic curve cryptography in the .NET Framework.&amp;nbsp; Since these will take more than just a paragraph to cover, the next couple of blog posts will focus on these classes (as well as the other supporting classes to&amp;nbsp;help work with CNG).&amp;nbsp; Up next, Elliptic Curve DSA.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1484417" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Orcas/default.aspx">Orcas</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/CNG/default.aspx">CNG</category></item><item><title>XML Digital Signature Verification with Unknown URI Schemes</title><link>http://blogs.msdn.com/shawnfa/archive/2006/10/12/xml-digital-signature-verification-with-unknown-uri-schemes.aspx</link><pubDate>Thu, 12 Oct 2006 19:07:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:819912</guid><dc:creator>shawnfa</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/819912.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=819912</wfw:commentRss><description>&lt;P&gt;A few years back, there was &lt;A class="" href="http://blogs.msdn.com/shawnfa/archive/2004/04/05/108098.aspx" mce_href="http://blogs.msdn.com/shawnfa/archive/2004/04/05/108098.aspx"&gt;a discussion thread on one of my XML digital signature posts&lt;/A&gt;&amp;nbsp;about verifying an XML digital signature which had references to a URI prefixed with cid:.&amp;nbsp; Recently &lt;A class="" href="http://blogs.msdn.com/mattlind" mce_href="http://blogs.msdn.com/mattlind"&gt;Mattias Lindberg&lt;/A&gt; ran into this problem as well, and &lt;A class="" href="http://blogs.msdn.com/mattlind/archive/2006/10/10/Validating-XML-Digital-Signatures-with-References-Using-Unrecognized-URI-Prefixes.aspx" mce_href="http://blogs.msdn.com/mattlind/archive/2006/10/10/Validating-XML-Digital-Signatures-with-References-Using-Unrecognized-URI-Prefixes.aspx"&gt;devised a clever solution to it&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Mattias realized that SignedXml uses WebRequest.Create to help resolve what the reference points to.&amp;nbsp; And since WebRequest is extensible, he registered a custom class to handle cid URLs.&amp;nbsp; Although his specific example is for cid, this technique will work for any other protocol that the .NET Framework does not know how to handle out of the box.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=819912" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/XML/default.aspx">XML</category></item><item><title>The Differences Between Rijndael and AES</title><link>http://blogs.msdn.com/shawnfa/archive/2006/10/09/The-Differences-Between-Rijndael-and-AES.aspx</link><pubDate>Mon, 09 Oct 2006 19:20:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:808439</guid><dc:creator>shawnfa</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/808439.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=808439</wfw:commentRss><description>&lt;P&gt;When you need to write managed code that encrypts or decrypts data according to the AES standard, most people just plug the &lt;A href="http://msdn2.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged.aspx"&gt;RijndaelManaged&lt;/A&gt; class in and go on their way.&amp;nbsp; After all, Rijndael was the winner of the NIST competition to select the algorithm that would become AES.&amp;nbsp; However, there are some differences between Rijndael and the official &lt;A href="http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf" mce_href="http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf"&gt;FIPS-197 specification for AES&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Namely, Rijndael allows for both key and block sizes to be chosen independently from&amp;nbsp;the set of&amp;nbsp;{ 128, 160, 192, 224,&amp;nbsp; 256 } bits.&amp;nbsp; (And the key size does not in fact have to match the block size).&amp;nbsp; However, FIPS-197 specifies that the block size must always be 128 bits in AES, and that the key size may be either 128, 192, or 256 bits.&amp;nbsp; Therefore AES-128, AES-192, and AES-256 are actually:&lt;/P&gt;
&lt;P&gt;
&lt;TABLE class="" border=1&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD class=""&gt;&lt;/TD&gt;
&lt;TD class=""&gt;Key Size (bits)&lt;/TD&gt;
&lt;TD class=""&gt;Block&amp;nbsp;Size (bits)&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;AES-128&lt;/TD&gt;
&lt;TD class=""&gt;128&lt;/TD&gt;
&lt;TD class=""&gt;128&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;AES-192&lt;/TD&gt;
&lt;TD class=""&gt;192&lt;/TD&gt;
&lt;TD class=""&gt;128&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;
&lt;TD class=""&gt;AES-256&lt;/TD&gt;
&lt;TD class=""&gt;256&lt;/TD&gt;
&lt;TD class=""&gt;128&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/P&gt;
&lt;P&gt;Since RijndaelManaged is an implementation of Rijndael, it will allow you to select different block sizes (although both block and key sizes must be either 128, 192, or 256 bits.&amp;nbsp; 160 and 224 bit are not supported).&amp;nbsp; By selecting a block size which is not 128 bits however, RijndaelManaged will not be able to interoperate with an AES implementation ... since the block sizes will not match on either end of the communication.&lt;/P&gt;
&lt;P&gt;One other interesting quirk of the RijndaelManaged implementation is that it will adjust block size to match the feedback size in CFB mode.&amp;nbsp; This means that if you use CFB and a block size of 128 bits, but a feedback size which is not 128 bits you again will not be compatible with AES.&amp;nbsp; Generally this does not affect many people, since the most common cipher mode to use is CBC.&lt;/P&gt;
&lt;P&gt;Essentially, if you want to use RijndaelManaged as AES you need to make sure that:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The block size is set to 128 bits&lt;/LI&gt;
&lt;LI&gt;You are not using CFB mode, or if you are the feedback size is also 128 bits&lt;/LI&gt;&lt;/OL&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=808439" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item><item><title>RSACryptoServiceProvider, Impersonation, and Ephemeral Keys</title><link>http://blogs.msdn.com/shawnfa/archive/2006/09/21/764977.aspx</link><pubDate>Thu, 21 Sep 2006 20:49:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:764977</guid><dc:creator>shawnfa</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/764977.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=764977</wfw:commentRss><description>&lt;p&gt;If you construct an RSACryptoServiceProvider class without specifying a name for the key, the CLR will create a random&lt;em&gt;&amp;nbsp;&lt;/em&gt;ephemeral key for you.&amp;nbsp; However,&amp;nbsp;ephemeral keys are not supported by the underlying CAPI APIs on all of the platforms that the CLR was built to support, so the RSACryptoServiceProvider will attempt to fake this behavior.&lt;/p&gt; &lt;p&gt;It does this by generating a random name for a key, saving the key in that named container, and then when the RSACryptoServiceProvider instance is disposed, deleting the key.&amp;nbsp; Generally this works well, but when impersonation gets thrown into the mix, things can go awry.&lt;/p&gt; &lt;p&gt;Imagine this scenario:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Create a new, random RSA key&lt;/li&gt; &lt;li&gt;Impersonate another user&lt;/li&gt; &lt;li&gt;Use the key&lt;/li&gt; &lt;li&gt;Dispose the key&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;In this case, the key was created in the profile of one user, and when it is disposed we're running in the context of a different user.&amp;nbsp;&amp;nbsp;When the dispose is attempts to delete the key, we run into an issue.&amp;nbsp; Namely, the new user probably doesn't have permission to delete keys in the old user's profile.&lt;/p&gt; &lt;p&gt;The solution here is to make sure that you create and dispose of ephemeral keys while running in the same user context.&amp;nbsp; Another solution is to name the key yourself, instead of letting the CLR generate a random name.&amp;nbsp; If you've given the key a name the CLR will not attempt to delete the key when the RSACryptoServiceProvider class is disposed -- you can then take care of deleting the key yourself at a later time.&lt;/p&gt; &lt;p&gt;That scenario is pretty straight forward, but you can get bit by this issue in another, more subtle way.&amp;nbsp; Lets say that you fix the above pattern in your code and&amp;nbsp; now you impersonate before creating the RSA key.&amp;nbsp; However, your code does not dispose the RSACryptoServiceProvider object, and instead waits for the GC to collect it for cleanup to occur.&lt;/p&gt; &lt;p&gt;When the GC is ready to collect the object, it will notice that it needs to be finalized, and run the finalizer -- on a separate thread from where you created the object.&amp;nbsp; This thread will not be impersonating, and you run into the same problem.&amp;nbsp; This is very similar to problems that Nicole Calinoiu mentioned in &lt;a href="http://msmvps.com/blogs/calinoiu/archive/2006/01/07/102951.aspx"&gt;her blog post about impersonation and finalization&lt;/a&gt; earlier this year.&lt;/p&gt; &lt;p&gt;In order to avoid these problems all together, the safest pattern to use when combining ephemeral keys with impersonation is:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Impersonate&lt;/li&gt; &lt;li&gt;Create the key&lt;/li&gt; &lt;li&gt;Use the key&lt;/li&gt; &lt;li&gt;Dispose of the key&lt;/li&gt; &lt;li&gt;Undo the impersonation&lt;/li&gt;&lt;/ol&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=764977" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item><item><title>Getting Information about an X509Certificate's Key Container</title><link>http://blogs.msdn.com/shawnfa/archive/2006/03/30/565033.aspx</link><pubDate>Thu, 30 Mar 2006 20:14:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:565033</guid><dc:creator>shawnfa</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/shawnfa/comments/565033.aspx</comments><wfw:commentRss>http://blogs.msdn.com/shawnfa/commentrss.aspx?PostID=565033</wfw:commentRss><description>&lt;P&gt;One of the more common things a lot of people want to do with their X509Certificate2 is figure out what key container its keys are stored in.&amp;nbsp; You can access this information relatively trivially via the PublicKey property of the X509Certificate2 object:&lt;/P&gt;
&lt;P&gt;
&lt;DIV style="BORDER-RIGHT: black thin inset; PADDING-RIGHT: 1em; BORDER-TOP: black thin inset; PADDING-LEFT: 2em; FONT-SIZE: x-small; PADDING-BOTTOM: 1em; MARGIN: 1em 1em 1em 2em; BORDER-LEFT: black thin inset; PADDING-TOP: 1em; BORDER-BOTTOM: black thin inset; FONT-FAMILY: monospace; BACKGROUND-COLOR: lightgrey; WORD-WRAP: break-word"&gt;&lt;SPAN style="COLOR: green"&gt;/// &amp;lt;summary&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: green"&gt;/// Get information about the key container a certificate is stored in&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: green"&gt;/// &amp;lt;/summary&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt;&amp;nbsp;CspKeyContainerInfo&amp;nbsp;GetKeyConatinerInformation(X509Certificate2&amp;nbsp;certificate)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;&amp;nbsp;(certificate&amp;nbsp;==&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&amp;nbsp;ArgumentNullException("certificate");&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ICspAsymmetricAlgorithm&amp;nbsp;key&amp;nbsp;=&amp;nbsp;certificate.PublicKey.Key&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;as&lt;/SPAN&gt;&amp;nbsp;ICspAsymmetricAlgorithm;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;&amp;nbsp;(key&amp;nbsp;==&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;null&lt;/SPAN&gt;)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;throw&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&amp;nbsp;InvalidOperationException("Unknown key type");&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt;&amp;nbsp;key.CspKeyContainerInfo;&lt;BR&gt;} &lt;/DIV&gt;
&lt;P&gt;Here we get the ICspAsymmetricAlgorithm representing the key from the public key, which should work for both RSA and DSS certificates.&amp;nbsp; From there we can simply pull the&amp;nbsp;&lt;A href="http://msdn2.microsoft.com/en-us/library/secaz6xf.aspx"&gt;CspKeyContainerInfo&lt;/A&gt; object and get basically anything we want to know about the key container.&amp;nbsp; Specifically, the KeyContainerName, KeyNumber, ProviderName, ProviderType, HardwareDevice, and Exportable properties tend to be the most interesting.&lt;/P&gt;
&lt;P&gt;Note that this trick will not work with the PrivateKey property of the X509Certificate2, since the private key returned is actually a copy of the key associated with the certificate.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=565033" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/shawnfa/archive/tags/Cryptography/default.aspx">Cryptography</category></item></channel></rss>