Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / infocard / Service / managed / Microsoft / InfoCards / PinProtectionHelper.cs / 1 / PinProtectionHelper.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.InfoCards { using System; using System.IO; using System.Security; using System.Security.Cryptography; using Microsoft.InfoCards.Diagnostics; using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; // // Summary: // Structure for carrying details of the PKCS5 algorithm used // to produce a key. // internal class PinProtectionHelper { // // Number of PKCS5 iterations to perform when generating the encryption key // const int InfoCardPKCS5IterationCount = 1000; // // Size of InfoCard Salt in bytes // public const int SaltSize = 16; // // Size of AES block length in bytes // const int AESBlockByteLength = 16; // // Size of AES key length in bytes // const int AESKeyByteLength = 32; // // Version for pin protection scheme // const byte EncryptForPinProtectionVersion = 2; // // PKCS5 implementation // NOTE: Need to use Rfc2898DeriveBytes // PasswordDeriveBytes m_pkcs5; byte[] m_key; RijndaelManaged m_aes = new RijndaelManaged(); // // Summary // Generates a key and associated details from a pin using random salt a IV. // // Parameters // pin - User passphrase used to generate the key using PKCS5 // public PinProtectionHelper( string pin ) { RNGCryptoServiceProvider prov = new RNGCryptoServiceProvider(); byte[] salt = new byte[ SaltSize ]; prov.GetBytes( salt ); // // Generate the key using PKCS5 // m_pkcs5 = new PasswordDeriveBytes( pin, salt, "SHA256", (int) InfoCardPKCS5IterationCount ); m_key = m_pkcs5.GetBytes( AESKeyByteLength ); // // Setup the AES algorithm // m_aes.Padding = PaddingMode.PKCS7; m_aes.Mode = CipherMode.CBC; m_aes.BlockSize = AESBlockByteLength * 8; m_aes.KeySize = m_key.Length * 8; m_aes.GenerateIV(); } // // Summary // Generates a key and associated details from a pin and the serialized parameters. // // Parameters // pin - User passphrase used to generate the key using PKCS5 // serializedParameters - Information about how the key was generated // // Remarks // Reads the serialized form below to constur // Version | Salt | Interations | IV | Encrypted Data // 0 1 17 21 37 // Version : 1 byte // Salt : 16 bytes // Iterations : 4 bytes // IV : 16 bytes // EncData : ?? bytes of unicode encrypted using AES256 // private const int VersionOffset = 0; private const int SaltOffset = 1; private const int IterationsOffset = 17; private const int IVOffset = 21; private const int EncryptedDataOffset = 37; public PinProtectionHelper( string pin, byte[] serializedParameters ) { if( EncryptForPinProtectionVersion != serializedParameters[ 0 ] ) { throw IDT.ThrowHelperError( new InvalidCardException( SR.GetString( SR.ServiceCardDecryptionFailed ) ) ); } // // Generate the key using PKCS5 // byte[] salt = new byte[ SaltSize ]; Array.Copy( serializedParameters, SaltOffset, salt, 0, SaltSize ); UInt32 iterations = BitConverter.ToUInt32( serializedParameters, IterationsOffset ); m_pkcs5 = new PasswordDeriveBytes( pin, salt, "SHA256", (int) iterations ); m_key = m_pkcs5.GetBytes( AESKeyByteLength ); // // Setup the AES algorithm // m_aes.Padding = PaddingMode.PKCS7; m_aes.Mode = CipherMode.CBC; m_aes.BlockSize = AESBlockByteLength * 8; m_aes.KeySize = m_key.Length * 8; byte[] iv = new byte[ AESBlockByteLength ]; // // Extract the IV from the byte array // Array.Copy( serializedParameters, IVOffset, iv, 0, iv.Length ); m_aes.IV = iv; } // // Summary // Encrypts an array of bytes using the pin protection scheme and AES // // Parameters // toEncrypt - bytes to be encrypted // pkcs5 - Information about how the key was generated // // Remarks // Encrypt each block to look like: // Version | Salt | Interations | IV | Encrypted Data // 0 1 17 21 37 // Version : 1 byte // Salt : 16 bytes // Iterations : 4 bytes // IV : 16 bytes // EncData : 48 bytes of unicode encrypted using AES256 // The size of the encrypted data can be computed by the following // // CipherText = PlainText(bytes) + BlockSize(bytes) - (PlainText MOD BlockSize ) // // So, In this case EncData = 32(MasterKeySize) + 16(BlockSize) - ( 32 MOD 16 ) = 48 // // NOTE: Change the EncryotedMasterKeySize method if the logic in this function changes // public byte[] EncryptMasterKey( byte[] toEncrypt ) { byte[] encryptedKey = Encrypt( toEncrypt ); using( MemoryStream digest = new MemoryStream() ) { digest.WriteByte( EncryptForPinProtectionVersion ); digest.Write( m_pkcs5.Salt, 0, m_pkcs5.Salt.Length ); digest.Write( System.BitConverter.GetBytes( (UInt32) m_pkcs5.IterationCount ), 0, 4 ); digest.Write( m_aes.IV, 0, m_aes.IV.Length ); digest.Write( encryptedKey, 0, encryptedKey.Length ); return digest.ToArray(); } } // // Summary // Returns the size of the encrypted master key // // Remarks // EncryptedMasterKeySize = 1(Version)+ 16(Salt)+4(Iterations)+16(IV)+48(EncData) // NOTE: the algorithm changes if the algorithm to create the digest in EncryptMasterKey changes public static int EncryptedMasterKeySize { get { return ( 1 + SaltSize + 4 + AESBlockByteLength + InfoCard.MasterKeySize + AESBlockByteLength - ( InfoCard.MasterKeySize % AESBlockByteLength ) ); } } // // Summary // Encrypts an array of bytes using the pin protection scheme and AES // // Parameters // toEncrypt - bytes to be encrypted // pkcs5 - Information about how the key was generated // // Remarks // public byte[] Encrypt( byte[] toEncrypt ) { using( ICryptoTransform encryptor = m_aes.CreateEncryptor( m_key, m_aes.IV ) ) { using( MemoryStream digest = new MemoryStream() ) { try { using( CryptoStream cs = new CryptoStream( digest, encryptor, CryptoStreamMode.Write ) ) { // // Encrypt the claim value // cs.Write( toEncrypt, 0, toEncrypt.Length ); cs.FlushFinalBlock(); return digest.ToArray(); } } catch( CryptographicException e ) { throw IDT.ThrowHelperError( new InvalidCardException( SR.GetString( SR.ServiceCardEncryptionFailed ), e ) ); } } } } // // Summary // Encrypts an array of bytes using the pin protection scheme and AES // // Parameters // toEncrypt - bytes to be encrypted // pkcs5 - Information about how the key was generated // // Remarks // Each block looks like the following: // public byte[] DecryptMasterKey( byte[] toDecrypt ) { byte[] encrypted = new byte[ toDecrypt.Length - EncryptedDataOffset ]; Array.Copy( toDecrypt, EncryptedDataOffset, encrypted, 0, toDecrypt.Length - EncryptedDataOffset ); return Decrypt( encrypted ); } // // Summary // Encrypts an array of bytes using the pin protection scheme and AES // // Parameters // encrypted - bytes to be decrypted // public byte[] Decrypt( byte[] encrypted ) { using( ICryptoTransform decryptor = m_aes.CreateDecryptor( m_key, m_aes.IV ) ) { using( MemoryStream digest = new MemoryStream( encrypted ) ) { try { using( CryptoStream cs = new CryptoStream( digest, decryptor, CryptoStreamMode.Read ) ) { byte[] decrypted = new byte[ encrypted.Length ]; int count = cs.Read( decrypted, 0, decrypted.Length ); // // Truncate to the subarray containing the plain text // byte[] result = new byte[ count ]; Array.Copy( decrypted, result, count ); return result; } } catch( CryptographicException e ) { throw IDT.ThrowHelperError( new InvalidCardException( SR.GetString( SR.ServiceCardDecryptionFailed ), e ) ); } } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataColumnMappingCollection.cs
- Image.cs
- ProviderUtil.cs
- basenumberconverter.cs
- GenericPrincipal.cs
- ViewPort3D.cs
- ByteKeyFrameCollection.cs
- TreeNodeBindingCollection.cs
- TimeSpanParse.cs
- SafeCertificateContext.cs
- WindowsContainer.cs
- DebugTraceHelper.cs
- isolationinterop.cs
- ObjectListShowCommandsEventArgs.cs
- IteratorDescriptor.cs
- ModelToObjectValueConverter.cs
- SymmetricAlgorithm.cs
- DocumentGridContextMenu.cs
- sortedlist.cs
- AsyncCodeActivityContext.cs
- BulletedListEventArgs.cs
- RuntimeWrappedException.cs
- ResolveCriteriaApril2005.cs
- DataGridViewCellLinkedList.cs
- DrawingContextWalker.cs
- TransportSecurityBindingElement.cs
- SafeRightsManagementQueryHandle.cs
- TypeDelegator.cs
- FillErrorEventArgs.cs
- XmlSerializerVersionAttribute.cs
- AlternateView.cs
- EditingCoordinator.cs
- DataTableClearEvent.cs
- DataServiceResponse.cs
- FlowchartStart.xaml.cs
- TypedAsyncResult.cs
- COM2TypeInfoProcessor.cs
- CapabilitiesUse.cs
- CqlLexerHelpers.cs
- LeftCellWrapper.cs
- CatalogPartCollection.cs
- FontStretchConverter.cs
- Message.cs
- NativeMethods.cs
- ContactManager.cs
- XmlRawWriterWrapper.cs
- DataSourceConverter.cs
- DeleteBookmarkScope.cs
- columnmapkeybuilder.cs
- ListViewAutomationPeer.cs
- Pts.cs
- UriSection.cs
- XmlSchemaInclude.cs
- OuterGlowBitmapEffect.cs
- ConvertEvent.cs
- PackWebRequestFactory.cs
- ToolStripMenuItem.cs
- ScrollItemPattern.cs
- SmtpCommands.cs
- IntellisenseTextBox.cs
- MessageSecurityTokenVersion.cs
- PolyBezierSegmentFigureLogic.cs
- DomainUpDown.cs
- TypeNameParser.cs
- DesignerVerbCollection.cs
- LocatorBase.cs
- XmlUtilWriter.cs
- ToolStripMenuItemDesigner.cs
- EncryptedPackage.cs
- ExpandSegment.cs
- NameTable.cs
- CornerRadius.cs
- OpacityConverter.cs
- DependencySource.cs
- RootBuilder.cs
- EventData.cs
- CatalogZone.cs
- MsmqMessageProperty.cs
- TextTrailingCharacterEllipsis.cs
- WebPartDeleteVerb.cs
- Parallel.cs
- SchemaCollectionPreprocessor.cs
- MissingMemberException.cs
- CornerRadius.cs
- Int16Storage.cs
- TagElement.cs
- isolationinterop.cs
- returneventsaver.cs
- NullReferenceException.cs
- HotSpotCollection.cs
- SystemException.cs
- KeyedHashAlgorithm.cs
- PerformanceCounters.cs
- Crc32.cs
- Vector3DConverter.cs
- _ProxyChain.cs
- SamlAuthorityBinding.cs
- TextServicesManager.cs
- SystemPens.cs
- GridItemCollection.cs