Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- NavigatorOutput.cs
- SortDescription.cs
- Inflater.cs
- DatagramAdapter.cs
- VisualStyleElement.cs
- RootBrowserWindowProxy.cs
- XmlSchemaAttributeGroup.cs
- nulltextcontainer.cs
- JavaScriptSerializer.cs
- SecurityTokenParametersEnumerable.cs
- WindowsNonControl.cs
- CompatibleIComparer.cs
- SystemColorTracker.cs
- Setter.cs
- CodeArrayCreateExpression.cs
- WebPartConnectVerb.cs
- GacUtil.cs
- ContentType.cs
- PublisherMembershipCondition.cs
- TypeUtil.cs
- DatePickerTextBox.cs
- SelectionUIHandler.cs
- TextRange.cs
- KoreanLunisolarCalendar.cs
- MediaElementAutomationPeer.cs
- ParserHooks.cs
- ConfigurationValidatorBase.cs
- UriWriter.cs
- SafeMILHandleMemoryPressure.cs
- UrlPath.cs
- RequestReplyCorrelator.cs
- DCSafeHandle.cs
- GeneralTransformGroup.cs
- CursorConverter.cs
- WebPartPersonalization.cs
- GestureRecognizer.cs
- EventManager.cs
- StrokeSerializer.cs
- LinqDataSource.cs
- TextBoxBase.cs
- CookieParameter.cs
- CodeAssignStatement.cs
- WindowsProgressbar.cs
- _NTAuthentication.cs
- SQLDateTime.cs
- odbcmetadatacolumnnames.cs
- Attachment.cs
- CacheMemory.cs
- DataGridViewComboBoxCell.cs
- ValidateNames.cs
- WizardSideBarListControlItemEventArgs.cs
- LowerCaseStringConverter.cs
- BaseTemplateBuildProvider.cs
- WebResponse.cs
- RawMouseInputReport.cs
- URIFormatException.cs
- CompiledELinqQueryState.cs
- SystemException.cs
- HashCodeCombiner.cs
- RegisteredHiddenField.cs
- ExecutionTracker.cs
- ServiceModelInstallComponent.cs
- XpsSerializationManagerAsync.cs
- SecurityDocument.cs
- IOThreadTimer.cs
- ThreadStateException.cs
- TreeWalker.cs
- XmlEncodedRawTextWriter.cs
- ClientSideQueueItem.cs
- SynchronizationFilter.cs
- MaterialGroup.cs
- DataGridViewCellStyle.cs
- DataRowExtensions.cs
- DesignerMetadata.cs
- TimeSpanSecondsConverter.cs
- ClientSettingsSection.cs
- CopyAttributesAction.cs
- ItemDragEvent.cs
- XmlUrlEditor.cs
- PathSegment.cs
- AppDomainFactory.cs
- OneOfTypeConst.cs
- PrincipalPermission.cs
- ExpressionEditorAttribute.cs
- FileDetails.cs
- WindowsStatic.cs
- XsltArgumentList.cs
- Accessible.cs
- XmlHelper.cs
- PathFigureCollection.cs
- NotifyCollectionChangedEventArgs.cs
- AllMembershipCondition.cs
- PresentationTraceSources.cs
- BinaryWriter.cs
- XmlHierarchicalDataSourceView.cs
- ResXResourceWriter.cs
- SystemColorTracker.cs
- HotSpotCollection.cs
- DataDesignUtil.cs
- EndpointDispatcherTable.cs