Является ли мое шифрование безопасным как openPGP / SMIME?

Я пытаюсь написать простой файл enc / decryption в рамках более крупного проекта. Я бы хотел избежать libgpgme из-за проблем с лицензией. Стандарт OpenPGP является сложным для проектного таймфрейма, который у меня есть. Я хотел бы сделать свой шифрование с помощью openssl.

Теперь я реализовал следующее:

шифрование (код псевдонима):

RAND_bytes(aes_key) RAND_bytes(aes_salt) EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (const unsigned char *)aes_salt, aes_key, sizeof(aes_key), 5, key, iv); 

то i aes256 мои данные

 EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, iv); 

затем я шифрую ключ и iv с помощью RSA

 RSA_public_encrypt(flen, (unsigned char *)key, encryptedKey, rsa, RSA_PKCS1_PADDING ); RSA_public_encrypt(flen, (unsigned char *)iv, encryptedIV, rsa, RSA_PKCS1_PADDING ); 

затем я сохраняю 128-битный ключ и iv в «верхней части» моего файла (заголовок 256Bytes).

дешифрование: -> прочитать первые 256 байт (разделить на ключ и iv) -> дешифровать ключ и iv с помощью локального закрытого ключа RSA (конечно, закрытый ключ RSA НЕ находится в файле) -> использовать ключ и iv расшифровывать данные

Я вроде как безопасен с этим кодом?

Так как вы все равно используете функции шифрования OpenSSL, вы должны просто использовать функции EVP_SealInit() / EVP_SealUpdate() / EVP_SealFinal() . Эти функции заботятся о генерации симметричного ключа и IV, шифрования данных симметричным ключом и шифровании симметричного ключа с помощью ключей (ов) RSA (-ов) получателя.

Когда вещь, о которой вы не заботитесь, – это подлинность. В режиме CBC злоумышленник может внести определенные предсказуемые изменения в открытый текст, даже если они не могут его прочитать. Чтобы обнаружить это, вы должны либо вычислить HMAC по зашифрованному сообщению (используя отдельный симметричный ключ для используемого для шифрования), либо подписать зашифрованное сообщение (например, с помощью EVP_SignInit() / EVP_SignUpdate() / EVP_SignFinal() ).

Поскольку это новый формат, вы должны использовать дополнение OAEP. Просто измените RSA_PKCS1_PADDING на RSA_PKCS1_OAEP_PADDING . Вам действительно не нужно шифровать IV (это не может повредить, насколько я могу судить, и это может помочь).

В противном случае этот метод должен быть точным до тех пор, пока RSA_size(rsa)==16 . Конечно, секретный ключ не должен быть узнаваем ни у кого, кто не сможет расшифровать файл.

Шифрование – это тема, в которой все легко сделать «работать» – но трудно сделать безопасным. Когда вы сомневаетесь (и вдвойне, если не сомневаетесь), выбирайте широко признанный стандарт и точно выполняйте спецификации . Идея шифрования ключа с общедоступным алгоритмом, а затем упаковка IV в том, как звучит теоретически, но я не уверен, что последствия шифрования IV также, и что произойдет, если злоумышленник начнет переворачивать бит в зашифрованных данных? И т. Д. Это выглядит здорово, но опять же, я бы настоятельно рекомендовал просто реализовать опубликованную спецификацию точно .

Я бы рекомендовал просто реализовать S / MIME , используя двоичную кодировку передачи. S / MIME распознается как безопасная спецификация, есть библиотеки, реализующие все жесткие части , и, самое главное, вы можете протестировать свою реализацию против других реализаций, чтобы убедиться, что вы не из спецификации.

Некоторые наблюдения:

  • Функция EVP_BytesToKey предназначена для создания вектора ключа и инициализации из пароля и соли, а не из случайных данных. Он будет работать, но вы также можете просто использовать случайные байты непосредственно в качестве ключа и вектора инициализации. (Убедитесь, что вы используете безопасный PRNG, я не уверен, что на RAND_bytes деле делает RAND_bytes .)

  • Вектор инициализации не должен быть секретным, режим CBC должен быть защищен с помощью нешифрованного IV. (Это не больно, хотя.)

  • Шифрование RSA выглядит хорошо (но вы можете использовать другое дополнение, как сказал Дэвид).

  • Как сказал Сердалис, вы также должны защитить свой файл от изменений. Любой ключевой MAC будет делать (наиболее часто встречаются HMAC на основе ключа и hash-функции). Примените MAC после шифрования.