== Code-signing == Code-signing means attaching a digital signature to an executable to verify its vendor and the integrity of the file itself. More information can be found here: http://en.wikipedia.org/wiki/Code_signing. This article assumes that the reader is already familiar with code-signing executables on Windows. == Support in !PyInstaller == !PyInstaller does not sign executables itself: it only allows the generated executables to be signed without this damaging its functionality. It is not obvious that this works out of the box like with normal executables, because !PyInstaller's executables are special (they have an attached package at the end of the executable itself). Since !PyInstaller allows a whole Python application, including all third-party dependencies, to be packaged into a single file, putting a digital signature on that file effectively mark the whole code of your application. == Integrating with !PyInstaller's build process == If you are familiar with code-signing executables on the command-line, you know that you usually run the SIGNTOOL program from MS with a command line like this: {{{ SIGNTOOL.EXE /F yourkey.pfx /P /T }}} This will work correctly with !PyInstaller's generated executable. To achieve a broader integration, you can add this code-signing step to the .spec file, leveraging the fact that it is a regular Python file. The following is an example: {{{ #!python # -*- mode: python -*- a = Analysis([os.path.join(HOMEPATH,'support\\_mountzlib.py'), os.path.join(HOMEPATH,'support\\useUnicode.py'), 'www.py'], pathex=['D:\\test']) pyz = PYZ(a.pure) exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name=os.path.join('dist', 'www.exe'), debug=True, strip=False, upx=False, console=True ) # **************************************** # Code-sign the generated executable import subprocess subprocess.call([ "SIGNTOOL.EXE", "/F", "path-to-key.pfx", "/P", "your-password", "/T", "time-stamping url", exe.name ]) # **************************************** }}} If you don't want to put your password in clear-text in the spec file, you can even use {{{getpass.getpass()}}} to ask it interactively to the user running the script. If you are using an older Python version without subprocess support, use the following code instead: {{{ #!python # **************************************** # Code-sign the generated executable os.system("SIGNTOOL.EXE /F %s /P %s /T %s %s" % ("path-to-key.pfx", "your-password", "time-stamping url", exe.name)) # **************************************** }}}