/// <summary> /// This routine opens the .dat file, reads in the salt and IV, and then /// sets the crypto object's key and IV. /// </summary> private void OpenSaltIVFileAndSetKeyIV() { // Initialize the byte arrays to the proper length for the // instantiated crypto class. ReDimByteArrays(); // Create a Filestream object to read in the contents of the .dat file // that contains the salt and IV. FileStream fsKey = new FileStream(strSaltIVFile, FileMode.Open, FileAccess.Read); fsKey.Read(abytSalt, 0, abytSalt.Length); fsKey.Read(abytIV, 0, abytIV.Length); fsKey.Close(); // Derive the key from the salted Text. PasswordDeriveBytes pdb = new PasswordDeriveBytes(strText, abytSalt); // Get the same amount of bytes the current abytKey length set in // ReDimByteArrays(). abytKey = pdb.GetBytes(abytKey.Length); // if the current crypto class is TripleDES, check to make sure the key being // used is not listed among the Weak Keys (i.e., keys known to have been // successfully attacked). if (crpSym.GetType() == typeof(TripleDESCryptoServiceProvider)) { // To access the IsWeakKey method you have to cast the SymmetricAlgorithm // variable type to the TripleDES base class or // TripleDESCryptoServiceProvider. TripleDES tdes = (TripleDES)crpSym; if (TripleDES.IsWeakKey(abytKey)) { throw new Exception("The current key is listed a Weak Key. " + "You should generate a different key before proceeding further."); } } // Assign the byte arrays to the Key and IV properties of the instantiated // symmetric crypto class. crpSym.Key = abytKey; crpSym.IV = abytIV; }
#pragma warning disable SYSLIB0022 // Rijndael types are obsolete /// <summary> /// Get specification URL from algorithm implementation /// </summary> /// <param name="key"></param> /// <returns></returns> public static string GetEncryptionMethodName(SymmetricAlgorithm key, bool keyWrap = false) { if (key is TripleDES) { return(keyWrap ? EncryptedXml.XmlEncTripleDESKeyWrapUrl : EncryptedXml.XmlEncTripleDESUrl); } else if (key is DES) { return(keyWrap ? EncryptedXml.XmlEncTripleDESKeyWrapUrl : EncryptedXml.XmlEncDESUrl); } else if (key is Rijndael || key is Aes) { switch (key.KeySize) { case 128: return(keyWrap ? EncryptedXml.XmlEncAES128KeyWrapUrl : EncryptedXml.XmlEncAES128Url); case 192: return(keyWrap ? EncryptedXml.XmlEncAES192KeyWrapUrl : EncryptedXml.XmlEncAES192Url); case 256: return(keyWrap ? EncryptedXml.XmlEncAES256KeyWrapUrl : EncryptedXml.XmlEncAES256Url); } } throw new ArgumentException($"The specified algorithm `{key.GetType().FullName}` is not supported for XML Encryption."); }
private static void ValidateBlockSize( SymmetricAlgorithm algorithm, IReadOnlyCollection <byte> initializationVector) { // Array length is bytes, IV size measured in bits. int initializationVectorSize = initializationVector.Count * BitsPerByte; // (BitsPerByte == 8) if (algorithm.ValidKeySize(initializationVectorSize)) { return; } string message = string.Format( "The size of the given initialization vector ({0}) does not match a valid block size ({2}) for the \"{1}\" algorithm.", initializationVector.Count, algorithm.GetType().Name, algorithm.LegalBlockSizes.Select( legalBlockSize => string.Format( "Max{0}Min{1}Skip{2}", legalBlockSize.MaxSize, legalBlockSize.MinSize, legalBlockSize.SkipSize)) .ToDelimitedString(", ")); //// Contract.Requires<ArgumentOutOfRangeException>( //// algorithm.ValidBlockSize(initializationVectorSize), message); throw new TypeInitializationException( "MiscCorLib.Security.Cryptography.SymmetricTransformer", new ArgumentOutOfRangeException("initializationVector", message)); }
public override string ToString() { return(String.Format(CultureInfo.InvariantCulture, Properties.Resources.SymmetricAlgorithmShimString, GetType(), m_wrappedAlgorithm.GetType())); }
private void GenerateAndPrintKey(SymmetricAlgorithm alg) { alg.GenerateKey(); alg.GenerateIV(); var algName = alg.GetType().Name.PadRight(30); var hexKey = HexUtil.ByteArrayToHex(alg.Key); Debug.WriteLine($"Algorithm: {algName}, keySize(bits): {alg.KeySize}, key: {hexKey}"); }
public byte[] DeriveKey(string password) { var passwordDeriveBytes = new PasswordDeriveBytes(password, PasswordSalt); var initialVector = new byte[InitialVector.Length]; InitialVector.CopyTo(initialVector, 0); return(passwordDeriveBytes.CryptDeriveKey(SymmetricAlgorithm.GetType().BaseType.Name, PasswordHashAlgorithm.GetType().BaseType.Name, SymmetricAlgorithm.LegalKeySizes.First().MaxSize, initialVector)); }
private static byte[]? DecryptContent( ReadOnlyMemory <byte> encryptedContent, byte[] cek, AlgorithmIdentifierAsn contentEncryptionAlgorithm, out Exception?exception) { exception = null; int encryptedContentLength = encryptedContent.Length; byte[]? encryptedContentArray = CryptoPool.Rent(encryptedContentLength); try { encryptedContent.CopyTo(encryptedContentArray); using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) { ICryptoTransform decryptor; try { decryptor = alg.CreateDecryptor(cek, alg.IV); } catch (ArgumentException ae) { // Decrypting or deriving the symmetric key with the wrong key may still succeed // but produce a symmetric key that is not the correct length. throw new CryptographicException(SR.Cryptography_Cms_InvalidSymmetricKey, ae); } using (decryptor) { // If we extend this library to accept additional algorithm providers // then a different array pool needs to be used. Debug.Assert(alg.GetType().Assembly == typeof(Aes).Assembly); return(decryptor.OneShot( encryptedContentArray, 0, encryptedContentLength)); } } } catch (CryptographicException e) { exception = e; return(null); } finally { CryptoPool.Return(encryptedContentArray, encryptedContentLength); encryptedContentArray = null; } }
// Find a valid key size for this algorithm. private static int FindKeySize(SymmetricAlgorithm algorithm) { for (int i = 1024; i > 1; i--) { if (algorithm.ValidKeySize(i)) { return(i); } } throw new InvalidOperationException( $"Cannot find a valid key size for {algorithm.GetType().Name}."); }
/// <summary> /// Initializes an instance of the SecuritySession_KnownSymmetric class. /// </summary> /// <param name="symmetricAlgorithm">The symmetricAlgorithm to be used.</param> /// <param name="name">The name of the security context.</param> public SecuritySession_KnownSymmetric(SymmetricAlgorithm symmetricAlgorithm, string name) : base(name, null) { // LOG: BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter; if (binaryLogWriter != null && binaryLogWriter[LogCategory.Security] > 0) { binaryLogWriter.WriteEvent(LogCategory.Security, "SecuritySession_KnownSymmetric.SecuritySession_KnownSymmetric", LogMessageType.SecuritySessionKey, null, null, this.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this, name, -1, 0, 0, 0, "Encryption using " + symmetricAlgorithm.GetType().ToString(), null, null, null, "Security Session security information is initialized."); } this.SymmetricAlgorithm = symmetricAlgorithm; this._encryptor = this.SymmetricAlgorithm.CreateEncryptor(); this._decryptor = this.SymmetricAlgorithm.CreateDecryptor(); this.IsEstablishedEvent.Set(); }
private static byte[]? DecryptContent( ReadOnlyMemory <byte> encryptedContent, byte[] cek, AlgorithmIdentifierAsn contentEncryptionAlgorithm, out Exception?exception) { exception = null; int encryptedContentLength = encryptedContent.Length; byte[]? encryptedContentArray = CryptoPool.Rent(encryptedContentLength); try { encryptedContent.CopyTo(encryptedContentArray); using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) using (ICryptoTransform decryptor = alg.CreateDecryptor(cek, alg.IV)) { // If we extend this library to accept additional algorithm providers // then a different array pool needs to be used. Debug.Assert(alg.GetType().Assembly == typeof(Aes).Assembly); return(decryptor.OneShot( encryptedContentArray, 0, encryptedContentLength)); } } catch (CryptographicException e) { exception = e; return(null); } finally { CryptoPool.Return(encryptedContentArray, encryptedContentLength); encryptedContentArray = null; } }
internal SymmetricEncryptionState(byte[] key, byte[] iv, SymmetricAlgorithm algorithm, Type baseAlgorithmType, bool compareCipherModes) { if (key == null) { throw new ArgumentNullException("key"); } if (iv == null) { throw new ArgumentNullException("iv"); } Debug.Assert(algorithm != null, "algorithm != null"); Debug.Assert(baseAlgorithmType != null, "baseAlgorithmType != null"); Debug.Assert(typeof(SymmetricAlgorithm).IsAssignableFrom(baseAlgorithmType), "typeof(SymmetricAlgorithm).IsAssignableFrom(baseAlgorithmType)"); m_baseAlgorithmType = baseAlgorithmType; m_compareCipherModes = compareCipherModes; m_algorithm = GetAlgorithmType(algorithm.GetType()); m_blockSize = algorithm.BlockSize; m_cipherMode = algorithm.Mode; m_paddingMode = algorithm.Padding; if (m_compareCipherModes && CipherModeUsesFeedback(algorithm.Mode)) { m_feedbackSize = algorithm.FeedbackSize; } m_iv = new byte[iv.Length]; Array.Copy(iv, m_iv, m_iv.Length); m_key = new byte[key.Length]; Array.Copy(key, m_key, m_key.Length); }
public SymmetricCipherPair(byte[] cipher, byte[] iv, SymmetricAlgorithm alg) : base(cipher, iv) { Condition.Requires(alg).IsNotNull(); this.AlgorithmType = alg.GetType(); }
/// <summary> /// Initializes a new instance of the EncryptionProvider class. /// </summary> /// <param name="algorithm">The symmetric algorithm to use during cryptographic transformations.</param> /// <param name="padding">The padding mode to use.</param> /// <param name="mode">The cipher mode to use.</param> /// <param name="key">The key to use.</param> /// <param name="iv">The initialization vector to use.</param> public EncryptionProvider(SymmetricAlgorithm algorithm, byte[] key, byte[] iv) { _algorithm = algorithm; // _algorithm.Padding = PaddingMode.PKCS7; // _algorithm.Mode = CipherMode.CBC; _algorithm.Key = key; _algorithm.IV = iv; foreach (KeySizes keySize in _algorithm.LegalKeySizes) { Debug.WriteLine(string.Format("Algorithm: {0}, KeyMaxSize: {1}, KeyMinSize: {2}", _algorithm.GetType().Name, keySize.MaxSize, keySize.MinSize)); } }
// Specifies the assymetric and the symmetric algorithm to use, and if it // must run as client or server. public SecureStream(Stream baseStream, RSACryptoServiceProvider rsa, string symmetricAlgorithmName, bool runAsServer) { if (baseStream == null) { throw new ArgumentNullException("baseStream"); } if (rsa == null) { throw new ArgumentNullException("rsa"); } if (string.IsNullOrEmpty(symmetricAlgorithmName)) { throw new ArgumentNullException("symmetricAlgorithm"); } BaseStream = baseStream; //SymmetricAlgorithm = SymmetricAlgorithm.Create(symmetricAlgorithmName); //symmetricAlgorithm; //string symmetricTypeName = SymmetricAlgorithm.GetType().ToString(); //byte[] symmetricTypeBytes = Encoding.UTF8.GetBytes(symmetricTypeName); if (runAsServer) { //1.Send symmetric algorithm name SymmetricAlgorithm = SymmetricAlgorithm.Create(symmetricAlgorithmName); //symmetricAlgorithm; string symmetricTypeName = SymmetricAlgorithm.GetType().ToString(); byte[] symmetricTypeBytes = Encoding.UTF8.GetBytes(symmetricTypeName); byte[] sizeBytes = BitConverter.GetBytes(symmetricTypeBytes.Length); baseStream.Write(sizeBytes, 0, sizeBytes.Length); baseStream.Write(symmetricTypeBytes, 0, symmetricTypeBytes.Length); //send public key byte[] bytes = rsa.ExportCspBlob(false); //public key sizeBytes = BitConverter.GetBytes(bytes.Length); baseStream.Write(sizeBytes, 0, sizeBytes.Length); baseStream.Write(bytes, 0, bytes.Length); //3.Recive symmetric algorithm key and IV SymmetricAlgorithm.Key = p_ReadWithLength(rsa);; SymmetricAlgorithm.IV = p_ReadWithLength(rsa); } else { // ok. We run as the client, so first we first check the // algorithm types and then receive the assymetric // key from the server. // symmetricAlgorithm var sizeBytes = new byte[4]; p_ReadDirect(sizeBytes); var stringLength = BitConverter.ToInt32(sizeBytes, 0); //if (stringLength != symmetricTypeBytes.Length) // throw new ArgumentException("Server and client must use the same SymmetricAlgorithm class."); var stringBytes = new byte[stringLength]; p_ReadDirect(stringBytes); // var str = Encoding.UTF8.GetString(stringBytes); var symmetricTypeName = Encoding.UTF8.GetString(stringBytes); SymmetricAlgorithm = SymmetricAlgorithm.Create(symmetricTypeName); //if (str != symmetricTypeName) // throw new ArgumentException("Server and client must use the same SymmetricAlgorithm class."); // public key. sizeBytes = new byte[4]; p_ReadDirect(sizeBytes); int asymmetricKeyLength = BitConverter.ToInt32(sizeBytes, 0); byte[] bytes = new byte[asymmetricKeyLength]; p_ReadDirect(bytes); rsa.ImportCspBlob(bytes); // Now that we have the asymmetricAlgorithm set, and considering // that the symmetricAlgorithm initializes automatically, we must // only send the key. p_WriteWithLength(rsa, SymmetricAlgorithm.Key); p_WriteWithLength(rsa, SymmetricAlgorithm.IV); } // After the object initialization being done, be it a client or a // server, we can dispose the assymetricAlgorithm. rsa.Clear(); Decryptor = SymmetricAlgorithm.CreateDecryptor(); Encryptor = SymmetricAlgorithm.CreateEncryptor(); fReadBuffer = fEmptyReadBuffer; fWriteBuffer = new MemoryStream(32 * 1024); }
private void ConfigureAlg(SymmetricAlgorithm alg) { //check for a valid key if (this.inputKey == null) { //create a trivial key inputKey = new byte[16]; // write a warning to the ouside word GuiLogMessage("WARNING - No key provided. Using 0x000..00!", NotificationLevel.Warning); } try { alg.Key = this.inputKey; } catch (Exception) { //if alg.Key is set to an "unsecure" key, crappy ms class throws an exception :/ //so we have to hack in that key value var keyValue = alg.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance); keyValue.SetValue(alg, inputKey); } //check for a valid IV if (this.inputIV == null) { //create a trivial key inputIV = new byte[alg.BlockSize / 8]; if (settings.Mode != 0) // no IV needed for ECB { GuiLogMessage("WARNING - No IV provided. Using 0x000..00!", NotificationLevel.Warning); } } alg.IV = this.inputIV; switch (settings.Mode) { //0="ECB"=default, 1="CBC", 2="CFB", 3="OFB" case 1: alg.Mode = CipherMode.CBC; break; case 2: alg.Mode = CipherMode.CFB; break; case 3: alg.Mode = CipherMode.ECB; break; default: alg.Mode = CipherMode.ECB; break; } switch (settings.Padding) { // 0="None", 1="Zeros"=default, 2="PKCS7", 3="ANSIX923", 4="ISO10126", 5=", 5="1-0-padding" case 0: alg.Padding = PaddingMode.None; break; case 1: alg.Padding = PaddingMode.Zeros; break; case 2: alg.Padding = PaddingMode.PKCS7; break; case 3: alg.Padding = PaddingMode.ANSIX923; break; case 4: alg.Padding = PaddingMode.ISO10126; break; case 5: alg.Padding = PaddingMode.None; break; // 1-0 padding, use PaddingMode.None, as it's handeled separately default: alg.Padding = PaddingMode.Zeros; break; } alg.Padding = PaddingMode.None; }
private void GenerateKey(SymmetricAlgorithm alg) { alg.GenerateKey(); alg.GenerateIV(); Debug.WriteLine("Algorithm: " + alg.GetType().Name.PadRight(30) + " keySize(bits): " + alg.KeySize + " key: " + HexUtil.ByteArrayToHex(alg.Key)); }
/// <summary> /// Controlla correttezza formale chiave /// </summary> /// <param name="algorithm"></param> /// <param name="key"></param> private static void checkAlgoKey(SymmetricAlgorithm algorithm, byte[] key) { if (!algorithm.ValidKeySize(key.Length * 8)) { throw new ArgumentException(string.Format("La lunghezza della chiave fornita ({0} Bytes / {1} bits) non risulta compatibile con l'algoritmo selezionato {2}. Lunghezze supportate: Min-> {3} bits, Max-> {4} bits", key.Length, key.Length * 8, algorithm.GetType().Name, algorithm.LegalKeySizes[0].MinSize, algorithm.LegalKeySizes[0].MaxSize)); } }
private static byte[]? DecryptContent( ReadOnlyMemory <byte> encryptedContent, byte[] cek, AlgorithmIdentifierAsn contentEncryptionAlgorithm, out Exception?exception) { exception = null; // Windows compat: If the encrypted content is completely empty, even where it does not make sense for the // mode and padding (e.g. CBC + PKCS7), produce an empty plaintext. if (encryptedContent.IsEmpty) { return(Array.Empty <byte>()); } #if NET try { using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) { try { alg.Key = cek; } catch (CryptographicException ce) { throw new CryptographicException(SR.Cryptography_Cms_InvalidSymmetricKey, ce); } return(alg.DecryptCbc(encryptedContent.Span, alg.IV)); } } catch (CryptographicException ce) { exception = ce; return(null); } #else int encryptedContentLength = encryptedContent.Length; byte[] encryptedContentArray = CryptoPool.Rent(encryptedContentLength); try { encryptedContent.CopyTo(encryptedContentArray); using (SymmetricAlgorithm alg = OpenAlgorithm(contentEncryptionAlgorithm)) { ICryptoTransform decryptor; try { decryptor = alg.CreateDecryptor(cek, alg.IV); } catch (ArgumentException ae) { // Decrypting or deriving the symmetric key with the wrong key may still succeed // but produce a symmetric key that is not the correct length. throw new CryptographicException(SR.Cryptography_Cms_InvalidSymmetricKey, ae); } using (decryptor) { // If we extend this library to accept additional algorithm providers // then a different array pool needs to be used. Debug.Assert(alg.GetType().Assembly == typeof(Aes).Assembly); return(decryptor.OneShot( encryptedContentArray, 0, encryptedContentLength)); } } } catch (CryptographicException e) { exception = e; return(null); } finally { CryptoPool.Return(encryptedContentArray, encryptedContentLength); } #endif }
private void ConfigureAlg(SymmetricAlgorithm alg) { //check for a valid key if (this.inputKey == null) { //create a default key inputKey = new byte[settings.TripleDES ? 16 : 8]; // write a warning to the ouside world GuiLogMessage("ERROR: No key provided. Using 0x000..00!", NotificationLevel.Error); } if (settings.TripleDES) { if (this.inputKey.Length != 16 && this.inputKey.Length != 24) { throw new Exception(String.Format("The specified key has a length of {0} bytes. The selected variant TripleDES of the DES algorithm needs a keylength of 16 or 24 bytes.", this.inputKey.Length)); } } else { if (this.inputKey.Length != 8) { throw new Exception(String.Format("The specified key has a length of {0} bytes. The DES algorithm needs a keylength of 8 bytes.", this.inputKey.Length)); } } try { alg.Key = inputKey; } catch { //dirty hack to allow weak keys: FieldInfo field = alg.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance); field.SetValue(alg, inputKey); } //check for a valid IV int bsize = alg.BlockSize / 8; if (this.inputIV == null) { //create a default IV inputIV = new byte[bsize]; if (settings.Mode != 0) // ECB needs no IV, thus no warning if IV misses { GuiLogMessage("NOTE: No IV provided. Using 0x000..00!", NotificationLevel.Info); } } if (this.inputIV.Length != bsize) { if (settings.TripleDES) { throw new Exception(String.Format("The specified IV has a length of {0} bytes. The selected variant TripleDES of the DES algorithm needs an IV of {1} bytes.", this.inputIV.Length, bsize)); } else { throw new Exception(String.Format("The specified IV has a length of {0} bytes. The DES algorithm needs an IV of {1} bytes.", this.inputIV.Length, bsize)); } } alg.IV = this.inputIV; switch (settings.Mode) { // 0="ECB"=default, 1="CBC", 2="CFB", 3="OFB" case 1: alg.Mode = CipherMode.CBC; break; case 2: alg.Mode = CipherMode.CFB; break; case 3: alg.Mode = CipherMode.ECB; break; default: alg.Mode = CipherMode.ECB; break; } switch (settings.Padding) { // 0="None", 1="Zeros"=default, 2="PKCS7", 3="ANSIX923", 4="ISO10126", 5=", 5="1-0-padding" case 0: alg.Padding = PaddingMode.None; break; case 2: alg.Padding = PaddingMode.PKCS7; break; case 3: alg.Padding = PaddingMode.ANSIX923; break; case 4: alg.Padding = PaddingMode.ISO10126; break; case 5: alg.Padding = PaddingMode.None; break; // 1-0 padding, use PaddingMode.None, as it's handeled separately default: alg.Padding = PaddingMode.Zeros; break; } }
/// <summary> /// Validates the key iv. /// </summary> /// <param name="key">The key.</param> /// <param name="IV">The iv.</param> /// <param name="sa">The sa.</param> /// <exception cref="System.Security.Cryptography.CryptographicException"> /// </exception> private static void ValidateKeyIV(byte[] key, byte[] IV, SymmetricAlgorithm sa) { if (key.Length != sa.Key.Length) { var eMsg = string.Format("SymAlgorithmServices: -> Invalid key length for {0}. Keys must be {1} bytes in length.", sa.GetType().Name, sa.Key.Length); throw new CryptographicException(eMsg); } if (IV.Length != sa.IV.Length) { var eMsg = string.Format("SymAlgorithmServices: -> Invalid IV length for {0}. IVs must be {1} bytes in length.", sa.GetType().Name, sa.IV.Length); throw new CryptographicException(eMsg); } }
protected bool IsSupportedSymmetricAlgorithm(SymmetricAlgorithm symmetricAlgorithm) { Type baseType = symmetricAlgorithm.GetType().BaseType; return(AllowedSymmetricAlgorithms.Contains(baseType)); }