AES is a block cipher and needs a proper mode of operation like CBC, CTR, and so on.
While the streaming modes like CFB, OFB, and CTR don't require padding the CBC and ECB mode of operations requires padding.
In CBC mode the usual padding is the PKCS#7 padding. For CBC encryption the message is divided into 128-bit blocks and the padding is applied into the last block. There can be two cases;
The message has missed some bytes; in this case, let $n$ is the number of missing bytes, then the number $n$ is added $n$ times as a byte.
[Message Bytes ][01] // 1 Byte is missing
[Message Bytes ][0202] // 2 Bytes are missing
[Message Bytes][030303] // 3 Bytes are missing
....
[MB][0F0F0F...0F0F0F0F] // 15 Bytes are missing
The message is multiple of 16-byte, this means that the last block is full. In this case, to distinguish this case from the first case we add a new block full of 10
s. Therefore, we can have the reverse of the padding. One can see the reason as to what if the last block has 01
as the last byte. Is it padding or not? So adding 01
removes this ambiguity.
The above can explain why a message becomes a multiple of 16 bytes after proper CBC encryption.
In the case of the question, 15 bytes can become 16 bytes by adding 01
as the last byte. What about the remaining 16-bytes?
CBC mode of operation needs a 16-byte random and unpredictable Initialization Vector (IV) to achieve Ind-CPA security.
IV is one of the requirements for the decryption of the first block other than the key ( key, IV, and $C_0$ is required);
$$P_0 = \operatorname{AES-DEC}(key,C_0) \oplus IV$$
Therefore the IV must be added/transferred, too. In the usual practice, the IV is appended to ciphertext.
What if IV is not stored/transferred? Well, you will lose only the first block of the message, the rest can be decrypted properly since;
$$P_i = \operatorname{AES-DEC}(key,C_i) \oplus C_{i-1}, \quad i \geq 1$$
CMS
The CMS requires
The AlgorithmIdentifier parameters field MUST be present, and the
parameters field MUST contain a AES-IV:
AES-IV ::= OCTET STRING (SIZE(16))
The IV is stored in the AlgorithmIdentifier
field, not in the encryptedContent
As Dave wroted it is -binary
issue.
OpenSSL option -k
The IV and Key are derived from the key derivation method by using the user's password and the 8-byte random salt. The IV is not prepended.
OpenSSL first outputs the magic word Salted__
then 8-byte salt then the ciphertext into the file. Now the output size is your magic size + salt size + ciphertext-size