Format of AES, Blowfish, Twofish, 3DES, etc. Symmetric Encrypted Data?

Question:

I know it isn’t listed in the documentation, but is there any method to test whether a file has been previously encrypted or not?  I would like to perform decryption on a file, but only if it is already encrypted.

Answer:

A symmetric encryption algorithm is simply a transformation of bytes such that the output has the properties of randomly generated byte data.  There is no file format, and each byte value from 0x00 to 0xFF is virtually equally probable.

There is no single test that can be performed to determine if a file is already encrypted.  There are two solutions:

  1. Create your own test based on the  type of file being encrypted.  For example, if XML files are encrypted, then test to see if “<xml” is found in the beginning.
  2. Create your own simple “encrytped file format”.  For example, it could be as easy as writing a 4-byte “marker” at the beginning of every file containing encrypted data.  The marker would be a constant value, such as 0x01020304.  Your application could read the 1st 4 bytes of a file, and if equal to 0x01, 0x02, 0x03, 0x04, then it discards the marker and knows the remainder is the encrypted file data..

C# Blowfish Test Vectors

C# to match the Blowfish test vectors at this URL: http://www.schneier.com/code/vectors.txt

    // keys
    string[] key = new string[] { 
        "0000000000000000",
        "FFFFFFFFFFFFFFFF",
        "3000000000000000",
        "1111111111111111",
        "0123456789ABCDEF",
        "1111111111111111",
        "0000000000000000",
        "FEDCBA9876543210",
        "7CA110454A1A6E57",
        "0131D9619DC1376E",
        "07A1133E4A0B2686",
        "3849674C2602319E",
        "04B915BA43FEB5B6",
        "0113B970FD34F2CE",
        "0170F175468FB5E6",
        "43297FAD38E373FE",
        "07A7137045DA2A16",
        "04689104C2FD3B2F",
        "37D06BB516CB7546",
        "1F08260D1AC2465E",
        "584023641ABA6176",
        "025816164629B007",
        "49793EBC79B3258F",
        "4FB05E1515AB73A7",
        "49E95D6D4CA229BF",
        "018310DC409B26D6",
        "1C587F1C13924FEF",
        "0101010101010101",
        "1F1F1F1F0E0E0E0E",
        "E0FEE0FEF1FEF1FE",
        "0000000000000000",
        "FFFFFFFFFFFFFFFF",
        "0123456789ABCDEF",
        "FEDCBA9876543210" };

    string[] plainText = new string[] { 
        "0000000000000000",
        "FFFFFFFFFFFFFFFF",
        "1000000000000001",
        "1111111111111111",
        "1111111111111111",
        "0123456789ABCDEF",
        "0000000000000000",
        "0123456789ABCDEF",
        "01A1D6D039776742",
        "5CD54CA83DEF57DA",
        "0248D43806F67172",
        "51454B582DDF440A",
        "42FD443059577FA2",
        "059B5E0851CF143A",
        "0756D8E0774761D2",
        "762514B829BF486A",
        "3BDD119049372802",
        "26955F6835AF609A",
        "164D5E404F275232",
        "6B056E18759F5CCA",
        "004BD6EF09176062",
        "480D39006EE762F2",
        "437540C8698F3CFA",
        "072D43A077075292",
        "02FE55778117F12A",
        "1D9D5C5018F728C2",
        "305532286D6F295A",
        "0123456789ABCDEF",
        "0123456789ABCDEF",
        "0123456789ABCDEF",
        "FFFFFFFFFFFFFFFF",
        "0000000000000000",
        "0000000000000000",
        "FFFFFFFFFFFFFFFF" };

    string[] cipherBytes = new string[] { 
        "4EF997456198DD78",
        "51866FD5B85ECB8A",
        "7D856F9A613063F2",
        "2466DD878B963C9D",
        "61F9C3802281B096",
        "7D0CC630AFDA1EC7",
        "4EF997456198DD78",
        "0ACEAB0FC6A0A28D",
        "59C68245EB05282B",
        "B1B8CC0B250F09A0",
        "1730E5778BEA1DA4",
        "A25E7856CF2651EB",
        "353882B109CE8F1A",
        "48F4D0884C379918",
        "432193B78951FC98",
        "13F04154D69D1AE5",
        "2EEDDA93FFD39C79",
        "D887E0393C2DA6E3",
        "5F99D04F5B163969",
        "4A057A3B24D3977B",
        "452031C1E4FADA8E",
        "7555AE39F59B87BD",
        "53C55F9CB49FC019",
        "7A8E7BFA937E89A3",
        "CF9C5D7A4986ADB5",
        "D1ABB290658BC778",
        "55CB3774D13EF201",
        "FA34EC4847B268B2",
        "A790795108EA3CAE",
        "C39E072D9FAC631D",
        "014933E0CDAFF6E4",
        "F21E9A77B71C49BC",
        "245946885754369A",
        "6B5C5A9C5D9E0A5A" };

    Chilkat.Crypt2 crypt = new Chilkat.Crypt2();

    bool success;
    success = crypt.UnlockComponent("Anything for 30-day trial");
    if (success != true)
    {
        MessageBox.Show("Crypt component unlock failed");
        return;
    }

    //  Attention: use "blowfish2" for the algorithm name:
    crypt.CryptAlgorithm = "blowfish2";

    //  CipherMode may be "ecb", "cbc", or "cfb"
    crypt.CipherMode = "ecb";

    //  KeyLength (in bits) may be a number between 32 and 448.
    //  128-bits is usually sufficient.  The KeyLength must be a
    //  multiple of 8.
    crypt.KeyLength = 64;

    //  The padding scheme determines the contents of the bytes
    //  that are added to pad the result to a multiple of the
    //  encryption algorithm's block size.  Blowfish has a block
    //  size of 8 bytes, so encrypted output is always
    //  a multiple of 8.
    crypt.PaddingScheme = 3;

    //  EncodingMode specifies the encoding of the output for
    //  encryption, and the input for decryption.
    //  It may be "hex", "url", "base64", or "quoted-printable".
    crypt.EncodingMode = "hex";


    int numTests = key.Length;
    int i;

    for (i = 0; i < numTests; i++)
    {
        crypt.SetEncodedKey(key[i], "hex");

        string encStr = crypt.EncryptEncoded(plainText[i]);
        textBox1.Text += encStr + " should equal " + cipherBytes[i] + "\r\n";
    }