I'm implementing dh-ietf1024-sha256-aes128-cbc-pkcs7 in golang and according to documentation I've managed to create the 128-bit key appropriate for AES (from my 1024-bit shared-key computed from my private key and clients public key).

API function input is just algorithm name and client public key. And for using AES I need to use the same IV that my client uses (am I correct?).

The question is where this IV comes from?

  • Are you doing this as an educational experience or for a production system?
    – user163495
    Commented Apr 20, 2021 at 19:37
  • 2
    CBC mode requires an unpredictable IV. Create from /dev/urandom. Is there a specific reason that you use CBC mode instead of authenticated modes like AES-GCM and ChaCha20-Poly1305?
    – kelalaka
    Commented Apr 20, 2021 at 19:39
  • @MechMK1: As an open source project for Secret Service as a systemd service on KDE. Because I'm tired of opening KeePassXC every-time I need to use vscode, skype...
    – Xaqron
    Commented Apr 20, 2021 at 19:40
  • @kelalaka: Because API says so.
    – Xaqron
    Commented Apr 20, 2021 at 19:44
  • 1
    1024-bit DH is considered too weak for secure use. It provides about an 80-bit security level, which is far below the 128-bit security level considered acceptable.
    – bk2204
    Commented Apr 20, 2021 at 22:39

3 Answers 3

  • DH key agreement [rfc2631] is used to create a secret key using 1024 bit parameters of the standard IETF 'Second Oakley Group' [rfc2409].
  • The secret key is then digested into a 128-bit key appropriate for AES.
  • This is done using HKDF [rfc5869] with NULL salt and empty info, using the SHA-2 256 hash algorithm [fips-180-3.2008]. -The secrets are encrypted using AES [fips-197.2001] in cipher block chaining mode with pkcs7 style padding [rfc2315].

Short answer

  1. Start Diffie-Hellman key exchange (DJKE) to agree on a key K
  2. Both sides uses HKDF to derive the symmetric key k of the required side.
  3. Generate random IV by using /dev/urandom or better methods.
  4. Encrypt message c = AES256-CBC( k, PKCS#7padding(m) )
  5. Send |IV and |c to the other side.
  6. The other gets the IV and c, and
  7. Decrypts m = AES256(k,c) and checks the PKCS#7 padding.

The usual practice is prepending the IV to ciphertext like a bundle |IV|ciphertext| and send it to the receiver. Encoding base64 of the bundle is advised.

Long answer


While using the CBC mode with AES you must consider this;

Your obligations:

  1. You must choose a 256-bit secret key k uniformly at random. You must keep it secret all the time.

    In your case DH generates this.

  2. Make sure that your messages are always an integer multiple of 128 bits long. To satisfy this you can use PKCS#7 padding and be aware of padding oracle attacks.

  3. If a key k is reused for multiple messages, you must choose a 128-bit initialization vector that is (a) unique and (b) unpredictable in advance. 4 The total data length must not be past 260 bytes of data using the same key k.

  4. You must not send more than 248 messages using the same key k.

In return, AES-CBC guarantees against an adversary who can adaptively influence plaintexts sent by Alice and Bob.

CBC mode has Ind-CPA security means the adversary cannot distinguish the ciphertexts of two equal-length messages even they choose the messages. Therefore they cannot read messages chosen by Alice or Bob.

If you violate the unique in your obligations, then the adversary can detect that a message is sent again. The random IV provides probabilistic encryption to mitigate this.

If you violate any other, the security properties provided by AES-CBC will be lost.


The 1024 bit DHKE is not considered today's standards. For the equivalent of 128-bit symmetric security, you should use at least 2048-bit by ANSSI's approximation. See on keylength.com

DHKE exchange provides forward secrecy, in order to achieve that both sides must delete the keys upon decryption. If the keys are kept keys at least one side and that side is attacked then the attacker can read the previously recorded sessions. This validates the forward secrecy.


HKDF has these parameters

`k = HKDF( salt, IKM, info, L)

  • where IKM is the input key material that comes from the output of the DHKE in your case.
  • info can be used for a generation multiple keys from a single IKM.

In your case salt is NULL and info set to empty string.


The question is where this IV comes from?

If you are asking about decryption of an already encrypted file, then the IV is typically stored along with the encrypted data file and you should read the IV block in along with the file blocks as input to the decryption.

If you are asking about encryption of a plain text file, then you should generate the IV randomly using a good (cryptographically strong) random number generator and store it alongside the encrypted file.

Do not use a global IV. This is a common error. Every file that gets encrypted should get its own random IV.

BTW, this means that the CBC encrypted data is always more than one block (cipher block size) larger than the plain text. (Even without the IV appended, the encrypted data is padded up to the next integer multiple of the block size. And then the IV is appended, which is another block in size.)

And for using AES I need to use the same IV that my client uses (am I correct?).

Yes, you need the same IV or the decryption will not work. And, as mentioned above, that IV should be generated randomly for each item that is encrypted.


After reading spec again it turns out what I described in question is just about key exchange and creating right key for AES. And where comes from IV?

each party uses random bytes to create its own IV, encrypts secret then sends IV and secret with each message (there is a struct for it) to other peer.

So there is no single IV agreed on once at initial key exchange, IVs are per message.

Sorry this question was more about mentioned API rather than cryptography. Hope this answer helps others trying to implement dh-ietf1024-sha256-aes128-cbc-pkcs7. From here it is easy to write encryption/decryption functions according to spec since I have the symmetric key and each message contains its own IV.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .