AES Crypt Stream Format

AES Crypt reads and writes data in the .aes stream format (or, "file format"). The stream format is easily identifiable by software. To date, there are three versions of the .aes stream format, which are numbered starting with version 0.

Stream format version 3 is shown below; it is the latest version. This stream format makes subtle improvements relative to the previous format, with each of the changes focused on improved security. Specificially, the Key Derivation Function (KDF) used in this version is much stronger than previous versions, making it substantially more difficult to brute-force attack a user's password. There were also changes to input into the HMAC for message authentication to address previously reported security concerns.

Click here to see a hex dump of a text file with the contents "Hello, World!" encrypted using AES Crypt using the v3 stream format and using the password "apples".

V3 Stream Format

 3 Octets - "AES"
 1 Octet  - Version (0x03)
 1 Octet  - Reserved (set to 0x00)
.... Start of repeating extension block section
 2 Octet  - Length in octets (in network byte order) of an extension identifier
            and contents.  If 0x0000, then no further extensions exist and the
            next octet is the start of the Initialization Vector (IV).
            Following an extension, this length indicator would appear again to
            indicate presence or absence of another extension and the size of
            any such extension.
nn Octets - Extension identifier.  This is either a URI or an standard
            identifier documented on the standard extensions page, either of
            which is terminated by a single 0x00 octet.  All extension
            identifiers are case sensitive.  URIs that use domain names,
            for example, must ensure the protocol and host portions lowercase.

                Examples of URIs:
                    http://aescrypt.com/extensions/creator/
                    urn:oid:1.3.6.1.4.1.17090.55.14
                    urn:uuid:85519EA3-1DA6-45b9-9041-8CD368D8C086

                Examples of standard extension identifiers:
                    CREATED_DATE
                    CREATED_BY

            A URI allows anyone to define an extension type without worrying
            about namespace conflicts.

            A special extension is defined that has no name, but is a
            "container" for extensions to be added after the AES stream is
            initially created.  Such an extension avoids the need to read and
            re-write the entire stream in order to add a small extension.
            Software tools that create AES Crypt streams should insert this
            128-octet "container" extension, placing a 0x00 in the first octet
            of the extension identifier field.  Developers may then insert
            extensions into this "container" area and reduce the size of this
            "container" as necessary.  If larger extensions are added or the
            "container" area is filled entirely, then reading and re-writing the
            entire stream would be necessary to add additional extensions.

            Note that extensions are neither encrypted nor authenticated.
            They may provide useful information, but they must not be relied
            upon by software to contain accurate information.
nn Octets - The contents of the extension
.... End of repeating extension block section
 4 octets - KDF iteration value (network byte order)
16 Octets - Initialization Vector (IV) used to encrypt the Session IV and
            Session Key
48 Octets - Encrypted Session IV and 256-bit AES Session Key used to encrypt the
            stream, protected by a raw key or PBKDF2-derived key
            (IV = 16 octets; Key = 32 octets)
