Joe Root made a career-best 125 as England posted a competitive 318 for eight after winning the toss.
England captain Eoin Morgan admitted: "I certainly thought at half-time that we would win the game."
But De Kock and Amla made the target look easy as they put on 239 for the first wicket.
De Kock in particular was in majestic form as he made 135 off 117 balls, with 16 fours and four sixes before he hit leg-spinner Adil Rashid, England's best bowler, to Root at mid-off.
Also Read
South Africa won with 22 balls to spare. England lead the five-match series 2-1, with matches in Johannesburg and Cape Town to come.
South African captain AB de Villiers praised an "unbelievable" effort by De Kock and Amla but said he was always confident South Africa could win.
"We were up for it today," said De Villiers.
"There was urgency in the field and a bit of hunger. I would have bowled first. Quite a few of us come from here and we know it is difficult to defend here at night."
He shared a second wicket partnership of 125 with Alex Hales, who made 65 off 73 balls, and 82 for the fifth wicket with Ben Stokes, who slammed 53 off 37 balls.
A mix-up with Stokes caused Root to be run out and South Africa came back into the match by taking another three wickets, including that of Stokes, in quick succession.
David Willey and Adil Rashid scored 27 runs off the last 15 balls of the innings as England finished strongly
De Kock, at the age of 23, became the youngest player to score ten one-day international centuries, reaching the mark off 96 balls, while Amla scored his 22nd one-day hundred off 109 deliveries.
Morgan paid tribute to "an incredible opening partnership" by the South African pair but added: "We didn't string together enough balls in the right areas to put pressure on them.