Python 有没有办法从命令行将常量注入Cython模块?

Python 有没有办法从命令行将常量注入Cython模块?,python,cython,Python,Cython,我想在用Cython编译的模块中嵌入配置秘密(如访问密钥)。这些值不应该容易从编译的代码中访问,也不应该与实际的源代码隔离。有没有一种方法可以从不同于主Python代码的源注入这些值(比如cython或c编译器的comand行选项) 注意:我不希望自己的Cython模块只包含访问密钥,因为可以很容易地找到访问密钥。您需要一个注入机制,因为您正确地假设用户可以访问的文件中存储的任何内容都将被提取 这无疑意味着,无论以何种方式将密钥材料传递给您选择的用户代码,密钥都将被加密和过滤。是的,用户可访问的

我想在用Cython编译的模块中嵌入配置秘密(如访问密钥)。这些值不应该容易从编译的代码中访问,也不应该与实际的源代码隔离。有没有一种方法可以从不同于主Python代码的源注入这些值(比如cython或c编译器的comand行选项)


注意:我不希望自己的Cython模块只包含访问密钥,因为可以很容易地找到访问密钥。

您需要一个注入机制,因为您正确地假设用户可以访问的文件中存储的任何内容都将被提取

这无疑意味着,无论以何种方式将密钥材料传递给您选择的用户代码,密钥都将被加密和过滤。是的,用户可访问的代码不应访问密钥

当然,这是一个已解决的问题。使用一个API,该API接受来自云服务的质询,并可以选择用户输入(“密码”等),然后返回一个临时授权令牌。令牌应该很快过期,使会话窃取变得不切实际。只要用户正在使用访问权限,重新授权过程应该定期重复

例如,SSH就是这样工作的。您可以使用OS权限或硬件令牌安全地隐藏SSH密钥(请参阅U2F)。您也可以尝试将U2F与GPG一起使用;一些云服务可能本机支持U2F


到现在为止,您肯定还记得安全性不能固定在现有解决方案上,而必须从一开始就构建在其中的想法。你可能需要在考虑安全性的情况下重新考虑应用程序的更广泛范围,并提出适当的授权机制。我不知道您的问题的具体情况,因此我无法猜测具体的方法。

您需要一种注入机制,因为您正确地假设,用户可以访问的文件中存储的任何内容都将被提取

这无疑意味着,无论以何种方式将密钥材料传递给您选择的用户代码,密钥都将被加密和过滤。是的,用户可访问的代码不应访问密钥

当然,这是一个已解决的问题。使用一个API,该API接受来自云服务的质询,并可以选择用户输入(“密码”等),然后返回一个临时授权令牌。令牌应该很快过期,使会话窃取变得不切实际。只要用户正在使用访问权限,重新授权过程应该定期重复

例如,SSH就是这样工作的。您可以使用OS权限或硬件令牌安全地隐藏SSH密钥(请参阅U2F)。您也可以尝试将U2F与GPG一起使用;一些云服务可能本机支持U2F


到现在为止,您肯定还记得安全性不能固定在现有解决方案上,而必须从一开始就构建在其中的想法。你可能需要在考虑安全性的情况下重新考虑应用程序的更广泛范围,并提出适当的授权机制。我不知道您的问题的具体情况,因此我无法猜测具体的方法。

前言:这是不安全的,您不应该这样做来隐藏凭据。任何有权访问二进制文件的人都可以转储凭证,如果他们有源代码(正如您在评论中所暗示的),这将特别容易

也就是说,由于cython文件是编译的,为了回答一般问题,可以使用C预处理器通过
-D
命令行标志注入文本

赛昂

# file.pyx
cdef extern from "header.h":
    cdef char* ARG

def f():
    return ARG
C头

# header.h
// empty, ARG will be inserted by preprocessor
设置工具

# setup.py
from setuptools import setup, Extension
from Cython.Build import cythonize
import os

ext = [Extension('file', ['file.pyx'], 
                 extra_compile_args=[f'-DARG=\\"{os.environ.get("ARG")}\\"'])]

setup(name='test', ext_modules=cythonize(ext))
行动中

$ set ARG=THING
$ python setup.py build_ext --inplace
$ python
>>> import file
>>> file.f()
b'THING'

前言:这是不安全的,您不应该这样做来隐藏凭据。任何有权访问二进制文件的人都可以转储凭证,如果他们有源代码(正如您在评论中所暗示的),这将特别容易

也就是说,由于cython文件是编译的,为了回答一般问题,可以使用C预处理器通过
-D
命令行标志注入文本

赛昂

# file.pyx
cdef extern from "header.h":
    cdef char* ARG

def f():
    return ARG
C头

# header.h
// empty, ARG will be inserted by preprocessor
设置工具

# setup.py
from setuptools import setup, Extension
from Cython.Build import cythonize
import os

ext = [Extension('file', ['file.pyx'], 
                 extra_compile_args=[f'-DARG=\\"{os.environ.get("ARG")}\\"'])]

setup(name='test', ext_modules=cythonize(ext))
行动中

$ set ARG=THING
$ python setup.py build_ext --inplace
$ python
>>> import file
>>> file.f()
b'THING'

您考虑过将常量作为环境变量传递吗?这在编译时是可以的。但不是在运行时读取二进制密钥文件如何?如果您将访问密钥编译到cython模块(甚至是编码的)中,并靠近解码/计算此密钥的代码,那么从二进制文件中提取代码不会花费很长时间。我想您需要的是对云服务端点的API授权,用户在其中管理自己的凭据。这应该是一个硬件无关的解决方案。您考虑过将常量作为环境变量传递吗?这在编译时是可以的。但不是在运行时读取二进制密钥文件如何?如果您将访问密钥编译到cython模块(甚至是编码的)中,并靠近解码/计算此密钥的代码,那么从二进制文件中提取代码不会花费很长时间。我想您需要的是对云服务端点的API授权,用户在其中管理自己的凭据。这应该是一个硬件不可知的解决方案。我更愿意得到我的问题的答案(如何注入该值)。授权API也有同样的问题。如何确保我只授权我们的客户代码?可能是某种形式的挑战/回应,这也需要一把钥匙。几乎所有的移动应用(带有云组件)最终都是这样工作的:它们在应用代码的某个地方隐藏了授权密钥。当然,有很多方法可以做到这一点,但它肯定比一个带值的纯文本配置文件更难(特别是对于普通用户而言)。这取决于“注入”的含义。你为什么不打开一个本地文件并从那里读取呢?您在需求中有一个矛盾:您需要使键对代码可用,但要求“这些值不应该很容易从编译的代码中访问”。当然,您可以将其从源代码中分离出来。你的想法是什么