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
- SerialPort.cs
- OleDbException.cs
- TabItemAutomationPeer.cs
- DictionaryManager.cs
- DeclarativeCatalogPart.cs
- DataSourceCacheDurationConverter.cs
- SecurityUtils.cs
- HttpCacheVaryByContentEncodings.cs
- filewebresponse.cs
- ThreadSafeList.cs
- CheckableControlBaseAdapter.cs
- HtmlInputFile.cs
- Freezable.cs
- TokenBasedSet.cs
- DomainUpDown.cs
- ICspAsymmetricAlgorithm.cs
- COM2Properties.cs
- DriveNotFoundException.cs
- WhitespaceRuleReader.cs
- TCPClient.cs
- TextEditorDragDrop.cs
- lengthconverter.cs
- DrawingCollection.cs
- MobileDeviceCapabilitiesSectionHandler.cs
- RMEnrollmentPage2.cs
- ClassGenerator.cs
- LineMetrics.cs
- FaultDescription.cs
- FocusManager.cs
- InternalResources.cs
- UserPersonalizationStateInfo.cs
- MorphHelpers.cs
- ApplicationDirectoryMembershipCondition.cs
- SqlClientWrapperSmiStream.cs
- WpfPayload.cs
- DrawingAttributesDefaultValueFactory.cs
- OracleRowUpdatingEventArgs.cs
- CodeTypeReferenceCollection.cs
- TextShapeableCharacters.cs
- Int32Converter.cs
- CurrencyWrapper.cs
- TrackingDataItem.cs
- NegotiateStream.cs
- KeyFrames.cs
- HandlerWithFactory.cs
- InstanceDescriptor.cs
- TextParagraph.cs
- RelatedImageListAttribute.cs
- PropertyManager.cs
- XmlSiteMapProvider.cs
- OleDragDropHandler.cs
- InvokeFunc.cs
- CapabilitiesAssignment.cs
- CapabilitiesSection.cs
- DataTableExtensions.cs
- COM2ExtendedBrowsingHandler.cs
- WsdlHelpGeneratorElement.cs
- AnyAllSearchOperator.cs
- RealizationDrawingContextWalker.cs
- MatrixAnimationBase.cs
- RelationshipEndCollection.cs
- CodeStatement.cs
- BrowserDefinition.cs
- DetailsViewCommandEventArgs.cs
- FlowLayout.cs
- SqlDelegatedTransaction.cs
- PriorityQueue.cs
- WorkflowServiceAttributesTypeConverter.cs
- DriveInfo.cs
- Query.cs
- WsatConfiguration.cs
- ObjectSecurity.cs
- ComponentFactoryHelpers.cs
- PEFileEvidenceFactory.cs
- RepeatBehaviorConverter.cs
- TypeToken.cs
- StylusPointDescription.cs
- MediaElement.cs
- TdsParser.cs
- QueryComponents.cs
- CaretElement.cs
- ColorMatrix.cs
- DataPointer.cs
- SelectedGridItemChangedEvent.cs
- WindowsGrip.cs
- PtsHelper.cs
- DrawingVisual.cs
- ContextMenuAutomationPeer.cs
- SimpleWorkerRequest.cs
- SignerInfo.cs
- UIElementParaClient.cs
- TemplateParser.cs
- InstanceHandleConflictException.cs
- PagerSettings.cs
- HtmlWindow.cs
- DeviceSpecificChoiceCollection.cs
- BaseTreeIterator.cs
- MetadataItem_Static.cs
- CompensatableSequenceActivity.cs
- AssemblyAttributesGoHere.cs