Receiving SNMPv3 traps using snmp4j in Java

Hi
I am using snmp4j version 2.8.0 with Java version 8. I have followed the online examples in java that implements CommandResponder to receive SNMPv3 traps. I have also followed the suggestion from the topic SNMPV3 Trap listner to use Snmp.discoverAuthorititiveEngineId to discover the engine ID of a SNMP entity.
I have multiple SNMP entities that I want to receive SNMP v3 traps from. So I added user for each snmp entity as below.
snmp.getUSM().addUser(new OctetString(agentSecName), engineID, user);

I receive snmpv3 traps from multiple snmp entities. But the problem that I am having is one in every few snmpv3 traps fail with different error each time. Some of the errors are as below. I believe the errors are based on the message received.
Error 1: java.io.IOException: Invalid sequence encoding: 55
Error 2: java.io.IOException: Data length > 4 bytes are not supported!
Error 3: java.io.IOException: Invalid sequence encoding: 0
How do I address this issue?

Thanks in advance for your help.

You need to be careful with engine IDs - it is a really critical part of SNMPv3.

The trap sender is the authoritative SNMP entity, thus the receiver does not need to discover the trap sender’s engine ID. The receiver simply receives the trap and that trap (precisely: notification) already includes the engine ID.

The USM authentication and privacy keys however, need to be localised with the sender’s engine ID. Thus, you need to know the engine ID of the sender before creating the corresponding SNMPv3 USM credentials. There are basically two options to solve this:

  1. Discover the engine ID of all senders and then create the localised USM keys.
  2. Do not discover any engine ID but add a non-localised USM user (= a user without engine ID provided but with passphrase) to the SNMP4J USM. SNMP4J will then create the necessary localised users on-the-fly when a message is received.

The errors you see in the log, are likely caused by trying to decrypt the received PDU with the wrong key (the key is wrong, because the engine ID is wrong).

Hope this helps.

Thank you for the quick response.
In that case wouldn’t it fail every time?
I had implemented using option 1 (

) and I do get SNMPv3 traps sometimes.
I will now try option2 that you suggested.

Thanks

Yes you are right: If the engine ID used for the key localisation is wrong, the received notification cannot be encrypted (always).

So, rethinking this case, I suggest simply updating to SNMP4J 2.8.6 which fixes an issue with lengthy sequence encodings (was fixed in 2.8.4 on 2020-05-19T22:00:00Z, see the CHANGE history at: https://www.snmp4j.org/CHANGES-2.x.txt

I tried with version 2.8.6 and still see the issue. This time I also tried the receiver example from here
https://cornercase.info/java-snmp-trap-receiver-and-sender/
The engineId was used only to create the USM as below.
USM usm = new USM(
SecurityProtocols.getInstance().addDefaultProtocols(),
new OctetString(MPv3.createLocalEngineID()), 0);

I did not specify the engineId when creating the user as below.
snmp.getUSM().addUser(new OctetString(username),
new UsmUser(new OctetString(username),AuthMD5.ID, new OctetString(
authpassphrase), PrivAES128.ID, new OctetString(privacypassphrase)));
Am I missing something?
Thanks!

Then it looks fine so far. Maybe it is a key extension issue (MD5 has a too short key for AES128 which needs to be extended)? Or some other misconfiguration like wrong password, protocol mismatch, etc.