Output Block Size with AES

I am trying to use the Racket Crypto library for encrypt of 16 bytes with a 16 byte key. I expect to have a 16 byte output block, but I get a 32 byte. A 15-byte input block provides 16-bit output.

#lang racket (require (planet vyzo/crypto)) (bytes-length (encrypt cipher:aes-128-ecb (string->bytes/latin-1 "0123456789ABCDEF") ; 16-byte key (make-bytes 16) ; IV (string->bytes/latin-1 "0123456789ABCDEF"))) ; 16-byte data ; -> 32 (bytes-length (encrypt cipher:aes-128-ecb (string->bytes/latin-1 "0123456789ABCDEF") ; 16-byte key (make-bytes 16) (string->bytes/latin-1 "0123456789ABCDE"))) ; 15-byte data ; -> 16 

Am I mistaken somewhere? Is it related to filling in?

Note. I know about problems with ECB mode. My goal is to implement CBC mode.

+4
source share
2 answers

You are right, this is due to filling. Unfortunately, the vyzo / crypto lib API does not allow you to easily disable padding (and this is correct, see the Caution below).

How to disable add-on

However, based on this Thread in the Racket user mailing list, you can disable the add-on as follows:

 #lang racket (require (planet vyzo/crypto) (planet vyzo/crypto/util)) (define (cipher-encrypt-unpadded type key iv) (lambda (ptext) (let ((octx (cipher-encrypt type key iv #:padding #f))) (bytes-append (cipher-update! octx ptext) (cipher-final! octx))))) (define (cipher-decrypt-unpadded type key iv) (lambda (ctext) (let ((ictx (cipher-decrypt type key iv #:padding #f))) (bytes-append (cipher-update! ictx ctext) (cipher-final! ictx))))) ; bytes-> bytes ; convenience function for encryption (define enc-aes-128-ecb-unpadded (cipher-encrypt-unpadded cipher:aes-128-ecb (string->bytes/latin-1 "0123456789ABCDEF"); 16-byte key (make-bytes 16))) ; bytes -> bytes ; convenience function for decryption (define dec-aes-128-ecb-unpadded (cipher-decrypt-unpadded cipher:aes-128-ecb (string->bytes/latin-1 "0123456789ABCDEF"); 16-byte key (make-bytes 16))) (define message (string->bytes/latin-1 "0123456789ABCDEF")) ; 16-byte data (bytes-length (enc-aes-128-ecb-unpadded message)) ; -> 16 (dec-aes-128-ecb-unpadded (enc-aes-128-ecb-unpadded message)) ; -> #"0123456789ABCDEF" 

This worked well on my machine. In addition, switching to CBC mode is trivial.

Caveat

When you turn off padding, your posts should be a multiple of the block size. For AES128, which is an exact multiple of 16 bytes. Otherwise, the function will explode in your face:

 (enc-aes-128-ecb-unpadded (string->bytes/latin-1 "too short!")) EVP_CipherFinal_ex: libcrypto error: data not multiple of block length [digital envelope routines:EVP_EncryptFinal_ex:101183626] 
+3
source

It looks like all the input is padded with the border of the next block. This means that the 16-byte input will be complemented by the next 32-byte boundary. If all your data is accurate block sizes, you can disable indentation. If the entry can end in the middle of the block, you will have to leave the add-on turned on.

If you intend to use CBC mode, you may also need to consider authentication. If you need it, then HMAC is probably the easiest way to start with.

+1
source

Source: https://habr.com/ru/post/1483933/


All Articles