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
- SecurityRuntime.cs
- Attribute.cs
- SafeSecurityHelper.cs
- MouseActionConverter.cs
- AQNBuilder.cs
- UITypeEditor.cs
- KerberosSecurityTokenAuthenticator.cs
- SafeHandles.cs
- DiagnosticEventProvider.cs
- InkCanvasFeedbackAdorner.cs
- CheckBoxField.cs
- IncrementalHitTester.cs
- XmlSchemaInclude.cs
- DocumentApplicationJournalEntry.cs
- NetStream.cs
- DictionarySectionHandler.cs
- StateChangeEvent.cs
- ProfileServiceManager.cs
- CodeMethodReturnStatement.cs
- ButtonFlatAdapter.cs
- LongTypeConverter.cs
- SqlDelegatedTransaction.cs
- SizeIndependentAnimationStorage.cs
- TrustSection.cs
- COM2Enum.cs
- SymDocumentType.cs
- DbBuffer.cs
- MSAAEventDispatcher.cs
- DoubleUtil.cs
- PageParser.cs
- SQLInt32.cs
- SecurityResources.cs
- WebContext.cs
- PasswordRecoveryAutoFormat.cs
- PriorityQueue.cs
- WebPartsPersonalizationAuthorization.cs
- __TransparentProxy.cs
- ArrayTypeMismatchException.cs
- NativeMethods.cs
- DocumentViewerConstants.cs
- BaseCollection.cs
- WebAdminConfigurationHelper.cs
- Container.cs
- PrivilegeNotHeldException.cs
- PartialArray.cs
- CryptoStream.cs
- PhoneCall.cs
- Convert.cs
- Decimal.cs
- FixedFlowMap.cs
- CapabilitiesPattern.cs
- IsolatedStorageFile.cs
- InvokeWebService.cs
- BitConverter.cs
- LinqDataSourceUpdateEventArgs.cs
- Vector3DCollectionValueSerializer.cs
- ObjectNotFoundException.cs
- FileIOPermission.cs
- TabControlAutomationPeer.cs
- EditingCoordinator.cs
- CommonDialog.cs
- IndentTextWriter.cs
- BinHexEncoder.cs
- NetworkInformationPermission.cs
- RawStylusInputCustomDataList.cs
- SpeechRecognizer.cs
- DiagnosticTrace.cs
- ErasingStroke.cs
- SmtpClient.cs
- UnsafeNativeMethodsMilCoreApi.cs
- SecuritySessionClientSettings.cs
- PolyQuadraticBezierSegment.cs
- ContainerTracking.cs
- ExpandableObjectConverter.cs
- ExternalException.cs
- ObjectAnimationUsingKeyFrames.cs
- VarRefManager.cs
- HeaderCollection.cs
- EntityDataSource.cs
- CollectionsUtil.cs
- XmlIlVisitor.cs
- QueryResultOp.cs
- FloaterParagraph.cs
- ProgressPage.cs
- PrintPreviewDialog.cs
- FamilyMapCollection.cs
- ElementFactory.cs
- RecognizerBase.cs
- ListBindableAttribute.cs
- WpfXamlMember.cs
- Command.cs
- SecurityState.cs
- FieldBuilder.cs
- CompositeControlDesigner.cs
- SelectedGridItemChangedEvent.cs
- Page.cs
- XmlTextReaderImplHelpers.cs
- TextComposition.cs
- _HeaderInfoTable.cs
- DecodeHelper.cs