The Swede first dispatched the rebound from his saved penalty, then tapped his second into an empty net just three minutes later. Romelu Lukaku pulled one back 29 minutes in, but that was all Inter could muster.
As a result, Milan won their first derby in nine matches, since January 2016, and also ended Inter’s four-match winning streak in the fixture.
Both teams were quick out the blocks, and it was Milan who looked the more likely before they were awarded a penalty.
Aleksandar Kolarov tackled Ibrahimovic from behind and clipped the Swede’s heels resulting in referee Maurizio Mariani pointing to the spot.
Ibrahimovic was denied by Samir Handanovic, but he put the ball in the back of the net at the second attempt.
Moments later, Ibrahimovic doubled the lead for Milan. Rafael Leao whipped a brilliant ball into the No.11 who was unmarked at the back post and he side-footed into the net.
Half an hour in Inter got themselves back into the game when Ivan Perisic made it to the goal line and his low cross was missed by Gianluigi Donnarumma before rolling into the path of Lukaku, who made no mistake from close range.
The score could have been level when Achraf Hakimi delivered a looping ball to the back post for Lautaro, but his header was cleared off the line by Simon Kjaer.
Inter continued to dominate the second half and Arturo Vidal played a brilliant ball over the defence into the path of Hakimi, but the former Real Madrid man out his diving header wide of the far post.
Made Krunic had a brilliant opportunity to kill the game off as he was put through on goal by Samu Castillejo, but he could only smash his effort well over the crossbar.
The referee then awarded a penalty after Lukaku was brought down in the box by Donnarumma, and after consultation with VAR, the decision was overturned after an offside earlier in the move.
Try as they might, Inter were unable to break a resolute Milan defence for a second time.