This array is then subjected to JSON.stringify(json) and encrypted with the AES-128-ECB algorithm.
That is: what's shown it's stripped from whitespace except in strings, leading to ≈274 characters encoded per ASCII into as many bytes. This then is encrypted with the AES-128-ECB algorithm and some padding mode into 18 × 16 = 288 bytes, then converted to text per Base64 encoding to 384 characters.
Does this knowledge make hacking easier in any way?
Depends on definition of hacking.
It does not help towards recovering the AES-128 key, which would effortlessly allow decryption of everything.
However, the fact that AES-ECB is used does allow some level of attack on confidentiality. Like depending on the length of the fields, there is a possibility that an adversary can tell with certainty that some dates are identical (if they are), or detect that some consecutive bytes appear in two "data" fields.
For an illustration, AES-ECB encrypt then Base64 these 65 characters, e.g. with this.
the old password has expired, we will thus burn the old password.
The output will be on the tune of the following, where the first 21 characters repeat 43 characters later. An observer can ascertain that the first 16 bytes of the plaintext repeat 32 bytes later, which is something about the plaintext, when the theoretical goal of encryption is to hide everything about the plaintext (except it's length).
S9cZFSSXRfeVgPkFLZCryQgR7UB5Ye6Jae/EAVhKQrsunpngokC4hKQN7+D74ZM9S9cZFSSXRfeVgPkFLZCryUegB+/d9azXomfSVIMMOtI=
More importantly, AES-ECB encryption allows shuffling 16-byte segments of the deciphered plaintext simply by shuffling the corresponding ciphertext segments, including from earlier ciphertexts. This can be a vector of attack, depending heavily on context.
For example, if the message conveys a new password, it's realistic that adversaries could modify the ciphertext so that the decryption results in a message that conveys a different password that they know, because it's a known field in the same message. That's all without knowing the key, even if the key is used for that single message.
To avoid such attack on integrity, if we stick with symmetric cryptography, a recommendable thing to do is to use an authenticated encryption mode like AES-GCM.
I can't memorize IV, but then I don't know where and how to store it.
Storing the Initialization Vector and Authentication Tag is easy: basically they are in or along the ciphertext. It can be internally handled by the encryption and decryption APIs, or added on top if not. Typically the IV is generated randomly on encryption and put at start of ciphertext, the AT is generated as a byproduct of encryption and put at end of ciphertext. The decryption extracts the IV, use it for decryption, extract the AT, check it (if invalid, it's critical that the deciphered plaintext is discarded).
We can use a RNG to generate the IV. For AES-GCM, the requirement is that it's a (e.g. 12-byte) value unique per encryption session of at most 64GiB. That's something a TRNG or proper /dev/urandom
does (but a PRG as defined in cryptography does not). If there was any difficulty generating a (most likely) unique IV for each encryption, we can use AES-GCM-SIV.
The Base64 encoding of the ciphertext produced by encryption and it's decoding before decryption can apply to IV and AT as well in the same operation.