Python 如何使用werkzeug/BATTLE实现私有/公共apikey?

Python 如何使用werkzeug/BATTLE实现私有/公共apikey?,python,rest,public-key-encryption,bottle,werkzeug,Python,Rest,Public Key Encryption,Bottle,Werkzeug,我正在用瓶子开发一个RESTful web服务,可能很快就会迁移到Werkzeug。我想实现一个基于私钥/公钥对的身份验证方案,其中服务器只需存储公共部分,而用户保留私有部分。访问时,服务器将要求访问者使用服务器可以验证并与公钥部分相关的私钥执行操作。例如,一旦成功,就会生成一个令牌,该令牌可以使用一段时间。对于Werkzeug或Bottle来说,实现这种功能的途径是什么?我可以从哪些项目/例子中学习 我认为,最好的选择是将使用密码学的责任转移到其他方面。Web服务器和CA(证书颁发机构)很擅长

我正在用瓶子开发一个RESTful web服务,可能很快就会迁移到Werkzeug。我想实现一个基于私钥/公钥对的身份验证方案,其中服务器只需存储公共部分,而用户保留私有部分。访问时,服务器将要求访问者使用服务器可以验证并与公钥部分相关的私钥执行操作。例如,一旦成功,就会生成一个令牌,该令牌可以使用一段时间。对于Werkzeug或Bottle来说,实现这种功能的途径是什么?我可以从哪些项目/例子中学习

我认为,最好的选择是将使用密码学的责任转移到其他方面。Web服务器和CA(证书颁发机构)很擅长使用它

基本上,他们可以做到

  • 确保连接牢固
  • 确保客户端使用由有效(比如您的)CA签名的证书
  • 确保证书未被吊销
  • 向应用程序提供所需的唯一信息:远程方的标识符
  • 我们使用这种机制对第三方支付服务进行身份验证(对不起,是私有代码),还有一种提供相同的客户端授权机制的方法,我们也使用它(当然,它是Ruby,但它也是可以在wild中找到此类服务的有效证明)

    要让事情顺利进行,你只需要

  • 配置您的CA
  • 配置您的web服务器,以确保它接受您的权限颁发的证书,并且仅接受这些证书,并将客户端id进一步传递给您的应用程序
  • 确保应用程序可以从请求中提取客户端标识符
  • 下面是easyrsa、nginx、uWsgi和werkzeug的一个小例子

    配置CA

    easyrsa工具包是OpenVPN安装的一部分。可以使用OpenSSL“raw”命令或PyOpenSSL,但easyrsa很方便,至少在概念阶段是合适的

    cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/nginx/easyrsa
    cd /etc/nginx/easyrsa && source vars && ./clean-all
    
    创建CA

    ./build-ca
    
    创建服务器证书

    ./build-key --server server
    
    创建客户端证书

    ./build-key-pkcs12  client1
    
    在上面的示例中,您创建了客户机密钥及其相应的公共部分(证书),但良好的做法是假设您对客户机证书请求进行签名,并且无法访问机密部分

    有些服务会为您生成一对密钥+证书,然后在下载页面上写一条消息,如“这是您下载密钥的唯一机会。我们不存储密钥,因此以后无法下载。”

    此外,该命令创建一个带有加密密钥和证书的PKCS12文件,便于导入到浏览器

    配置nginx

    首先,我们应该创建一对“服务器证书+ca证书”,作为我们的ca自签名:

    cat keys/server.crt keys/ca.crt > keys/server_and_ca.crt
    
    然后可以应用以下配置:

    server {
        listen 443;
    
        location / {
            # Here we define the name and the contents of the WSGI variable to pass to service
            uwsgi_param SSL_CLIENT_ID $ssl_client_s_dn;
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:5000;
        }
    
    
        # SSL support
        ssl                 on;
        ssl_protocols       SSLv3 TLSv1;
        ssl_certificate     easyrsa/keys/ca_and_server.crt;
        ssl_certificate_key easyrsa/keys/server.key;
    
        # We don't accept anyone without correct client certificate
        ssl_verify_client on;
        # The CA we use to verify client certificates
        ssl_client_certificate easyrsa/keys/ca.crt;
    }
    
    有关配置选项的更多信息,请参阅

    确保您对/etc/nginx/easyrsa目录拥有正确的权限,并且只有root和nginx可以访问密钥

    编写Werkzeug应用程序

    python部分很简单。只需从WSGI环境中读取变量SSL_CLIENT_ID

    文件
    sample.py

    from werkzeug.wrappers import Response
    
    def application(environ, start_response):
        text = 'Hello, your certificate id is %s\n' % environ.get('SSL_CLIENT_ID', '(unknown)')
        response = Response(text, mimetype='text/plain')
        return response(environ, start_response)
    
    使用uwsgi服务器启动服务:
    uwsgi-w示例:应用程序——套接字127.0.0.1:5000

    测试您的安装

    用旋度测试很容易

    $ curl --cert keys/client1.crt --key keys/client1.key --cacert keys/ca.crt https://localhost/
    Hello, your certificate id is /C=US/ST=CA/L=SanFrancisco/O=Fort-Funston/OU=changeme/CN=client1/name=changeme/emailAddress=mail@host.domain
    

    我认为,最好的选择是将使用密码技术的责任转移到其他方面。Web服务器和CA(证书颁发机构)很擅长使用它

    基本上,他们可以做到

  • 确保连接牢固
  • 确保客户端使用由有效(比如您的)CA签名的证书
  • 确保证书未被吊销
  • 向应用程序提供所需的唯一信息:远程方的标识符
  • 我们使用这种机制对第三方支付服务进行身份验证(对不起,是私有代码),还有一种提供相同的客户端授权机制的方法,我们也使用它(当然,它是Ruby,但它也是可以在wild中找到此类服务的有效证明)

    要让事情顺利进行,你只需要

  • 配置您的CA
  • 配置您的web服务器,以确保它接受您的权限颁发的证书,并且仅接受这些证书,并将客户端id进一步传递给您的应用程序
  • 确保应用程序可以从请求中提取客户端标识符
  • 下面是easyrsa、nginx、uWsgi和werkzeug的一个小例子

    配置CA

    easyrsa工具包是OpenVPN安装的一部分。可以使用OpenSSL“raw”命令或PyOpenSSL,但easyrsa很方便,至少在概念阶段是合适的

    cp -a /usr/share/doc/openvpn/examples/easy-rsa/2.0 /etc/nginx/easyrsa
    cd /etc/nginx/easyrsa && source vars && ./clean-all
    
    创建CA

    ./build-ca
    
    创建服务器证书

    ./build-key --server server
    
    创建客户端证书

    ./build-key-pkcs12  client1
    
    在上面的示例中,您创建了客户机密钥及其相应的公共部分(证书),但良好的做法是假设您对客户机证书请求进行签名,并且无法访问机密部分

    有些服务会为您生成一对密钥+证书,然后在下载页面上写一条消息,如“这是您下载密钥的唯一机会。我们不存储密钥,因此以后无法下载。”

    此外,该命令创建一个带有加密密钥和证书的PKCS12文件,便于导入到浏览器

    配置nginx

    首先,我们应该创建一对“服务器证书+ca证书”,作为我们的ca自签名:

    cat keys/server.crt keys/ca.crt > keys/server_and_ca.crt
    
    然后可以应用以下配置:

    server {
        listen 443;
    
        location / {
            # Here we define the name and the contents of the WSGI variable to pass to service
            uwsgi_param SSL_CLIENT_ID $ssl_client_s_dn;
            include uwsgi_params;
            uwsgi_pass 127.0.0.1:5000;
        }
    
    
        # SSL support
        ssl                 on;
        ssl_protocols       SSLv3 TLSv1;
        ssl_certificate     easyrsa/keys/ca_and_server.crt;
        ssl_certificate_key easyrsa/keys/server.key;
    
        # We don't accept anyone without correct client certificate
        ssl_verify_client on;
        # The CA we use to verify client certificates
        ssl_client_certificate easyrsa/keys/ca.crt;
    }
    
    有关配置选项的更多信息,请参阅

    确保您对/etc/nginx/easyrsa目录具有正确的权限,并且只有root和nginx可以访问