About AES-256-CBC and keys

Hi TMS Crypto people. We are suscribers using your whole TMS pack.

We have this littel question: we have to make a development with these specifications. Below is our attempt.

-API-key encryption:

* The AES-256-CBC algorithm must be used.
* A specific key provided by us that you will use as a 
password encryption.
* You also need a value called IV (Initialization Vector), 
which must be generated randomly for each request.

- Data to send in the request headers:

* x-api-key: The result of encrypting the api-key.
* x-iv: The Initialization Vector used for encryption, 
converted to hexadecimal format.

All requests will ask you to send those two fields in the 
headers, the api-key of the client has to travel encrypted, 
we are going to decrypt it to be able to use it

The key you have to use to encrypt it is this 
“p@55w0rdu1tr@s3cr3t0”

The x-api-key is 
“317301cc6cbbc-87e144ce-9ed2-a397192j9900”

Ok: What we did

var
 aes: TAESEncryption;
 cipher: string;

begin
 aes:= TAESEncryption.Create;
 aes.AType:= atCBC;
 aes.KeyLength:= kl256;
 aes.Unicode := yesUni;

 aes.Key:= ‘p@55w0rdu1tr@s3cr3t0’;  //here the key…

 aes.OutputFormat:=hexa;
 aes.PaddingMode:= TpaddingMode.PKCS7;
 aes.IVMode:= TIVMode.rand;  //test says so

 cipher:= aes.Encrypt(‘317301cc6cbbc-87e144ce-9ed2-a397192j9900’);
 aes.Free;
end;

The problem is this error message

class ECryptoPack with message ‘Keylength incorrect, must be 32’.

The client gave us that key, but it is not 32 characters long.

We don’t know about the subject, what can we do?

Regards
Pablo Romero
Flexxus SA

Hi, the password has indeed 20 bytes only, which raises the exception.
You then have 3 solutions:

  • hash the password with SHA256 and use the result as the key
  • derive a key with PBKDF2 (or Argon2) and the password
  • pad the password with 12 extra bytes

In all cases, the specification is incomplete and you need to check with your customer.

1 Like

I've recently started using TMS Crypto (been using DCPCrypt for many years), and I encountered the same error message, telling me that the key is not x-number of characters long. If the key size is 128 bits, the expected key length is 16 bytes. With a 256-bit key, the key length should be 32 bytes, etc.

So why are we seeing these error messages if the user enters a key length that's not precisely 16 bytes or 32 bytes? Shouldn't there be padding applied automatically within the library?

If the padding is not applied automatically, then what is the point of this line:
aes.PaddingMode := TpaddingMode.PKCS7;

Hello,

Padding is only for messages, not for keys (message size needs to be a multiple of 16).

You have several options:

  • use a key with the correct size (16, 24 or 32 bytes - same for Speck)
  • padd the key using the same principle as PKCS#7 (say, if 4 bytes are missing, add 4 bytes containing 4, if 5 are missing, add 5 bytes with 5, etc.)
  • hash the existing key with SHA2 (256) for instance
  • derive a key with PBKDF2 or Argon2 (like in key derivation for passwords)

Whatever you choose, use the same method to derive the key before decrypting.

I am not familiar with DCPCrypt but it must use one of these methods otherwise it is not compatible with anything else using the AES (and not AES compliant anyway).

Regards,
bernard

Just checked the DCPCrypt wiki:

Bugs

If you are using DCPrijndael, be advised that key sizes that are not in the AES standard are known to produce key schedules that are not inter-operable with other Rijndael implementations. Few implementations provide the non-standard key (or block) sizes

"Few implementations provide the non-standard key (or block) sizes"
Actually, none to my knowledge, otherwise you are not AES compliant.

Thanks for the quick reply.

DCPCrypt didn't have built-in padding (it had to be done manually), so I'm very familiar with that process.

But when I saw the line " aes.PaddingMode := TpaddingMode.PKCS7;" in the TMSCrypto demo, I assumed that padding was built into the library for messages and keys.

Just out of curiosity, is there a reason that key padding cannot be included in the library code so that it's done automatically?

No technical reason, just not part of any standard.