Reputation: 91
I am trying to use CryptoJS to encrypt a string of 32 characters:
var string = '12345678901234567890123456789012'.
I am using the key of 32 characters for AES256:
var key = '12345678901234567890123456789012':
var _key = CryptoJS.enc.Utf8.parse(key);
var encryptedECB = CryptoJS.AES.encrypt(string.trim(), _key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}).toString();
I am expecting the encryptedECB string length to be 44 characters. Instead it is 64 characters. What I am doing wrong?
Upvotes: 3
Views: 3346
Reputation: 49276
As already explained in my comment, the ciphertext is encrypted correctly: The posted plaintext is 32 bytes long, which is an integer multiple of the blocksize (16 bytes for AES). The PKCS7 padding used in this case pads with a whole block (16 bytes) to 48 bytes, which results in a ciphertext of the same length. CryptoJS.AES.encrypt
returns a CipherParams
object that encapsulates various parameters including the ciphertext. By default the toString()
method returns the ciphertext as a Base64 encoded string, which gives a length of 64 bytes (4*ceil(n/3)
, n=48
).
Block ciphers like AES in ECB mode require plaintexts whose length is an integer multiple of the blocksize. Otherwise a padding such as PKCS7 must be used. However, since the length of the posted plaintext with 32 bytes already corresponds to an integer multiple of the block size (32 = 2 * 16 bytes), the padding can also be omitted (padding: CryptoJS.pad.NoPadding
), which saves a whole block (16 bytes). So the ciphertext has the same length as the plaintext (32 bytes) and becomes Base64 encoded 44 bytes (4*ceil(n/3)
, n=32
), which is probably the result you expect:
var string = '12345678901234567890123456789012';
var key = '12345678901234567890123456789012';
var _key = CryptoJS.enc.Utf8.parse(key);
var encryptedECB = CryptoJS.AES.encrypt(string.trim(), _key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
}).toString();
console.log(encryptedECB);
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
Note, however, that padding is generally necessary for block ciphers and can only be omitted if the length of the plaintext is an integer multiple of the blocksize. For completeness it should be mentioned that besides Base64 with an efficiency of 75% there are other binary-to-text encodings. There are also other paddings (s. here), but PKCS7 is reliable (in contrast to e.g. Zero padding). Regarding security: ECB is an insecure mode.
Upvotes: 6