/// Last Modified: 10/18/10 /// <summary> /// A static method that decrypts a byte array based on the scheme & passphrase provided. /// </summary> /// ----------------------------------------------------- /// PRECONDITIONS: Refer to the following arguments. /// ----------------------------------------------------- /// <param name="passphrase"> /// Is a 16-character word that is used as a key for decryption. /// </param> /// <param name="es"> /// Determines the decryption type being used. /// </param> /// <param name="rawBytes"> /// An array of raw bytes to decrypted. /// </param> /// <param name="byteCount"> /// The byte count of the raw bytes. This argument also contains the number of transformed bytes after transformation. /// </param> /// ----------------------------------------------------- /// POSTCONDITIONS: Refer to the return statement. /// ----------------------------------------------------- /// <returns> /// Returns a decrypted series of bytes based on the passphrase. /// </returns> public static byte[] PassphraseByteDecrypt(string passphrase, EncryptionScheme es, byte[] rawBytes, ref int byteCount) { MemoryStream mStream = null; CryptoStream readerStream = null; try { //Make sure the passphrase is exactly 16-characters. passphrase = PreparePassphrase(passphrase); //Instantiate the memory stream with the bytes of the encrypted message. mStream = new MemoryStream(rawBytes, 0, byteCount); //Create the stream for decryption. readerStream = new CryptoStream(mStream, GetCryptoTransform(EncryptionScheme.AES, false, passphrase, passphrase), CryptoStreamMode.Read); //Obtain the transformed bytes. byte[] transformedBytes = new byte[byteCount]; byteCount = readerStream.Read(transformedBytes, 0, byteCount); //Return the series of bytes. return transformedBytes; } finally { //Cleanup. mStream.Close(); readerStream.Close(); } }
public void Deserialize(Stream input) { var basePosition = input.Position; // read as two unsigned longs so we don't have to actually // decode the strings var version1 = input.ReadValueU64(false); var version2 = input.ReadValueU64(false); if (version1 == 0x4552462056322E31) // ERF V2.1 { input.Seek(basePosition + 8, SeekOrigin.Begin); throw new NotSupportedException(); } else if (version1 == 0x4500520046002000 && version2 == 0x560032002E003000) // ERF V2.0 { input.Seek(basePosition + 16, SeekOrigin.Begin); this.Version = 1; var fileCount = input.ReadValueU32(); var unknown14 = input.ReadValueU32(); var unknown18 = input.ReadValueU32(); var unknown1C = input.ReadValueU32(); this.Flags = 0; this.Encryption = EncryptionScheme.None; this.Compression = CompressionScheme.None; this.ContentId = 0; this.PasswordDigest = null; this.Entries.Clear(); for (uint i = 0; i < fileCount; i++) { var entry = new Entry(); entry.Name = input.ReadString(64, true, Encoding.Unicode); entry.CalculateHashes(); entry.Offset = input.ReadValueU32(); entry.UncompressedSize = input.ReadValueU32(); entry.CompressedSize = entry.UncompressedSize; this.Entries.Add(entry); } } else if (version1 == 0x4500520046002000 && version2 == 0x560032002E003200) // ERF V2.2 { input.Seek(basePosition + 16, SeekOrigin.Begin); this.Version = 2; var fileCount = input.ReadValueU32(); var year = input.ReadValueU32(); var day = input.ReadValueU32(); var unknown1C = input.ReadValueU32(); // always 0xFFFFFFFF? var flags = input.ReadValueU32(); var contentId = input.ReadValueU32(); var passwordDigest = new byte[16]; input.Read(passwordDigest, 0, passwordDigest.Length); if (unknown1C != 0xFFFFFFFF) { throw new InvalidOperationException(); } this.Flags = (flags & 0x1FFFFF0F) >> 0; this.Encryption = (EncryptionScheme)((flags & 0x000000F0) >> 4); this.Compression = (CompressionScheme)((flags & 0xE0000000) >> 29); if (this.Flags != 0 && this.Flags != 1) { throw new FormatException("unknown flags value"); } this.ContentId = contentId; this.PasswordDigest = passwordDigest; this.Entries.Clear(); for (uint i = 0; i < fileCount; i++) { var entry = new Entry(); entry.Name = input.ReadString(64, true, Encoding.Unicode); entry.CalculateHashes(); entry.Offset = input.ReadValueU32(); entry.CompressedSize = input.ReadValueU32(); entry.UncompressedSize = input.ReadValueU32(); this.Entries.Add(entry); } } else if (version1 == 0x4500520046002000 && version2 == 0x560033002E003000) // ERF V3.0 { input.Seek(basePosition + 16, SeekOrigin.Begin); this.Version = 3; var stringTableSize = input.ReadValueU32(); var fileCount = input.ReadValueU32(); var flags = input.ReadValueU32(); var contentId = input.ReadValueU32(); var passwordDigest = new byte[16]; input.Read(passwordDigest, 0, passwordDigest.Length); this.Flags = (flags & 0x1FFFFF0F) >> 0; this.Encryption = (EncryptionScheme)((flags & 0x000000F0) >> 4); this.Compression = (CompressionScheme)((flags & 0xE0000000) >> 29); if (this.Flags != 0 && this.Flags != 1) { throw new FormatException("unknown flags value"); } this.ContentId = contentId; this.PasswordDigest = passwordDigest; MemoryStream stringTable = stringTableSize == 0 ? null : input.ReadToMemoryStream(stringTableSize); this.Entries.Clear(); for (uint i = 0; i < fileCount; i++) { var entry = new Entry(); uint nameOffset = input.ReadValueU32(); entry.NameHash = input.ReadValueU64(); if (nameOffset != 0xFFFFFFFF) { if (nameOffset + 1 > stringTable.Length) { throw new FormatException("file name exceeds string table bounds"); } stringTable.Position = nameOffset; entry.Name = stringTable.ReadStringZ(Encoding.ASCII); if (entry.Name.HashFNV64() != entry.NameHash) { throw new InvalidOperationException("hash mismatch"); } } else { entry.Name = null; } entry.TypeHash = input.ReadValueU32(); entry.Offset = input.ReadValueU32(); entry.CompressedSize = input.ReadValueU32(); entry.UncompressedSize = input.ReadValueU32(); this.Entries.Add(entry); } } else { throw new FormatException("unsupported / unknown ERF format"); } }
//----------------------------------------------------------------------------- // createEncDef //----------------------------------------------------------------------------- /// <summary> /// Creates a new prefix definition in the dictionary. /// </summary> /// <param name="sEncName"> /// Encryption definition name. /// </param> /// <param name="eEncType"> /// Encryption type. /// </param> /// <param name="uiRequestedId"> /// If non-zero, then XFLAIM will try to use this /// number as the name ID of the new definition. /// </param> /// <returns> /// Returns the name ID of the new definition. /// </returns> public uint createEncDef( string sEncName, EncryptionScheme eEncType, uint uiRequestedId) { RCODE rc; uint uiKeySize = 128; string sEncType = "aes"; switch (eEncType) { case EncryptionScheme.ENC_AES128: uiKeySize = 128; sEncType = "aes"; break; case EncryptionScheme.ENC_AES192: uiKeySize = 192; sEncType = "aes"; break; case EncryptionScheme.ENC_AES256: uiKeySize = 256; sEncType = "aes"; break; case EncryptionScheme.ENC_DES3: uiKeySize = 168; sEncType = "des3"; break; default: throw new XFlaimException( RCODE.NE_XFLM_INVALID_PARM); } if ((rc = xflaim_Db_createEncDef( m_pDb, sEncType, sEncName, uiKeySize, ref uiRequestedId)) != 0) { throw new XFlaimException(rc); } return( uiRequestedId); }
/// Last Modified: 10/10/10 /// <summary> /// Returns the appropriate ICryptoTransform object based on the encryption scheme, direction, /// key, and initialization vector. /// </summary> /// ----------------------------------------------------- /// PRECONDITIONS: Refer to the following arguments. /// ----------------------------------------------------- /// <param name="es"> /// Encryption scheme being requested. /// </param> /// <param name="isEncryption"> /// True for encryption. False for decryption. /// </param> /// <param name="key"> /// A key in string form to use. /// NOTE: This value MUST be 16-characters long. /// </param> /// <param name="IV"> /// An initialization vector in string form to use. /// NOTE: This value MUST be 16-characters long. /// </param> /// ----------------------------------------------------- /// POSTCONDITIONS: Refer to the return statement. /// ----------------------------------------------------- /// <returns> /// Returns a decrypts string based on the passphrase. /// </returns> private static ICryptoTransform GetCryptoTransform(EncryptionScheme es, bool isEncryption, string key, string IV) { if (key.Length != 16) throw new Exception("The key is an incorrect length and must be 16-characters long."); if (IV.Length != 16) throw new Exception("The IV is an incorrect length and must be 16-characters long."); ASCIIEncoding enc = new ASCIIEncoding(); switch (es) { case EncryptionScheme.AES: { AesCryptoServiceProvider aes = new AesCryptoServiceProvider(); aes.KeySize = 128; aes.Key = enc.GetBytes(key); aes.IV = enc.GetBytes(IV); return isEncryption ? aes.CreateEncryptor() : aes.CreateDecryptor(); } case EncryptionScheme.DES: { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); des.KeySize = 128; des.Key = enc.GetBytes(key); des.IV = enc.GetBytes(IV); return isEncryption ? des.CreateEncryptor() : des.CreateDecryptor(); } } return null; }
/// Last Modified: 10/12/10 /// <summary> /// A static method that encrypts a msg based on the scheme & passphrase provided. /// </summary> /// ----------------------------------------------------- /// PRECONDITIONS: Refer to the following arguments. /// ----------------------------------------------------- /// <param name="passphrase"> /// Is a 16-character word that is used as a key for encryption. /// </param> /// <param name="es"> /// Determines the encryption type being used. /// </param> /// <param name="Msg"> /// The string being encrypted. /// </param> /// ----------------------------------------------------- /// POSTCONDITIONS: Refer to the return statement. /// ----------------------------------------------------- /// <returns> /// Returns an encrypted string based on the passphrase. /// </returns> public static string PassphraseStrEncrypt(string passphrase, EncryptionScheme es, string Msg) { //Return the encrypted series of bytes as a string. return Convert.ToBase64String(PassphraseByteEncrypt(passphrase, es, Encoding.Default.GetBytes(Msg))); }
/// Last Modified: 10/25/10 /// <summary> /// A static method that decrypts a string based on the scheme & passphrase provided. /// </summary> /// ----------------------------------------------------- /// PRECONDITIONS: Refer to the following arguments. /// ----------------------------------------------------- /// <param name="passphrase"> /// Is a 16-character word that is used as a key for decryption. /// </param> /// <param name="es"> /// Determines the decryption type being used. /// </param> /// <param name="Msg"> /// The string being decrypted. /// </param> /// ----------------------------------------------------- /// POSTCONDITIONS: Refer to the return statement. /// ----------------------------------------------------- /// <returns> /// Returns a decrypts string based on the passphrase. /// </returns> public static string PassphraseStrDecrypt(string passphrase, EncryptionScheme es, string Msg) { byte[] byRaw = Convert.FromBase64String(Msg); int byteCount = byRaw.Length; byte[] byTransformed = PassphraseByteDecrypt(passphrase, es, byRaw, ref byteCount); //Convert and return the series of bytes as a string. ASCIIEncoding enc = new ASCIIEncoding(); return enc.GetString(byTransformed, 0, byteCount); }
/// Last Modified: 10/10/10 /// <summary> /// A static method that encrypts a byte array based on the scheme & passphrase provided. /// </summary> /// ----------------------------------------------------- /// PRECONDITIONS: Refer to the following arguments. /// ----------------------------------------------------- /// <param name="passphrase"> /// Is a 16-character word that is used as a key for encryption. /// </param> /// <param name="es"> /// Determines the encryption type being used. /// </param> /// <param name="rawBytes"> /// An array of raw bytes to encryption. /// </param> /// ----------------------------------------------------- /// POSTCONDITIONS: Refer to the return statement. /// ----------------------------------------------------- /// <returns> /// Returns an encrypted series of bytes based on the passphrase. /// </returns> public static byte[] PassphraseByteEncrypt(string passphrase, EncryptionScheme es, byte[] rawBytes) { CryptoStream writerStream = null; MemoryStream mStream = null; try { //Make sure the passphrase is exactly 16-characters. passphrase = PreparePassphrase(passphrase); mStream = new MemoryStream(); //Create the stream for encryption. writerStream = new CryptoStream(mStream, GetCryptoTransform(EncryptionScheme.AES, true, passphrase, passphrase), CryptoStreamMode.Write); //Write those bytes to the stream. writerStream.Write(rawBytes, 0, rawBytes.Length); writerStream.FlushFinalBlock(); //Obtain the transformed bytes. byte[] transformedBytes = mStream.ToArray(); //Return the encrypted series of bytes. return transformedBytes; } finally { //Clean up. mStream.Close(); writerStream.Close(); } }