1. Общее
Прежде всего, я хочу упомянуть, что хотя я понимаю причины, я не полностью согласен с видением Криптография ( [Криптография]: Установка - СтатическаяКолеса ). Совместно используемые библиотеки существуют десятилетиями и доказали свое превосходство. Не говоря уже о том, что Python поставляет 2 (стандартные) модули ( _ssl и _hashlib ), которые динамически ссылка на OpenSSL (что бы это ни было в системе). В качестве примечания, на Win модули 2 Python также используются для статической ссылки на OpenSSL , но начинаются с v 3.7 , они больше не делают. Назад к Nix : 2 Версии OpenSSL загружаются в один и тот же ( Python ) процесс. Это не вредит, но выглядит смешно. И так как сегодня ( 191009 ), есть куча .whl с для v2.7 и v3.4 ,но ничего для довольно приличного ( Python ) окружения:
![Img0](https://i.stack.imgur.com/7acqj.png)
Я помню похожую ситуацию некоторое время назад: помимо 2стандартные модули M2Crypto также использовались. В этой ситуации (мы поставили Python полностью), 2 конкретных ( FIPS способны) OpenSSL ( динамический ) lib *Также были отправлены 1065 * s, и все модули Python связаны с ними. Он работал в различных ( настольных ) средах (из которых многие "экзотические"):
- CPU архитектуры ( LE *)1076 * / BE ): x86 , AMD64 , IA64 , SPARC , PPC , zSeries
- ОС es (с несколькими версиями): Win , Lnx ( RH , CentOS , OEL , SuSE , Xen , Ubuntu ), Solaris , AIX , HP-UX (и в качестве личного упражнения я добавил OSX )
[OpenSSL]: UserGuide-2.0.pdf - Руководство пользователя для объектного модуля OpenSSL FIPS v2.0 (ссылка из [OpenSSL]: FIPS-140 в случае изменения URL ) содержитвсе необходимые детали.
Прежде чем идти дальше, вот несколько терминов, которые я собираюсь использовать в этом посте:
- FOM - FIPS объектный модуль (fipscanister.o )
- FOME - исполняемый файл ( ELF ( PE на Win )), который FOM был связан в . Имейте в виду, что это может быть либо исполняемый файл сам по себе , либо .so ( .dll ). Кроме того, если он включен в статическую библиотеку ( .a ), он не связан (просто заархивирован). В качестве примечания, когда OpenSSL собран совместно, FOME равен libcrypto.so. *, тогда как при статической сборке (как в этом случае) этоисполняемый файл, который связывается с libcrypto.a (например, openssl исполняемый файл)
FOM поставляется поверх OpenSSL (и, вероятно, других таких поставщиков криптографии, как LibreSSL , WolfSSL ,), и это предназначено для усиления безопасности (согласно стандартам NIST ), ограничиваянекоторые функции, которые в противном случае были бы доступны. Одним из таких примеров является использование хеша md5 , который считается слабым (я уверен, что sha1 будет следовать в следующей версии обудет выпущен).
Вот (очень упрощенная) версия того, что происходит (во время выполнения):
- FIPS включен режим:
- Проверьте,дополнительные ограничения соблюдены:
- Да: продолжить (с функциональностью по умолчанию)
- Нет: возврат с ошибкой
- FIPS режим выключен:
- Откат к функциональности по умолчанию
Часть # 1.1. является самопроверкой. Он состоит из:
- Вычисление FOME подписи
- Сравнение со значением (которое также было сохранено в FOME )
Это делается для того, чтобы удостовериться (или резко уменьшить шансы), что никто не вмешивался (изменяя вручную, разбирая, ...) с FOME . Чтобы лучше понять механизм подписи, давайте погрузимся в процесс сборки FOME :
- Все источники FOME + FOM скомпилированы (в объектные файлы)
- Они связаны вместе (в FOME ). Это когда нормальная сборка заканчивается
- Считается FOME подпись
- Элементы из # 1. + fips_premain.o связаны с (настоящим, а не .dll ) исполняемым файлом ( FPD )
- FPD вызывается против FOME ( # 1. ). Он читает раздел FOME .rodata и вычисляет его sha1 хэш. Обратите внимание, что игнорирует 41 зону байтов (пробивает отверстие) , расположенную по определенному адресу
- # 3.1. повторяется, но на этот раз fips_premain.o было перекомпилировано, чтобы также включить хэш из предыдущего шага. Теперь становится понятным пробитое отверстие из предыдущего шага, это место, куда идет подпись: (длина ша хеш ( 40 ) + нуль ). Это последний FOME
Примечание: при Win все происходит немного иначе.
Мне удалось воспроизвести проблему. Я собираюсь начать с тестового сценария.
code00.py :
#!/usr/bin/env python3
import sys
from cryptography.hazmat.backends.openssl.backend import backend
import cffi
def main():
ffi = cffi.FFI()
lib = backend._lib
fmt = "OpenSSL version: {0:s}\nFIPS_mode(): {1:d}\nFIPS_mode_set(1): {2:d}\nFIPS_mode(): {3:d}"
print(fmt.format(ffi.string(lib.OPENSSL_VERSION_TEXT).decode(),
lib.FIPS_mode(), lib.FIPS_mode_set(1), lib.FIPS_mode()))
err = lib.ERR_get_error()
if err:
err_fmt = "error:[{0:d}]:[{1:s}]:[{2:s}]:[{3:s}]"
print(err_fmt.format(
err,
ffi.string(lib.ERR_lib_error_string(err)).decode(),
ffi.string(lib.ERR_func_error_string(err)).decode(),
ffi.string(lib.ERR_reason_error_string(err)).decode()
))
else:
print("Success !!!")
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main()
print("\nDone.")
2. Настройка
Я уже собрал FOM и FIPS с поддержкой OpenSSL (аналогично вашему, но я настроил их пути). Переменная $ {FIPSDIR} использовалась при построении FOM и OpenSSL .
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435]> ~/sopr.sh
*** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ***
[064bit-prompt]> uname -a
Linux cfati-ubtu16x64-0 4.15.0-65-generic #74~16.04.1-Ubuntu SMP Wed Sep 18 09:51:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
[064bit-prompt]> cat /etc/lsb-release | grep DESCR
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
[064bit-prompt]> gcc --version | grep gcc
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.11) 5.4.0 20160609
[064bit-prompt]>
[064bit-prompt]> echo ${FIPSDIR}
/home/cfati/Work/Dev/Tools/zzz_Build/OpenSSL/int/openssl-fips-2.0.16
[064bit-prompt]> tree ${FIPSDIR}
/home/cfati/Work/Dev/Tools/zzz_Build/OpenSSL/int/openssl-fips-2.0.16
├── bin
│ ├── fipsld
│ └── fips_standalone_sha1
├── include
│ └── openssl
│ ├── aes.h
│ ├── bn.h
│ ├── buffer.h
│ ├── cmac.h
│ ├── crypto.h
│ ├── des.h
│ ├── des_old.h
│ ├── dh.h
│ ├── dsa.h
│ ├── ebcdic.h
│ ├── ecdh.h
│ ├── ecdsa.h
│ ├── ec.h
│ ├── e_os2.h
│ ├── evp.h
│ ├── fips.h
│ ├── fips_rand.h
│ ├── fipssyms.h
│ ├── hmac.h
│ ├── modes.h
│ ├── opensslconf.h
│ ├── opensslv.h
│ ├── ossl_typ.h
│ ├── rsa.h
│ ├── sha.h
│ └── symhacks.h
└── lib
├── fipscanister.o
├── fipscanister.o.sha1
├── fips_premain.c
└── fips_premain.c.sha1
4 directories, 32 files
[064bit-prompt]>
[064bit-prompt]> echo ${OPENSSL_DIR}
/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16-static
[064bit-prompt]> tree ${OPENSSL_DIR}/bin ${OPENSSL_DIR}/lib
/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16-static/bin
├── c_rehash
└── openssl
/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16-static/lib
├── engines
├── libcrypto.a
├── libssl.a
└── pkgconfig
├── libcrypto.pc
├── libssl.pc
└── openssl.pc
2 directories, 7 files
[064bit-prompt]>
[064bit-prompt]> ldd ${OPENSSL_DIR}/bin/openssl
linux-vdso.so.1 => (0x00007ffeec045000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f12c19c2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f12c15f8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f12c1bc6000)
[064bit-prompt]>
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl version
OpenSSL 1.0.2t-fips 10 Sep 2019
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl sha1 ./code00.py
SHA1(./code00.py)= ff122260b025103dbc03316e3d3e26cd683e7a12
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
MD5(./code00.py)= eac85e46734260c1bfcceb89d6a3bd32
[064bit-prompt]> OPENSSL_FIPS=1 ${OPENSSL_DIR}/bin/openssl sha1 ./code00.py
SHA1(./code00.py)= ff122260b025103dbc03316e3d3e26cd683e7a12
[064bit-prompt]> OPENSSL_FIPS=1 ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
Error setting digest md5
140584610875032:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180:
3. Криптография модуль
[064bit-prompt]> ls
code00.py cryptography-2.7.tar.gz
[064bit-prompt]> mkdir build
[064bit-prompt]> cd build
[064bit-prompt]>
[064bit-prompt]> CFLAGS="-I${OPENSSL_DIR}/include -DOPENSSL_FIPS=1" LDFLAGS="-L${OPENSSL_DIR}/lib" python3 -m pip wheel --no-cache --no-binary :all: ../cryptography-2.7.tar.gz
Processing /home/cfati/Work/Dev/StackOverflow/q058228435/cryptography-2.7.tar.gz
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting asn1crypto>=0.21.0 (from cryptography==2.7)
Downloading https://files.pythonhosted.org/packages/d1/e2/c518f2bc5805668803ebf0659628b0e9d77ca981308c7e9e5564b30b8337/asn1crypto-1.0.1.tar.gz (115kB)
|████████████████████████████████| 122kB 801kB/s
Collecting cffi!=1.11.3,>=1.8 (from cryptography==2.7)
Downloading https://files.pythonhosted.org/packages/93/1a/ab8c62b5838722f29f3daffcc8d4bd61844aa9b5f437341cc890ceee483b/cffi-1.12.3.tar.gz (456kB)
|████████████████████████████████| 460kB 1.8MB/s
Collecting six>=1.4.1 (from cryptography==2.7)
Downloading https://files.pythonhosted.org/packages/dd/bf/4138e7bfb757de47d1f4b6994648ec67a51efe58fa907c1e11e350cddfca/six-1.12.0.tar.gz
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography==2.7)
Downloading https://files.pythonhosted.org/packages/68/9e/49196946aee219aead1290e00d1e7fdeab8567783e83e1b9ab5585e6206a/pycparser-2.19.tar.gz (158kB)
|████████████████████████████████| 163kB 4.5MB/s
Building wheels for collected packages: cryptography, asn1crypto, cffi, six, pycparser
Building wheel for cryptography (PEP 517) ... done
Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
Building wheel for asn1crypto (setup.py) ... done
Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
Building wheel for cffi (setup.py) ... done
Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
Building wheel for six (setup.py) ... done
Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
Building wheel for pycparser (setup.py) ... done
Stored in directory: /home/cfati/Work/Dev/StackOverflow/q058228435/build
Successfully built cryptography asn1crypto cffi six pycparser
WARNING: You are using pip version 19.1.1, however version 19.2.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
[064bit-prompt]>
[064bit-prompt]> ls
asn1crypto-1.0.1-py3-none-any.whl cryptography-2.7-cp35-cp35m-linux_x86_64.whl six-1.12.0-py2.py3-none-any.whl
cffi-1.12.3-cp35-cp35m-linux_x86_64.whl pycparser-2.19-py2.py3-none-any.whl
[064bit-prompt]>
[064bit-prompt]> for f in $(ls *.whl); do unzip ${f} > /dev/null; done
[064bit-prompt]> ls
asn1crypto cffi-1.12.3-cp35-cp35m-linux_x86_64.whl cryptography-2.7-cp35-cp35m-linux_x86_64.whl pycparser-2.19-py2.py3-none-any.whl
asn1crypto-1.0.1.dist-info cffi-1.12.3.dist-info cryptography-2.7.dist-info six-1.12.0.dist-info
asn1crypto-1.0.1-py3-none-any.whl _cffi_backend.cpython-35m-x86_64-linux-gnu.so pycparser six-1.12.0-py2.py3-none-any.whl
cffi cryptography pycparser-2.19.dist-info six.py
[064bit-prompt]> PYTHONPATH=.:${PYTHONPATH} python3 ../code00.py
Python 3.5.2 (default, Jul 10 2019, 11:58:48) [GCC 5.4.0 20160609] 64bit on linux
OpenSSL version: OpenSSL 1.0.2t-fips 10 Sep 2019
FIPS_mode(): 0
FIPS_mode_set(1): 0
FIPS_mode(): 0
error:[755413103]:[FIPS routines]:[FIPS_check_incore_fingerprint]:[fingerprint does not match]
Done.
Как видно, я в значительной степени там, где вы находитесь.
4. Более глубокое погружение
После долгих (и некоторых может показаться болезненными) часов отладки, испытаний ... я пришел к выводу. Учитывая, что:
- Подделка чего-либо из FOM (содержимое $ {FIPSDIR} ), одиночка не будет квалифицироваться как FIPS подтверждено . Честно говоря, этого тоже не происходит, поскольку есть конкретные инструкции, что при сборке FOM только sys admin должен копировать артефакты в безопасном месте ...., бла, блаблаМне это кажется параноидальным, но это факты. Как примечание, еще в 2013 году, когда мы 1 st вступили в контакт с FIPS (вероятно, для предотвращения любой возможной атаки (например, MITM )), FOM источники CD было отправлено из США в ROU :)))
- По умолчанию Python версия построена статически (снова :)), что означает, что $ {PYTHONCORE} (интерпретатор Python ) находится в исполняемом файле python , а не в .so ( libpython * .so *), который может быть связан с (и который исполняемый файл python делает в случае общих сборок)
- Криптография Для модуля расширения _openssl ( _openssl.abi * .so ) нужны символы из $ {PYTHONCORE} (например, PyLong_FromLong ), но это OK , поскольку в данный момент он будет загружен в процесс ( Python ) (запущенный из вышеупомянутого исполняемого файла), оннайдет их (это обычный рractice на Nix )
- Шаг сборки # 3.2. : исполняемый файл ( FPD - который должен выполняться) не выполняетсяне найти символы, поэтому он не может
Это тупик (вне зависимости от того, какая комната выходит из одного ограничения, закрыта другими), поэтому ЭТО ПРОСТО НЕ МОЖЕТ БЫТЬ СДЕЛАНО !!! (по крайней мере, на данный момент). Период! X (
5. Альтернатива
Я собирался предложить это как элегантную альтернативу (включая OpenSSL .so s (с любым ( .so ) клиент с rpath , установленным на "там") в .whl , рядом с _openssl.abi3.so , который связываетдля них), но, по-видимому, это единственный путь (который я нашел, по крайней мере).
Шаг 1 st состоит в создании общего OpenSSL версия ( FOME будет libcrypto.so. *).
[064bit-prompt]> ls
code00.py cryptography-2.7.tar.gz
[064bit-prompt]> export OPENSSL_DIR=/home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16
[064bit-prompt]> ldd ${OPENSSL_DIR}/bin/openssl
linux-vdso.so.1 => (0x00007ffe62faf000)
libssl.so.1.0.0 => /home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16/lib/libssl.so.1.0.0 (0x00007fe33c06f000)
libcrypto.so.1.0.0 => /home/cfati/Work/Dev/Tools/openssl-1.0.2t-fips-2.0.16/lib/libcrypto.so.1.0.0 (0x00007fe33bb92000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe33b7c8000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fe33b5c4000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe33c2e3000)
[064bit-prompt]>
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl version
OpenSSL 1.0.2t-fips 10 Sep 2019
[064bit-prompt]> ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
MD5(./code00.py)= eac85e46734260c1bfcceb89d6a3bd32
[064bit-prompt]> OPENSSL_FIPS=1 ${OPENSSL_DIR}/bin/openssl md5 ./code00.py
Error setting digest md5
139796140275352:error:060A80A3:digital envelope routines:FIPS_DIGESTINIT:disabled for fips:fips_md.c:180
После очередного сеанса глубокого погружения (множество неудачных попыток)попыток), я смог заставить его работать. Однако предпринял много действий:
- Ручные вмешательства
- Взломы
- (Хромой) обходные пути ( gainarii )
Боюсь, что если бы я все это здесь поместил, он бы значительно превысил 30K char s limit ( [SE.Meta]: Зная свои пределы: какова максимальная длина названия вопроса,post, image и использованные ссылки? ).
Однако я опубликовал .whl на [GitHub]: CristiFati / Prebuilt-Binaries - (master) Prebuilt-Binaries / Криптография / v2.7 / OpenSSL-1.0.2t-fips-2.0.16 . Пока это только для Python 3.5 ( 64bit ), так как это версия по умолчанию, которая устанавливается на Ubuntu 16 . Если вы используете другую (более новую) версию, просто дайте мне знать, и я ее получу (возможно, соберу сам), и соберу .whl для этой версии (я все равно собираюсь это сделать)).
После замены оригинального .whl на созданный мной:
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> ll
total 2936
drwxrwxr-x 2 cfati cfati 4096 Oct 9 21:40 .
drwxrwxr-x 4 cfati cfati 4096 Oct 9 21:28 ..
-rw-rw-r-- 1 cfati cfati 108067 Oct 9 08:43 asn1crypto-1.0.1-py3-none-any.whl
-rw-rw-r-- 1 cfati cfati 318045 Oct 9 08:43 cffi-1.12.3-cp35-cp35m-linux_x86_64.whl
-rw-rw-r-- 1 cfati cfati 2438739 Oct 9 21:40 cryptography-2.7-cp35-cp35m-linux_x86_64.whl
-rw-rw-r-- 1 cfati cfati 112066 Oct 9 08:43 pycparser-2.19-py2.py3-none-any.whl
-rw-rw-r-- 1 cfati cfati 12099 Oct 9 08:43 six-1.12.0-py2.py3-none-any.whl
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> for f in $(ls *.whl); do unzip ${f} > /dev/null; done
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> ls
asn1crypto cffi-1.12.3-cp35-cp35m-linux_x86_64.whl cryptography-2.7-cp35-cp35m-linux_x86_64.whl pycparser-2.19-py2.py3-none-any.whl
asn1crypto-1.0.1.dist-info cffi-1.12.3.dist-info cryptography-2.7.dist-info six-1.12.0.dist-info
asn1crypto-1.0.1-py3-none-any.whl _cffi_backend.cpython-35m-x86_64-linux-gnu.so pycparser six-1.12.0-py2.py3-none-any.whl
cffi cryptography pycparser-2.19.dist-info six.py
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q058228435/build]> PYTHONPATH=.:${PYTHONPATH} python3 ../code00.py
Python 3.5.2 (default, Jul 10 2019, 11:58:48) [GCC 5.4.0 20160609] 64bit on linux
OpenSSL version: OpenSSL 1.0.2t-fips 10 Sep 2019
FIPS_mode(): 0
FIPS_mode_set(1): 1
FIPS_mode(): 1
Success !!!
Done.
Похожие (более или менее) сообщения: