Расшифровка HSM + цепочка шифрования

Мое приложение действует как коммутатор для передачи очень конфиденциальных сообщений между двумя сторонами, и я пытаюсь понять, как я могу это сделать, не «глядя» на сообщение, которое они пытаются отправить.

У меня есть HSM, и я создал пару ключей для отправителя - они собираются зашифровать сообщение своим открытым ключом, который я им дал, и я могу расшифровать сообщение, используя закрытый ключ, который у меня есть в HSM.

Затем я собираюсь передать это сообщение, зашифруя его открытым ключом конечного получателя, который у меня есть.

Есть ли способ связать эти две операции внутри HSM, не имея расшифрованного сообщения где-либо рядом с моей памятью приложения? Я бы хотел, чтобы содержимое открытого текста никогда не выходило за пределы HSM.

Я знаю, что у некоторых HSM есть машинная функция CodeSafe / SEE, которая позволяет мне писать встроенный системный код и запускать его внутри HSM, прежде чем я перейду к этому, я хотел бы посмотреть, есть ли способ использовать общие API-интерфейсы PKCS / JCE / CNG сделать это безопасно.


person Sudhir Jonathan    schedule 30.07.2019    source источник
comment
Думаю, вы можете сделать это с помощью переноса ключей. Используйте закрытый ключ отправителя, чтобы развернуть симметричный ключ для каждого сообщения: вы получаете дескриптор симметричного ключа, а не сам симметричный, а затем вы обертываете его с открытым ключом следующего получателя.   -  person Gilles 'SO- stop being evil'    schedule 30.07.2019
comment
Некоторые HSM предоставляют функцию перевода данных, где вы можете переводить (расшифровывать с помощью key1 и шифровать с помощью key2) данные из входящего ключа данных key1 в исходящий ключ key2, операция выполняется внутри HSM, поэтому вы действительно не касаетесь чистых данных, но эти команды выглядят чтобы быть только с симметричными ключами, в этом случае вам потребуется устройство механизма обмена ключами для симметричного ключа данных   -  person Pras    schedule 30.07.2019
comment
... Я создал пару ключей для отправителя ... Что ж, игра окончена, вы можете читать все их сообщения.   -  person President James K. Polk    schedule 30.07.2019
comment
AFAIK ни один из распространенных криптографических API не поддерживает безопасное повторное шифрование. Кстати, я ответил на аналогичный вопрос для интерфейса PKCS # 11 несколько месяцев назад.   -  person jariq    schedule 30.07.2019
comment
@Pras, не могли бы вы рассказать подробнее о поставщике / модели HSM, которая обеспечивает функцию перевода данных?   -  person jariq    schedule 30.07.2019
comment
Модели @jariq Atalla Ax160 поддерживают перевод данных   -  person Pras    schedule 31.07.2019
comment
@Pras Спасибо, проверю эти HSM.   -  person Sudhir Jonathan    schedule 31.07.2019
comment
@Giles рассмотрит это. В данном случае полезная нагрузка действительно является симметричным ключом, но у меня нет информации о его формате или генерации. Я не знаю, распознает ли HSM это как крипто-материал и выдаст мне непрозрачный обработчик.   -  person Sudhir Jonathan    schedule 31.07.2019
comment
@JamesKPolk: да, но отправитель платит мне много денег за безопасную передачу сообщения на десятки тысяч устройств, открытыми ключами которых я управляю. Они доверяют мне все делать правильно, поэтому они зашифровали его с помощью открытого ключа, который я им дал. Я пытаюсь убедиться, что полезная нагрузка доставляется во все места назначения, и я, моя команда, сотрудники или хакеры никогда ее не увидят.   -  person Sudhir Jonathan    schedule 31.07.2019
comment
Многие HSM имеют методы получения ключей с использованием XOR. Для XOR вы можете расшифровать / зашифровать в любом порядке. Что касается типа ключа, просто скажите, что это ключ HMAC, ключ HMAC может иметь любой размер (хотя я не удивлюсь, если HSM по-прежнему будет ограничивать вас определенными размерами).   -  person Maarten Bodewes    schedule 31.07.2019
comment
Как писал Жиль выше, простое развертывание в общий секретный ключ, предназначенный только для сеанса, который затем можно обернуть для всех получателей и удалить, должно работать ... И какой именно HSM вы используете? Некоторые конкретные настройки (например, политика, шаблон развертывания) могут (и должны использоваться) в дальнейшем использоваться, чтобы ужесточить то, что разрешено делать с сохраненным / импортированным ключевым материалом.   -  person vlp    schedule 01.08.2019
comment
Серия Thales nCipher, точную модель не знаю. Думаю, мы просто перейдем к CodeSafe SEE и напишем C / C ++ для работы внутри HSM. В любом случае нужно сделать и другие проверки.   -  person Sudhir Jonathan    schedule 02.08.2019


Ответы (1)


Если все, что вам нужно, это повторно зашифровать один и тот же секрет под другим ключом, вы можете использовать C_Unwrap для создания временного объекта HSM со значением переведенного секрета, а затем использовать C_Wrap для шифрования значения этого временного объекта HSM для всех получателей. .

Таким образом, секрет никогда не покинет HSM.

Что-то вроде этого (подтверждено, что работает над SafeNet Luna 7 с RSA-OAEP):

// Your private key for 'decrypting' secret. Must have key unwrapping allowed
CK_OBJECT_HANDLE hsmPrivateKey = ... ;

// Encrypted secret
byte[] wrappedKey = ... ; // 

// Template for temporal generic secret key with value of the secret
CK_ATTRIBUTE[] tempTemplate = new CK_ATTRIBUTE[] {
        new CK_ATTRIBUTE(CKA.CLASS, CKO.SECRET_KEY),
        new CK_ATTRIBUTE(CKA.KEY_TYPE, CKK.GENERIC_SECRET),
        new CK_ATTRIBUTE(CKA.TOKEN, false),
        new CK_ATTRIBUTE(CKA.PRIVATE, true),
        new CK_ATTRIBUTE(CKA.EXTRACTABLE, true),
        new CK_ATTRIBUTE(CKA.SENSITIVE, true),
        new CK_ATTRIBUTE(CKA.ENCRYPT, false),
        new CK_ATTRIBUTE(CKA.DECRYPT, false),
        new CK_ATTRIBUTE(CKA.WRAP, false),
        new CK_ATTRIBUTE(CKA.UNWRAP, false),
        new CK_ATTRIBUTE(CKA.SIGN, false),
        new CK_ATTRIBUTE(CKA.VERIFY, false),
        new CK_ATTRIBUTE(CKA.DERIVE, false)
};

// Unwrapping/decryption mechanism
CK_MECHANISM mechanism = ... ;

// Handle for temporal generic secret key with value of the secret
CK_OBJECT_HANDLE temporalValueHandle = new CK_OBJECT_HANDLE();

// Unwrap/decrypt the secret into temporal key
CryptokiEx.C_UnwrapKey(session, mechanism, hsmPrivateKey, wrappedKey, wrappedKey.length, tempTemplate, tempTemplate.length, temporalValueHandle);

// Wrap/encrypt the secret for recipients. Recipient public keys must have key wrapping allowed
for(CK_OBJECT_HANDLE recipientPublicKey : ... ) {
    LongRef resSize = new LongRef(0);
    CryptokiEx.C_WrapKey(session, mechanism, recipientPublicKey, temporalValueHandle, null, resSize);
    byte[] rewrappedKey = new byte[CryptokiUtils.safeIntCast(resSize.value)];
    CryptokiEx.C_WrapKey(session, mechanism, recipientPublicKey, temporalValueHandle, rewrappedKey, resSize);
    System.out.println("Re-wrapped key: " + bytesToHexString(rewrappedKey));
}

// Delete temporal generic secret key
CryptokiEx.C_DestroyObject(session, temporalValueHandle);

Удачи!

person vlp    schedule 02.08.2019
comment
Я боюсь, что это решение не соответствует требованиям OP, если расшифрованное сообщение не находится где-то рядом с памятью моего приложения. - person jariq; 04.08.2019
comment
@jariq Почему - расшифрованное сообщение находится внутри HSM как общий секретный ключ. В приложении есть только дескриптор для этого ключа. Учитывая шаблон этого общего секретного ключа, он является ЧУВСТВИТЕЛЬНЫМ ... Все, что приложение делает с ключом, это то, что оно обертывает его открытыми ключами получателей (кем бы они ни были) ... - person vlp; 04.08.2019
comment
Извините, я не заметил, что вы использовали общий секретный ключ. Это очень интересная идея, которую стоит изучить! Теперь мне интересно, каков предел размера для общего значения ключа. - person jariq; 04.08.2019
comment
@jariq Я никогда не пробовал, но Luna 7 утверждает, что поддерживает генерацию (через CKM_GENERIC_SECRET_KEY_GEN) общих секретных ключей длиной до 512 байт. Также обратите внимание, что ключ для переноса / развертывания не имеет вариантов, состоящих из нескольких частей. - person vlp; 04.08.2019