Customize option whitespace-display-mappings. That's what it's for.
M-x customize-option whitespace-display-mappings RET
The doc gives you details (below), but just look at the Customize buffer and things will be even clearer. You can use C-u C-x = with the cursor before a given character, to see its Unicode code point.
C-h v whitespace-display-mappings ...
The docs of standard-display-table refer to buffer-display-table which mentions that you can create display tables with make-display-table if necessary.
This means the following should work:
(let ((display-table (or standard-display-table (make-display-table))))
(set-display-table-slot display-table 'vertical-border (make-glyph-code ?┃))
Here is a very ugly solution. First, define a function to find hard newlines such that it can be used by font-lock-mode:
(defun whitespace-find-hard-newlines (end)
(search-forward "\n" end t)
(while (and (not (memq 'hard (text-properties-at (match-beginning 0))))
(search-forward "\n" end t)))
(memq 'hard (text-properties-at (match-beginning 0)))...