Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Security / System / Security / Cryptography / Xml / SymmetricKeyWrap.cs / 1305376 / 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
- TopClause.cs
- SchemeSettingElementCollection.cs
- ParserStack.cs
- RegistryConfigurationProvider.cs
- ToggleButtonAutomationPeer.cs
- SamlAssertionKeyIdentifierClause.cs
- WebPartAddingEventArgs.cs
- StringCollection.cs
- BinaryObjectReader.cs
- Metafile.cs
- HttpWrapper.cs
- Vector.cs
- PlainXmlWriter.cs
- AdornerHitTestResult.cs
- FileAuthorizationModule.cs
- ObjectSet.cs
- CodeAccessPermission.cs
- ProcessStartInfo.cs
- FontSource.cs
- IncrementalReadDecoders.cs
- Transform3DCollection.cs
- Decimal.cs
- RawKeyboardInputReport.cs
- DesignerSerializerAttribute.cs
- FixedDocument.cs
- SQLDateTime.cs
- ComplexObject.cs
- HostedHttpContext.cs
- MsmqInputChannelListenerBase.cs
- CollectionsUtil.cs
- FastEncoder.cs
- HasCopySemanticsAttribute.cs
- PrimaryKeyTypeConverter.cs
- Freezable.cs
- IdentityReference.cs
- ColorConverter.cs
- X509SecurityToken.cs
- MultipleViewPattern.cs
- TextTreeNode.cs
- BoundPropertyEntry.cs
- HttpWriter.cs
- BitmapImage.cs
- BypassElement.cs
- Internal.cs
- InternalUserCancelledException.cs
- ExtensibleClassFactory.cs
- Pipe.cs
- Int64AnimationUsingKeyFrames.cs
- PointCollection.cs
- ClientTargetCollection.cs
- GridViewCommandEventArgs.cs
- DataMemberConverter.cs
- StaticContext.cs
- ObjectDataSourceStatusEventArgs.cs
- JsonByteArrayDataContract.cs
- XsdDataContractExporter.cs
- ColorDialog.cs
- TextBox.cs
- PrimitiveList.cs
- SqlCachedBuffer.cs
- SearchForVirtualItemEventArgs.cs
- UrlMappingCollection.cs
- TaiwanCalendar.cs
- FixedPageStructure.cs
- ComponentConverter.cs
- OptimalBreakSession.cs
- NopReturnReader.cs
- CodeAttributeDeclarationCollection.cs
- ProcessManager.cs
- SQLInt16.cs
- Menu.cs
- AutomationProperty.cs
- FixedSOMPage.cs
- XmlSerializerSection.cs
- ProvidersHelper.cs
- SspiWrapper.cs
- SecureEnvironment.cs
- ExtractedStateEntry.cs
- METAHEADER.cs
- XPathParser.cs
- ImageFormatConverter.cs
- ImmComposition.cs
- XamlSerializationHelper.cs
- DataBoundControlAdapter.cs
- CaseInsensitiveComparer.cs
- HttpServerVarsCollection.cs
- HtmlToClrEventProxy.cs
- DbSource.cs
- DependentList.cs
- XmlLanguage.cs
- TypeEnumerableViewSchema.cs
- ServiceDefaults.cs
- ResourceProperty.cs
- ChangeTracker.cs
- XmlCharType.cs
- AddInAdapter.cs
- CryptoApi.cs
- DataIdProcessor.cs
- SafeRightsManagementPubHandle.cs
- CheckBox.cs