Файл приватного ключа, который генерирует openssl, содержит также открытый ключ.
К счастью, проблема легко разрешилась. Если генерировать ключ с параметром -no_public, то openssl делает файл без публичного ключа. При генерации из этого файла самоподписанного сертификата публичный ключ стандартным образом рассчитывается из заданного приватного. Так что подставить в файл приватного ключа вместо самого ключа некий хеш - технически простая задача, сертификаты получаются вполне корректные.
Я сейчас столкнулся с другой проблемой: русские буквы в имени владельца сертификата заменяются на коды, начинающиеся со слеша. Не смог побороть это ни указанием utf8=yes в конфигурационном файле openssl, ни указанием при генерации сертификата параметра -nameopt sep_comma_plus,utf8. Кодировка командной строки тоже utf8. Непонятно, что ещё можно сделать.