The Russia international sealed three points for Luciano Spalletti's men as Hulk made his return to the Portuguese club where he made his name.
The forward's 85th-minute header was enough for the visitors, who labored to take advantage of Porto playing much of the game a man down. The hosts found themselves reduced to 10 men after six minutes of the Group G clash as Mexico international Hector Herrera saw yellow twice in the space of a minute.
Zenit failed to make the extra man count for much of the game, though, and, aside from a pair of Hulk chances in the second half, rarely threatened home goalkeeper Helton.
Porto more than held its own after the early setback and twice hit the woodwork in a tie it arguably deserved to win. But the deadlock was finally broken five minutes from time as Kerzhakov sealed the three points for Luciano Spalletti's men.
The victory lifts Zenit to within five points of Atletico Madrid for second place in the group, leapfrogging Porto in the process.
The game got off to a nightmare start for the hosts at a far-from-full Estadio do Dragao, with Herrera sent off after receiving two yellow cards within six minutes.
His first for a reckless challenge on former Porto striker Hulk was immediately followed by a foolish second for encroachment on the resulting free kick, meaning the Mexican set the new mark for the fastest dismissal for a double booking in the competition’s history.
Despite being a man down, it was Porto that had the better of the chances early on, with Lucho Gonzalez rattling the angle between post and crossbar from 20 yards after 20 minutes and a stretching Lica unable to take advantage of the rebound.
Zenit struggled to settle and was reduced to speculative efforts from distance, with its best chance of the half being a curling Roman Shirokov effort from the edge of the area that drifted just beyond the far post.
With the match crying out for an injection of energy after the break, Porto substitute Silvestre Varela provided something of a spark as he cut in from the right, skipping past two defenders in the process, before skewing his strike wide of the left post.
Moments later at the other end, Hulk robbed Nicolas Otamendi of possession just outside the penalty area, but he was denied by the outstretched foot of Helton after finding himself through 1-on-1 with the goalkeeper.
And Helton had to be alert again in the 65th minute, as Hulk powered a thunderbolt of a free kick in his direction from 25 yards. It was too hot to handle, but the Brazilian punched clear to deny his former teammate.
Varela, who looked lively after replacing Lica, went close for the hosts once again with just more than 10 minutes left to play. He turned on the edge of the area and fired an effort against the Zenit crossbar, with goalkeeper Yuri Lodygin beaten.
Zenit finally snatched the points, though, as Kerzhakov rose highest to head home from an excellent cross from Hulk on the right wing and make Porto pay for Herrera's early mistakes.