我们生活在一个应用程序用于做任何事情的世界,无论是股票交易还是预订沙龙,但在幕后,连接是使用秘密完成的。必须适当管理机密,例如数据库密码、API 密钥、令牌等,以避免任何泄露。
管理机密的需求对任何组织都至关重要。机密可以通过多种方式泄露,包括通过版本控制系统(切勿对代码中的任何机密进行硬编码)、私人消息、电子邮件和其他通信渠道。如果机密泄露,可能会导致信任、信誉甚至业务的丧失。在某些情况下,泄露的机密也可能导致法律诉讼。这就是为什么制定管理机密的计划如此重要的原因。
在本文中,我们将讨论在 Python 中有效管理机密的四种不同方法。
在开始之前,请记住以下几点,以避免以后出现任何问题:
我们将为此设备使用 MacOS。请根据您的操作系统使用这些命令。
在本节中,我们将讨论在 Python 中管理机密的四种不同方法:
该文件是用于在Python中存储环境变量的文件。环境变量是在 Python 代码之外设置的变量,用于配置 Python 代码。该文件通常用于存储密钥和密码。.env
我们将使用该包来访问文件的内容。若要开始,请首先使用以下命令安装包:python-dotenv.env
$ pip install python-dotenv
创建用于测试目的的文件并粘贴以下机密:.env
API_KEY=test-key
API_SECRET=test-secret
当然,此文件不应提交到您的 git 存储库。否则,即使您删除它,它也将被版本控制和可读。
将此行添加到您的文件中:.gitignore
.env
完成后,创建一个文件并粘贴下面提到的代码片段。在此代码中,我们使用函数从文件加载内容:main.pyload_dotenv().env
from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv("API_KEY")
api_secret = os.getenv("API_SECRET")
print("API_KEY: ", api_key)
print("API_SECRET: ", api_secret)
我们还可以使用该函数,它将机密转换为字典。可以使用以下代码片段访问机密:dotenv_values()
from dotenv import dotenv_values
secrets = dotenv_values(".env")
def main():
print(secrets["API_KEY"])
print(secrets["API_SECRET"])
if __name__ == "__main__":
main()
处理大型项目时,您可能会发现需要多个文件。例如,您可能有一个用于本地开发环境的文件和一个用于云开发生产环境的文件。如果您有多个文件,以下代码片段可能会有所帮助:.env.env.env.dev.env
from dotenv import dotenv_values
secrets = dotenv_values(".env")
local_secrets = dotenv_values(".env.dev")
def main():
print(secrets["API_KEY"])
print(local_secrets["API_SECRET"])
if __name__ == "__main__":
main()
若要使机密更有条理,还可以使用 JSON 文件。让我们创建一个文件并将以下机密粘贴到其中:secrets.json
{
"db": {
"host": "localhost",
"port": 27017,
"name": "test"
},
"server": {
"host": "localhost",
"port": 3000
}
}
与上述相同,请勿提交此文件。
现在我们已经准备好了 JSON 文件,让我们编写一个函数来访问文件中的机密:
import json
def get_value_from_json(json_file, key, sub_key):
try:
with open(json_file) as f:
data = json.load(f)
return data[key][sub_key]
except Exception as e:
print("Error: ", e)
print(get_value_from_json("secrets.json", "db", "host")) # prints localhost
$ export variable_name=value
$ export API_KEY_TEST=dummykey
在 Windows 计算机上,可以使用 GUI 添加环境变量或使用以下命令添加变量:
$ setx [variable_name] “[value]”
可以使用操作系统包访问操作系统环境变量。下面提到的是示例代码:
import os
# Get the secret key from the environment
secret_key = os.environ.get('api_key_test')
print(secret_key) // prints dummykey
命令行中的机密也应特别小心地处理。
AWS Secrets Manager 在整个行业中广泛使用。让我们编写一个函数来使用 Boto3 在 AWS 中创建和访问密钥:
import boto3
def fetch_secret_from_aws(secret_name):
try:
session = boto3.session.Session()
client = session.client(service_name='secretsmanager', region_name='us-east-1')
get_secret_value_response = client.get_secret_value(SecretId=secret_name)
return get_secret_value_response['SecretString']
except Exception as e:
print(e)
return None
def create_secret_in_aws(secret_name, secret_value):
try:
session = boto3.session.Session()
client = session.client(service_name='secretsmanager', region_name='us-east-1')
client.create_secret(Name=secret_name, SecretString=secret_value)
return True
except Exception as e:
print(e)
return False
KMS 是集中管理应用程序和服务使用的密钥的便捷方法,有助于确保只有授权用户才能访问这些密钥。
Hashicorp Vault 是市场上最好的开源 KMS 之一,它提供了许多功能和优势,包括跨多个环境管理密钥和密钥的能力、强大的安全控制和良好的可扩展性。
让我们编写一个函数来读取机密并将其写入保管库中的特定路径。
注意:请确保您已安装 hvac(适用于 Vault 的 Python 客户端)并设置了 Hashicorp Vault:
import hvac
def read_secret_from_vault(secret_path, token, secret_name):
try:
client = hvac.Client(
url='',
token=token,
)
read_response = client.secrets.kv.read_secret_version(path=secret_path)
return read_response['data']['data'][secret_name]
except Exception as e:
print(e)
return None
def write_secret_to_vault(secret_path, token, secret_name, secret_value):
try:
client = hvac.Client(
url='',
token=token,
)
create_response = client.secrets.kv.v2.create_or_update_secret(
path=secret_path,
secret={secret_name: secret_value},
)
return create_response
except Exception as e:
print(e)
return None
管理机密是应用程序开发的重要组成部分。当开发人员将明文机密硬编码到他们的应用程序中时,会产生潜在的安全漏洞。如果发现敏感数据,攻击者可以使用这些机密访问这些数据。
此处建议的方法的另一种替代方法是将机密签入源代码,并与加密的团队共享。如果您学习如何利用Mozilla SOPS等工具,这可能是一个非常灵活的解决方案。