32 Octets - HMAC-SHA256(48-octet IV and KEY || 0x03)
nn Octets - Ciphertext (AES-256 in CBC mode; PKCS#7 padded; 2^64 octets max)
32 Octets - HMAC-SHA256(nn octets)

The footprint of the stream is at least 140 octets.

Stream format version 2 is shown below. It is no longer written by AES Crypt, but it can consume streams created in this format. The major enhancement to this version is the ability to have user-defined "tags" that may be inserted as plaintext into the encrypted stream. These tags are inserted by AES Crypt or by other software that knows how to read and write the .aes stream format. These tags are not encrypted so that they may be read or altered after the .aes stream is created, without modifying the contents of the encrypted parts of the stream or knowing the key required to decrypt the stream. Tags should never be considered secure information.

V2 Stream Format

 3 Octets - "AES"
 1 Octet  - Version (0x02)
 1 Octet  - Reserved (set to 0x00; modulo moved to end of stream)
.... Start of repeating extension block section
 2 Octet  - Length in octets (in network byte order) of an extension identifier
            and contents.  If 0x0000, then no further extensions exist and the
            next octet is the start of the Initialization Vector (IV).
            Following an extension, this length indicator would appear again to
            indicate presence or absence of another extension and the size of
            any such extension.
nn Octets - Extension identifier.  This is either a URI or an identifier
            documented on the standard extensions page, either of which is
            terminated by a single 0x00 octet.  All extension identifiers are
            case sensitive.  URIs that use domain names, for example, must
            ensure the protocol and host portions lowercase.


                Examples of URIs:
                    http://aescrypt.com/extensions/creator/
                    urn:oid:1.3.6.1.4.1.17090.55.14
                    urn:uuid:85519EA3-1DA6-45b9-9041-8CD368D8C086

                Examples of standard extension identifiers:
                    CREATED_DATE
                    CREATED_BY

            A URI allows anyone to define an extension type without worrying
            about namespace conflicts.

            A special extension is defined that has no name, but is a
            "container" for extensions to be added after the AES stream is
            initially created.  Such an extension avoids the need to read and
            re-write the entire stream in order to add a small extension.
            Software tools that create AES Crypt streams should insert this
            128-octet "container" extension, placing a 0x00 in the first octet
            of the extension identifier field.  Developers may then insert
            extensions into this "container" area and reduce the size of this
            "container" as necessary.  If larger extensions are added or the
            "container" area is filled entirely, then reading and re-writing the
            entire stream would be necessary to add additional extensions.

            Note that extensions are neither encrypted nor authenticated.
            They may provide useful information, but they must not be relied
            upon by software to contain accurate information.
nn Octets - The contents of the extension
.... End of repeating extension block section
16 Octets - Initialization Vector (IV) used to encrypt the Session IV and
            Session Key
48 Octets - Encrypted Session IV and AES Session Key used to encrypt the stream
            (IV = 16 octets; Key = 32 octets)
32 Octets - HMAC-SHA256(48-octet IV and KEY)
nn Octets - Ciphertext (AES-256 in CBC mode; 2^64 octets max)
 1 Octet  - Ciphertext size modulo 16 in least significant bit positions
32 Octets - HMAC-SHA256(nn octets)

The footprint of the stream is at least 136 octets.

Stream format is version 1 is no longer written by AES Crypt, though it does have the ability to read streams in this format. Version 1 contains enhancements to allow the streams to be produced in "streaming" mode, which is suitable for use with Linux as part of a backup process, for example, where the tar command is used and output is sent to AES Crypt as standard input (stdin). The other benefit to version 1 is faster password verification. The password entered by the user is used to encrypt an initialization vector (IV) and 32-octet (256-bit) encryption key, both of which are randomly created. The password can be verified immediately after checking the HMAC that protects this IV and key. The format for version 1 is shown below.

V1 Stream Format

 3 Octets - "AES"
 1 Octet  - Version (0x01)
 1 Octet  - Reserved (set to 0x00; modulo moved to end of stream)
16 Octets - Initialization Vector (IV) used for encrypting the IV and symmetric
            key that is actually used to encrypt the bulk of the plaintext.
48 Octets - Encrypted IV and 256-bit AES key used to encrypt the bulk of the
            stream (IV = 16 octets; Key = 32 octets)
32 Octets - HMAC-SHA256
nn Octets - Ciphertext (AES-256 in CBC mode; 2^64 octets max)
 1 Octet  - Ciphertext size modulo 16 in least significant bit positions
32 Octets - HMAC-SHA256

The footprint of the stream is at least 134 octets.

Version 0 is no longer written by AES Crypt, though it does have the ability to read streams in this format. The format for version 0 is shown below.

V0 Stream Format

 3 Octets - "AES"
 1 Octet  - Version (0x00)
 1 Octet  - Ciphertext size modulo 16 in least significant bit positions
16 Octets - Initialization Vector (IV)
nn Octets - Ciphertext (AES-256 in CBC mode; 2^64 octets max)
32 Octets - HMAC-SHA256

The footprint of the stream is at least 53 octets.