Ваш подход может применяться только к RSA и только в том случае, если вы используете ключи, сгенерированные в соответствии с версией PKCS#11 >= 2.40. Стандарт PKCS # 11 определяет (раздел 2.1.3 «Объекты закрытого ключа RSA» в базовой спецификации 3.0): «Начиная с версии 2.40, токены ДОЛЖНЫ также хранить CKA_PUBLIC_EXPONENT».
Таким образом, вы можете получить атрибуты модуля и публичной экспоненты (C_GetAttributeValue) и создать из них объект открытого ключа, используя C_CreateObject. Но, как указал DannyNiu, это, безусловно, стоит производительности.
В зависимости от токена вы можете использовать объект закрытого ключа вместо открытого ключа для таких операций, как C_Encrypt* или C_Verify*, поскольку токен будет использовать только общедоступные атрибуты.
Для других асимметричных ключей, например. Ключи EC, в стандарте PKCS#11 нет определения, аналогичного определению для RSA. Таким образом, никакие общедоступные части не будут сохранены. Это будет зависеть от токена, вычисляется ли открытый ключ на лету (подтверждая комментарий Конрадо). Это, безусловно, имеет еще большее влияние на производительность. Если токен не делает этого автоматически, невозможно инициировать вычисление открытого ключа из закрытого ключа из PKCS#11.И, конечно же, вы никогда не должны делать это извне — зачем вам вообще использовать токен (HSM), если вы используете закрытый ключ снаружи?
Наконец, если вы используете стандартные приложения, ваш подход, скорее всего, потерпит неудачу, поскольку приложения часто добавляют CKA_CLASS=CKO_PUBLIC_KEY в шаблон поиска, когда ищут открытый ключ, который хотят использовать.