bentonstark/py-hsm
GitHub: bentonstark/py-hsm
一个简化 PKCS#11 标准硬件安全模块访问的 Python 封装库,让开发者无需深入掌握复杂 C API 即可完成密钥管理与加解密操作。
Stars: 58 | Forks: 18
# py-hsm
## 概述
py-hsm 模块使 Python 用户能够简化访问任何符合 PKCS#11 标准的硬件安全模块 (HSM) 或软件 API。PKCS#11 API 是由 OASIS 标准机构管理的供应商中立、开放标准 API。它为硬件安全模块 (HSM) 和 HSM PaaS 解决方案(例如 Amazon 的 CloudHSM)提供了标准的编程接口。
## 什么是 HSM?
硬件安全模块 (HSM) 是物理的电子黑盒设备,旨在提供硬件保护的加密密钥和机密的创建、管理和存储。大多数 HSM 是实际的物理设备,通过了美国和外国政府认证计划,例如美国政府的 FIPS 计划。这些计划评估特定 HSM 产品的安全性和合规性级别。
## 什么是 PKCS#11?
物理 HSM 由各种第三方供应商制造,并有多种外形规格。然而,所有主流 HSM 设备都实现了行业 OASIS 基于 C 语言的 API,称为 PKCS#11。PKCS#11 API 最初是行业事实上的标准 API,由 RSA Security 为 HSM 安全令牌开发。后来 EMC 收购了 RSA Security。收购后不久,OASIS 标准机构接管了 PKCS #11 加密令牌接口基础规范标准,并使其成为真正的行业标准 API。许多现有的软件应用程序使用 PKCS#11 API 以供应商中立的方式与各种硬件安全模块交互。尽管开发人员可以直接与供应商的 PKCS#11 API 实现交互,但该 API 非常复杂,充满了陷阱和隐患。pyhsm 和 libhsm 模块的目标是为 Python 用户提供简化的 HSM 接口,通过抽象化 PKCS#11 API 的许多痛苦复杂性而不牺牲性能。
## 支持的 HSM
py-hsm 模块已经过测试,可与以下 HSM 设备和基于软件的测试平台 HSM 一起使用。
- Gemalto SafeNet Luna SA-4
- Gemalto SafeNet Luna SA-5
- Gemalto SafeNet Luna PCIe K5/K6
- Gemalto SafeNet Luna CA-4
- SafeNet ProtectServer PCIe
- FutureX Vectera Series
- Cavium LiquidSecurity FIPS PCIe Card
- Utimaco Security Server Simulator (SMOS Ver. 3.1.2.3)
- OpenDNSSEC SoftHSM 2.2.0 (softhsm2)
## 安装先决条件
- Python 3.x
- 如果是 Python 3.3 或更低版本,则需要 enum34 ($ pip install enum34)
- libhsm.so https://github.com/bentonstark/libhsm
**pyenv** 和可选的 **virtualenv** 可用于创建隔离的 Python 3.x 环境(如果您的系统上没有 3.x)。
如果有足够的需求请求,未来版本可能会反向支持 Python 2.7.x
## 测试过的平台
- Fedora 19, 23, 24, 25
- Debian
- CentOS 6
- CentOS 7
## Pypi 安装步骤
https://pypi.python.org/pypi/py-hsm
```
$ pip install py-hsm
```
## 手动安装步骤
```
$ git clone https://github.com/bentonstark/py-hsm.git
$ cd py-hsm
$ python setup.py install
```
## 使用示例
### 登录 / 登出
```
from pyhsm.hsmclient import HsmClient
# 注意:可以使用 with 关键字来减少登录 / 登出步骤
# 下面展示的是详细方法
c = HsmClient(pkcs11_lib="/usr/lib/vendorp11.so")
c.open_session(slot=1)
c.login(pin="partition_password")
c.logout()
c.close_session()
```
### 列出插槽
```
from pyhsm.hsmclient import HsmClient
# 注意:列出 slot 信息不需要登录
with HsmClient(pkcs11_lib="/usr/lib/vendorp11.so") as c:
for s in c.get_slot_info():
print("----------------------------------------")
print(s.to_string())
```
### 列出对象
```
from pyhsm.hsmclient import HsmClient
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
for s in c.get_slot_info():
obj_list = c.get_objects()
for obj in obj_list:
print(obj.to_string())
```
### 签名
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmMech
from pyhsm.convert import bytes_to_hex
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
sig = c.sign(handle=1, data=data_to_sign, mechanism=HsmMech.SHA256_RSA_PKCS)
print(bytes_to_hex(sig))
```
### 验证
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmMech
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
result = c.verify(handle=1,
data=data_to_verify,
signature=sig,
mechanism=HsmMech.SHA256_RSA_PKCS)
print(str(result))
```
### 加密
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmMech
from pyhsm.convert import bytes_to_hex
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
ciphertext = c.encrypt(handle=aes_key_handle,
data=cleartext,
mechanism=HsmMech.AES_CBC_PAD,
iv=init_vector)
print(bytes_to_hex(ciphertext))
```
### 解密
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmMech
from pyhsm.convert import bytes_to_hex
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
cleartext = c.decrypt(handle=aes_key_handle, data=ciphertext, mechanism=HsmMech.AES_CBC_PAD, iv=init_vector)
print(bytes_to_hex(cleartext))
```
### 创建 AES 密钥
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmSymKeyGen
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
key_handle = c.create_secret_key(key_label="my_aes_key",
key_type=HsmSymKeyGen.AES,
key_size_in_bits=256,
token=True,
private=True,
modifiable=False,
extractable=False,
sign=True,
verify=True,
decrypt=True,
wrap=True,
unwrap=True,
derive=False)
print(key_handle)
```
### 创建 RSA 密钥对
```
from pyhsm.hsmclient import HsmClient
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
key_handles = c.create_rsa_key_pair(public_key_label="my_rsa_pub",
private_key_label="my_rsa_pvt",
key_length=2048,
public_exponent=b"\x01\x00\x01",
token=True,
private=True,
modifiable=False,
extractable=False,
sign_verify=True,
encrypt_decrypt=True,
wrap_unwrap=True,
derive=False)
print("public_handle: " + key_handles[0])
print("private_handle: " + key_handles[1])
```
### 创建 EC 密钥对
```
from pyhsm.hsmclient import HsmClient
from pyhsm.convert import hex_to_bytes
from pyhsm.eccurveoids import EcCurveOids
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
# NIST P-256
key_handles = c.create_ecc_key_pair(public_key_label="my_ec_pub",
private_key_label="my_ec_pvt",
curve_parameters=EcCurveOids.P256,
token=True,
private=True,
modifiable=False,
extractable=False,
sign_verify=True,
encrypt_decrypt=True,
wrap_unwrap=True,
derive=False)
print("public_handle: " + key_handles[0])
print("private_handle: " + key_handles[1])
```
### 包装密钥 (AES 使用 AES 包装)
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmMech
from pyhsm.convert import bytes_to_hex
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
my_key_handle_to_wrap = 1
my_aes_wrapping_key_handle = 2
iv = c.generate_random(size=16)
wrapped_key_bytes = c.wrap_key(key_handle=my_key_handle_to_wrap,
wrap_key_handle=my_aes_wrapping_key_handle,
wrap_key_mech=HsmMech.AES_CBC_PAD,
wrap_key_iv=iv)
print(bytes_to_hex(wrapped_key_bytes))
```
### 解包密钥 (AES 使用 AES 包装)
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmMech
from pyhsm.convert import bytes_to_hex
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
hkey = c.unwrap_secret_key(wrap_key_handle=wraping_key_handle,
wrap_key_mech=HsmMech.AES_CBC_PAD,
wrap_key_iv=iv,
key_label="my_key",
key_data=wrapped_key_bytes,
key_type=HsmSymKeyType.AES,
key_size_in_bits=key_size,
token=True,
private=True,
modifiable=False,
extractable=False,
sign=True,
verify=True,
encrypt=True,
decrypt=True,
wrap=True,
unwrap=True,
derive=False)
```
### 生成随机数
```
from pyhsm.hsmclient import HsmClient
from pyhsm.convert import bytes_to_hex
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
rnd_bytes = c.generate_random(size=16)
print(bytes_to_hex(rnd_bytes))
```
### 通过标签获取对象句柄
```
from pyhsm.hsmclient import HsmClient
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
handle = c.get_object_handle(label="my_key_label")
print(str(handle))
```
### 更改对象标签
```
from pyhsm.hsmclient import HsmClient
from pyhsm.hsmenums import HsmAttribute
from pyhsm.convert import str_to_bytes
with HsmClient(slot=1, pin="partition_password", pkcs11_lib="/usr/lib/vendorp11.so") as c:
my_key_label = 1
c.set_attribute_value(handle=my_key_label,
attribute_type=HsmAttribute.LABEL,
attribute_value=str_to_bytes("my_new_label"))
```
标签:API封装, CloudHSM, CVE, DevSecOps, FIPS, HSM, meg, OASIS标准, PKCS#11, Python, StruQ, 上游代理, 令牌, 信息安全, 加密, 安全存储, 密码学, 密钥生命周期, 开发库, 手动系统调用, 操作系统检测, 数字签名, 无后门, 漏洞扫描器, 硬件安全模块, 逆向工具