Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Xml / SymmetricKeyWrap.cs / 1 / SymmetricKeyWrap.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //---------------------------------------------------------------------------- // // SymmetricKeyWrap.cs // // 04/01/2002 // //--------------------------------------------------------------------------- namespace System.Security.Cryptography.Xml { using System; using System.Security.Cryptography; // abstract class providing symmetric key wrap implementation internal static class SymmetricKeyWrap { private readonly static byte[] s_rgbTripleDES_KW_IV = {0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05}; private readonly static byte[] s_rgbAES_KW_IV = {0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6}; // // internal static methods // // CMS TripleDES KeyWrap as described in "http://www.w3.org/2001/04/xmlenc#kw-tripledes" internal static byte[] TripleDESKeyWrapEncrypt (byte[] rgbKey, byte[] rgbWrappedKeyData) { // checksum the key SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); byte[] rgbCKS = sha.ComputeHash(rgbWrappedKeyData); // generate a random IV RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] rgbIV = new byte[8]; rng.GetBytes(rgbIV); // rgbWKCS = rgbWrappedKeyData | (first 8 bytes of the hash) byte[] rgbWKCKS = new byte[rgbWrappedKeyData.Length + 8]; TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider(); // Don't add padding, use CBC mode: for example, a 192 bits key will yield 40 bytes of encrypted data tripleDES.Padding = PaddingMode.None; ICryptoTransform enc1 = tripleDES.CreateEncryptor(rgbKey, rgbIV); Buffer.BlockCopy(rgbWrappedKeyData, 0, rgbWKCKS, 0, rgbWrappedKeyData.Length); Buffer.BlockCopy(rgbCKS, 0, rgbWKCKS, rgbWrappedKeyData.Length, 8); byte[] temp1 = enc1.TransformFinalBlock(rgbWKCKS, 0, rgbWKCKS.Length); byte[] temp2 = new byte[rgbIV.Length + temp1.Length]; Buffer.BlockCopy(rgbIV, 0, temp2, 0, rgbIV.Length); Buffer.BlockCopy(temp1, 0, temp2, rgbIV.Length, temp1.Length); // temp2 = REV (rgbIV | E_k(rgbWrappedKeyData | rgbCKS)) Array.Reverse(temp2); ICryptoTransform enc2 = tripleDES.CreateEncryptor(rgbKey, s_rgbTripleDES_KW_IV); return enc2.TransformFinalBlock(temp2, 0, temp2.Length); } internal static byte[] TripleDESKeyWrapDecrypt (byte[] rgbKey, byte[] rgbEncryptedWrappedKeyData) { // Check to see whether the length of the encrypted key is reasonable if (rgbEncryptedWrappedKeyData.Length != 32 && rgbEncryptedWrappedKeyData.Length != 40 && rgbEncryptedWrappedKeyData.Length != 48) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider(); // Assume no padding, use CBC mode tripleDES.Padding = PaddingMode.None; ICryptoTransform dec1 = tripleDES.CreateDecryptor(rgbKey, s_rgbTripleDES_KW_IV); byte[] temp2 = dec1.TransformFinalBlock(rgbEncryptedWrappedKeyData, 0, rgbEncryptedWrappedKeyData.Length); Array.Reverse(temp2); // Get the IV and temp1 byte[] rgbIV = new byte[8]; Buffer.BlockCopy(temp2, 0, rgbIV, 0, 8); byte[] temp1 = new byte[temp2.Length - rgbIV.Length]; Buffer.BlockCopy(temp2, 8, temp1, 0, temp1.Length); ICryptoTransform dec2 = tripleDES.CreateDecryptor(rgbKey, rgbIV); byte[] rgbWKCKS = dec2.TransformFinalBlock(temp1, 0, temp1.Length); // checksum the key byte[] rgbWrappedKeyData = new byte[rgbWKCKS.Length - 8]; Buffer.BlockCopy(rgbWKCKS, 0, rgbWrappedKeyData, 0, rgbWrappedKeyData.Length); SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); byte[] rgbCKS = sha.ComputeHash(rgbWrappedKeyData); for (int index = rgbWrappedKeyData.Length, index1 = 0; index < rgbWKCKS.Length; index++, index1++) if (rgbWKCKS[index] != rgbCKS[index1]) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); return rgbWrappedKeyData; } // AES KeyWrap described in "http://www.w3.org/2001/04/xmlenc#kw-aes***", as suggested by NIST internal static byte[] AESKeyWrapEncrypt (byte[] rgbKey, byte[] rgbWrappedKeyData) { int N = rgbWrappedKeyData.Length >> 3; // The information wrapped need not actually be a key, but it needs to be a multiple of 64 bits if ((rgbWrappedKeyData.Length % 8 != 0) || N <= 0) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); RijndaelManaged rijn = new RijndaelManaged(); rijn.Key = rgbKey; // Use ECB mode, no padding rijn.Mode = CipherMode.ECB; rijn.Padding = PaddingMode.None; ICryptoTransform enc = rijn.CreateEncryptor(); // special case: only 1 block -- 8 bytes if (N == 1) { // temp = 0xa6a6a6a6a6a6a6a6 | P(1) byte[] temp = new byte[s_rgbAES_KW_IV.Length + rgbWrappedKeyData.Length]; Buffer.BlockCopy(s_rgbAES_KW_IV, 0, temp, 0, s_rgbAES_KW_IV.Length); Buffer.BlockCopy(rgbWrappedKeyData, 0, temp, s_rgbAES_KW_IV.Length, rgbWrappedKeyData.Length); return enc.TransformFinalBlock(temp, 0, temp.Length); } // second case: more than 1 block Int64 t = 0; byte[] rgbOutput = new byte[(N+1) << 3]; // initialize the R_i's Buffer.BlockCopy(rgbWrappedKeyData, 0, rgbOutput, 8, rgbWrappedKeyData.Length); byte[] rgbA = new byte[8]; byte[] rgbBlock = new byte[16]; Buffer.BlockCopy(s_rgbAES_KW_IV, 0, rgbA, 0, 8); for (int j=0; j<=5; j++) { for (int i=1; i<=N; i++) { t = i + j*N; Buffer.BlockCopy(rgbA, 0, rgbBlock, 0, 8); Buffer.BlockCopy(rgbOutput, 8*i, rgbBlock, 8, 8); byte[] rgbB = enc.TransformFinalBlock(rgbBlock, 0, 16); for (int k=0; k<8; k++) { byte tmp = (byte) ((t >> (8*(7-k))) & 0xFF); rgbA[k] = (byte) (tmp ^ rgbB[k]); } Buffer.BlockCopy(rgbB, 8, rgbOutput, 8*i, 8); } } // Set the first block of rgbOutput to rgbA Buffer.BlockCopy(rgbA, 0, rgbOutput, 0, 8); return rgbOutput; } internal static byte[] AESKeyWrapDecrypt (byte[] rgbKey, byte[] rgbEncryptedWrappedKeyData) { int N = (rgbEncryptedWrappedKeyData.Length >> 3) - 1; // The information wrapped need not actually be a key, but it needs to be a multiple of 64 bits if ((rgbEncryptedWrappedKeyData.Length % 8 != 0) || N <= 0) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); byte[] rgbOutput = new byte[N << 3]; RijndaelManaged rijn = new RijndaelManaged(); rijn.Key = rgbKey; // Use ECB mode, no padding rijn.Mode = CipherMode.ECB; rijn.Padding = PaddingMode.None; ICryptoTransform dec = rijn.CreateDecryptor(); // special case: only 1 block -- 8 bytes if (N == 1) { byte[] temp = dec.TransformFinalBlock(rgbEncryptedWrappedKeyData, 0, rgbEncryptedWrappedKeyData.Length); // checksum the key for (int index = 0; index < 8; index++) if (temp[index] != s_rgbAES_KW_IV[index]) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); // rgbOutput is LSB(temp) Buffer.BlockCopy(temp, 8, rgbOutput, 0, 8); return rgbOutput; } // second case: more than 1 block Int64 t = 0; // initialize the C_i's Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 8, rgbOutput, 0, rgbOutput.Length); byte[] rgbA = new byte[8]; byte[] rgbBlock = new byte[16]; Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 0, rgbA, 0, 8); for (int j=5; j>=0; j--) { for (int i=N; i>=1; i--) { t = i + j*N; for (int k=0; k<8; k++) { byte tmp = (byte) ((t >> (8*(7-k))) & 0xFF); rgbA[k] ^= tmp; } Buffer.BlockCopy(rgbA, 0, rgbBlock, 0, 8); Buffer.BlockCopy(rgbOutput, 8*(i-1), rgbBlock, 8, 8); byte[] rgbB = dec.TransformFinalBlock(rgbBlock, 0, 16); Buffer.BlockCopy(rgbB, 8, rgbOutput, 8*(i-1), 8); Buffer.BlockCopy(rgbB, 0, rgbA, 0, 8); } } // checksum the key for (int index = 0; index < 8; index++) if (rgbA[index] != s_rgbAES_KW_IV[index]) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); return rgbOutput; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //---------------------------------------------------------------------------- // // SymmetricKeyWrap.cs // // 04/01/2002 // //--------------------------------------------------------------------------- namespace System.Security.Cryptography.Xml { using System; using System.Security.Cryptography; // abstract class providing symmetric key wrap implementation internal static class SymmetricKeyWrap { private readonly static byte[] s_rgbTripleDES_KW_IV = {0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05}; private readonly static byte[] s_rgbAES_KW_IV = {0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6}; // // internal static methods // // CMS TripleDES KeyWrap as described in "http://www.w3.org/2001/04/xmlenc#kw-tripledes" internal static byte[] TripleDESKeyWrapEncrypt (byte[] rgbKey, byte[] rgbWrappedKeyData) { // checksum the key SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); byte[] rgbCKS = sha.ComputeHash(rgbWrappedKeyData); // generate a random IV RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] rgbIV = new byte[8]; rng.GetBytes(rgbIV); // rgbWKCS = rgbWrappedKeyData | (first 8 bytes of the hash) byte[] rgbWKCKS = new byte[rgbWrappedKeyData.Length + 8]; TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider(); // Don't add padding, use CBC mode: for example, a 192 bits key will yield 40 bytes of encrypted data tripleDES.Padding = PaddingMode.None; ICryptoTransform enc1 = tripleDES.CreateEncryptor(rgbKey, rgbIV); Buffer.BlockCopy(rgbWrappedKeyData, 0, rgbWKCKS, 0, rgbWrappedKeyData.Length); Buffer.BlockCopy(rgbCKS, 0, rgbWKCKS, rgbWrappedKeyData.Length, 8); byte[] temp1 = enc1.TransformFinalBlock(rgbWKCKS, 0, rgbWKCKS.Length); byte[] temp2 = new byte[rgbIV.Length + temp1.Length]; Buffer.BlockCopy(rgbIV, 0, temp2, 0, rgbIV.Length); Buffer.BlockCopy(temp1, 0, temp2, rgbIV.Length, temp1.Length); // temp2 = REV (rgbIV | E_k(rgbWrappedKeyData | rgbCKS)) Array.Reverse(temp2); ICryptoTransform enc2 = tripleDES.CreateEncryptor(rgbKey, s_rgbTripleDES_KW_IV); return enc2.TransformFinalBlock(temp2, 0, temp2.Length); } internal static byte[] TripleDESKeyWrapDecrypt (byte[] rgbKey, byte[] rgbEncryptedWrappedKeyData) { // Check to see whether the length of the encrypted key is reasonable if (rgbEncryptedWrappedKeyData.Length != 32 && rgbEncryptedWrappedKeyData.Length != 40 && rgbEncryptedWrappedKeyData.Length != 48) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider(); // Assume no padding, use CBC mode tripleDES.Padding = PaddingMode.None; ICryptoTransform dec1 = tripleDES.CreateDecryptor(rgbKey, s_rgbTripleDES_KW_IV); byte[] temp2 = dec1.TransformFinalBlock(rgbEncryptedWrappedKeyData, 0, rgbEncryptedWrappedKeyData.Length); Array.Reverse(temp2); // Get the IV and temp1 byte[] rgbIV = new byte[8]; Buffer.BlockCopy(temp2, 0, rgbIV, 0, 8); byte[] temp1 = new byte[temp2.Length - rgbIV.Length]; Buffer.BlockCopy(temp2, 8, temp1, 0, temp1.Length); ICryptoTransform dec2 = tripleDES.CreateDecryptor(rgbKey, rgbIV); byte[] rgbWKCKS = dec2.TransformFinalBlock(temp1, 0, temp1.Length); // checksum the key byte[] rgbWrappedKeyData = new byte[rgbWKCKS.Length - 8]; Buffer.BlockCopy(rgbWKCKS, 0, rgbWrappedKeyData, 0, rgbWrappedKeyData.Length); SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); byte[] rgbCKS = sha.ComputeHash(rgbWrappedKeyData); for (int index = rgbWrappedKeyData.Length, index1 = 0; index < rgbWKCKS.Length; index++, index1++) if (rgbWKCKS[index] != rgbCKS[index1]) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); return rgbWrappedKeyData; } // AES KeyWrap described in "http://www.w3.org/2001/04/xmlenc#kw-aes***", as suggested by NIST internal static byte[] AESKeyWrapEncrypt (byte[] rgbKey, byte[] rgbWrappedKeyData) { int N = rgbWrappedKeyData.Length >> 3; // The information wrapped need not actually be a key, but it needs to be a multiple of 64 bits if ((rgbWrappedKeyData.Length % 8 != 0) || N <= 0) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); RijndaelManaged rijn = new RijndaelManaged(); rijn.Key = rgbKey; // Use ECB mode, no padding rijn.Mode = CipherMode.ECB; rijn.Padding = PaddingMode.None; ICryptoTransform enc = rijn.CreateEncryptor(); // special case: only 1 block -- 8 bytes if (N == 1) { // temp = 0xa6a6a6a6a6a6a6a6 | P(1) byte[] temp = new byte[s_rgbAES_KW_IV.Length + rgbWrappedKeyData.Length]; Buffer.BlockCopy(s_rgbAES_KW_IV, 0, temp, 0, s_rgbAES_KW_IV.Length); Buffer.BlockCopy(rgbWrappedKeyData, 0, temp, s_rgbAES_KW_IV.Length, rgbWrappedKeyData.Length); return enc.TransformFinalBlock(temp, 0, temp.Length); } // second case: more than 1 block Int64 t = 0; byte[] rgbOutput = new byte[(N+1) << 3]; // initialize the R_i's Buffer.BlockCopy(rgbWrappedKeyData, 0, rgbOutput, 8, rgbWrappedKeyData.Length); byte[] rgbA = new byte[8]; byte[] rgbBlock = new byte[16]; Buffer.BlockCopy(s_rgbAES_KW_IV, 0, rgbA, 0, 8); for (int j=0; j<=5; j++) { for (int i=1; i<=N; i++) { t = i + j*N; Buffer.BlockCopy(rgbA, 0, rgbBlock, 0, 8); Buffer.BlockCopy(rgbOutput, 8*i, rgbBlock, 8, 8); byte[] rgbB = enc.TransformFinalBlock(rgbBlock, 0, 16); for (int k=0; k<8; k++) { byte tmp = (byte) ((t >> (8*(7-k))) & 0xFF); rgbA[k] = (byte) (tmp ^ rgbB[k]); } Buffer.BlockCopy(rgbB, 8, rgbOutput, 8*i, 8); } } // Set the first block of rgbOutput to rgbA Buffer.BlockCopy(rgbA, 0, rgbOutput, 0, 8); return rgbOutput; } internal static byte[] AESKeyWrapDecrypt (byte[] rgbKey, byte[] rgbEncryptedWrappedKeyData) { int N = (rgbEncryptedWrappedKeyData.Length >> 3) - 1; // The information wrapped need not actually be a key, but it needs to be a multiple of 64 bits if ((rgbEncryptedWrappedKeyData.Length % 8 != 0) || N <= 0) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_KW_BadKeySize")); byte[] rgbOutput = new byte[N << 3]; RijndaelManaged rijn = new RijndaelManaged(); rijn.Key = rgbKey; // Use ECB mode, no padding rijn.Mode = CipherMode.ECB; rijn.Padding = PaddingMode.None; ICryptoTransform dec = rijn.CreateDecryptor(); // special case: only 1 block -- 8 bytes if (N == 1) { byte[] temp = dec.TransformFinalBlock(rgbEncryptedWrappedKeyData, 0, rgbEncryptedWrappedKeyData.Length); // checksum the key for (int index = 0; index < 8; index++) if (temp[index] != s_rgbAES_KW_IV[index]) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); // rgbOutput is LSB(temp) Buffer.BlockCopy(temp, 8, rgbOutput, 0, 8); return rgbOutput; } // second case: more than 1 block Int64 t = 0; // initialize the C_i's Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 8, rgbOutput, 0, rgbOutput.Length); byte[] rgbA = new byte[8]; byte[] rgbBlock = new byte[16]; Buffer.BlockCopy(rgbEncryptedWrappedKeyData, 0, rgbA, 0, 8); for (int j=5; j>=0; j--) { for (int i=N; i>=1; i--) { t = i + j*N; for (int k=0; k<8; k++) { byte tmp = (byte) ((t >> (8*(7-k))) & 0xFF); rgbA[k] ^= tmp; } Buffer.BlockCopy(rgbA, 0, rgbBlock, 0, 8); Buffer.BlockCopy(rgbOutput, 8*(i-1), rgbBlock, 8, 8); byte[] rgbB = dec.TransformFinalBlock(rgbBlock, 0, 16); Buffer.BlockCopy(rgbB, 8, rgbOutput, 8*(i-1), 8); Buffer.BlockCopy(rgbB, 0, rgbA, 0, 8); } } // checksum the key for (int index = 0; index < 8; index++) if (rgbA[index] != s_rgbAES_KW_IV[index]) throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_BadWrappedKeySize")); return rgbOutput; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- FullTrustAssembliesSection.cs
- PropertyIDSet.cs
- SqlDataSourceConfigureFilterForm.cs
- MouseActionConverter.cs
- FilteredXmlReader.cs
- Zone.cs
- ConnectionStringSettingsCollection.cs
- TableLayoutStyleCollection.cs
- MenuItemStyle.cs
- ResourceProperty.cs
- Point3D.cs
- SourceLineInfo.cs
- WindowsScrollBar.cs
- CacheOutputQuery.cs
- Int32EqualityComparer.cs
- BuildProvider.cs
- DrawingImage.cs
- MonitoringDescriptionAttribute.cs
- Thread.cs
- EdmMember.cs
- XPathNodeHelper.cs
- Buffer.cs
- QilBinary.cs
- BrowserInteropHelper.cs
- DBConnection.cs
- UxThemeWrapper.cs
- ChannelOptions.cs
- DelimitedListTraceListener.cs
- AudienceUriMode.cs
- SqlLiftWhereClauses.cs
- WebControlParameterProxy.cs
- KnownColorTable.cs
- DataListItem.cs
- WindowsTreeView.cs
- CompositeScriptReferenceEventArgs.cs
- CrossSiteScriptingValidation.cs
- MdiWindowListStrip.cs
- XmlQueryType.cs
- DataGridViewComboBoxCell.cs
- BidPrivateBase.cs
- Model3DCollection.cs
- OrderedDictionaryStateHelper.cs
- CommandValueSerializer.cs
- JobCollate.cs
- SynchronizedRandom.cs
- String.cs
- BufferAllocator.cs
- PartialTrustVisibleAssembly.cs
- PKCS1MaskGenerationMethod.cs
- PixelFormatConverter.cs
- DefaultParameterValueAttribute.cs
- DbParameterCollectionHelper.cs
- WindowShowOrOpenTracker.cs
- SqlTopReducer.cs
- CodeTypeMemberCollection.cs
- TextParagraph.cs
- PathSegmentCollection.cs
- ISessionStateStore.cs
- PartManifestEntry.cs
- XmlDictionary.cs
- WindowCollection.cs
- CompositeCollectionView.cs
- HtmlElementErrorEventArgs.cs
- ParallelTimeline.cs
- SafeRightsManagementPubHandle.cs
- BaseCAMarshaler.cs
- ToolboxItem.cs
- VirtualPath.cs
- BoundField.cs
- DocumentPageView.cs
- ExtensionQuery.cs
- PanelStyle.cs
- SqlServices.cs
- CredentialManagerDialog.cs
- DataGridViewCellFormattingEventArgs.cs
- ComponentChangingEvent.cs
- EncryptedPackage.cs
- HttpListenerPrefixCollection.cs
- WebPart.cs
- ChannelReliableSession.cs
- LogFlushAsyncResult.cs
- IsolatedStorageFileStream.cs
- Mapping.cs
- ClientScriptManagerWrapper.cs
- PerformanceCounterPermissionAttribute.cs
- KoreanCalendar.cs
- ColumnProvider.cs
- Pair.cs
- CompatibleIComparer.cs
- KeyFrames.cs
- XmlUtil.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- MoveSizeWinEventHandler.cs
- SQLInt32.cs
- StringReader.cs
- ResourcePart.cs
- DynamicILGenerator.cs
- WebPartMovingEventArgs.cs
- AttributeTableBuilder.cs
- HtmlHead.cs