Python-使用U盾完成数据的加解密(使用国密算法SKF接口)


Python-使用U盾完成数据的加解密(使用国密算法SKF接口)

如果身边有银行的U盾,或者其他Ukey产品,可以使用这些产品完成对数据的加解密,针对个人的敏感数据进行加密处理。

1-涉及的内容

  • 使用的python库:ctypes

作用:是Python的外部函数库。提供与 C语言兼容的数据类型,并允许调用 DLL 或共享库中的函数。

  • 使用的Ukey:文鼎创的一款Key。

与Ukey使用会有配套的驱动程序(管理工具),安装之后会在【C:\Windows\System32】释放对应dll库文件,使用ctypes库调用这个dll文件。

  • dll的接口函数

现在各厂家的Ukey一般都支持国密算法(SKF),使用SKF中的函数,实现数据的加解密。了解到文鼎创这边提供的SKF的函数中有使用ECC非对称算法完成数据加解密。本文内容就是用里面的ECC算法完成数据分非对称加解密。

2-动态库涉及的函数,及结构体

2.1 相关结构体

  • ECC公钥结构

C中的结构体声明:

typedef struct Struct_ECCPUBLICKEYBLOB{
   
ULONG BitLen;
BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8];
BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8];
}ECCPUBLICKEYBLOB, *PECCPUBLICKEYBLOB;
//ECC_MAX_XCOORDINATE_LEN为ECC算法X坐标的最大长度;
//ECC_MAX_YCOORDINATE_LEN为ECC算法Y坐标的最大长度。

Python的ctype库声明:

# ECC 公钥结构体
class Struct_ECCPUBLICKEYBLOB(Structure):
    _fields_ = [("BitLen", c_ulong),
                ("XCoordinate", c_ubyte * 64),
                ("YCoordinate", c_ubyte * 64)]
  • 密文数据结构

C中的结构体声明:

a) 类型定义
typedef struct Struct_ECCCIPHERBLOB{
   
BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; 
BYTE YCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; 
BYTE HASH[32]; 
ULONG CipherLen;
BYTE Cipher[1]; 
} ECCCIPHERBLOB, *PECCCIPHERBLOB;

Python的ctype库声明:

# 密文数据结构
class Struct_ECCCIPHERBLOB(Structure):
    _fields_ = [("XCoordinate", c_ubyte * 64),
                ("YCoordinate", c_ubyte * 64),
                ("HASH", c_ubyte * 32),
                ("CipherLen", c_ulong),
                ("Cipher", c_ubyte * 1)]

2.2 相关函数

/*设备相关*/
//枚举设备
ULONG DEVAPI SKF_EnumDev(BOOL bPresent, LPSTR szNameList, ULONG *pulSize); 
//连接设备
ULONG DEVAPI SKF_ConnectDev (LPSTR szName, DEVHANDLE *phDev);
//断开连接
ULONG DEVAPI SKF_DisConnectDev (DEVHANDLE hDev);

/*应用相关*/
//枚举应用
ULONG DEVAPI SKF_EnumApplication(DEVHANDLE hDev, LPSTR szAppName,ULONG *pulSize);
//打开应用
ULONG DEVAPI SKF_OpenApplication(DEVHANDLE hDev, LPSTR szAppName,HAPPLICATION *phApplication);
//关闭应用
ULONG DEVAPI SKF_CloseApplication(HAPPLICATION hApplication);

/*容器相关*/
//枚举容器
ULONG DEVAPI SKF_EnumContainer(HAPPLICATION hApplication, LPSTR szContainerName,ULONG *pulSize);
//打开容器
ULONG DEVAPI SKF_OpenContainer(HAPPLICATION hApplication,LPSTR szContainerName,HCONTAINER *phContainer);
//关闭容器
ULONG DEVAPI SKF_CloseContainer(HCONTAINER hContainer);

/*密码服务*/
//导出公钥
ULONG DEVAPI SKF_ExportPublicKey (HCONTAINER hContainer, BOOL bSignFlag,BYTE* pbBlob,ULONG* pulBlobLen);
//ECC外来公钥加密
ULONG DEVAPI SKF_ExtECCEncrypt (DEVHANDLE hDev, ECCPUBLICKEYBLOB* pECCPubKeyBlob,BYTE* pbPlainText, ULONG ulPlainTextLen, PECCCIPHERBLOB pCipherText);
//私钥解密
ULONG DEVAPI SKF_ECCDecrypt(HCONTAINER hContainer, BOOL bSign, const ECCCIPHERBLOB* pCipherText, BYTE *pbData, ULONG *pdwDataLen);


/*注:私钥解密接口应该是厂商的扩展接口,如果不是wdc的key,可能提供的驱动没有这个函数,那么可以使用对称算法对数据进行加解密,或者使用SKF_ExtECCDecrypt(ECC外来私钥解密)*/
/*
参数说明:
1:BOOL bPresen:为TRUE表示取当前设备状态为存在的设备列表。为FALSE表示取当前驱动支持的设备列表。
2:ULONG *pulSize: 输入时表示设备名称列表的缓冲区长度,输出时表示(一般是)前一个参数(如szNameList)需要获取的,所占用的空间大小。
3:DEVHANDLE phDev:设备的句柄
4:HAPPLICATION hApplication:应用的句柄
5:HCONTAINER hContainer:容器的句柄
6:BOOL bSignFlag:TRUE,签名证书;FALSE,加密证书
7:ECCPUBLICKEYBLOB* pECCPubKeyBlob:公钥类型参数
8:ECCCIPHERBLOB* pCipherText:待解密的数据类型
*/

3-Python实现

要求:Ukey中有SM2容器,使用SM2加密密钥对,且默认在第一个容器名中,如果不是,请自行修改。

实现内容:

  • 使用ctype先定义好所需要到的结构体

  • 创建一个类,实现加解密的过程

    • 在类中在初始化中初始化句柄
    • 在对象结束的时候释放掉对应的句柄
    • 将句柄的获取放在一个函数中,获取句柄。
    • 将加密结果转换为Hex字符串形式。
    • 传入Hex密文字符进行解密。
  • 辅助函数:

    • def __IntList_ToHexStr(self, int_list):将int类型的列表转为Hex字符串
    • def __HexStr_ToIntList(self, str_hex):Hex字符串转为int类型的列表
    • def StrHex_ToCipherText(self, str_hex):Hex密文字符串转为密文结构体
    • def CipherText_ToStrHex(self, cipher_text):将密文结构体转为Hex密文字符串
  • 主要函数:

    • def ECCEncrypt(self, plain_text):返会的是密文结构类型数据
    • def ECCEncrypt_Hex(self, plain_text):返会的是密文Hex字符串
    • def ECCDecrypt(self, cipher_text):传入密文结构体进行解密
    • def ECCDecrypt_Hex(self, cipher_hex):传入密文Hex字符串进行解密
    • def VerifyPIN(self, user_pin):验证UkeyPIN
  • 其他函数:获取句柄相关,比较简单。

完整代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
"""
@Project :PythonStudy 
@File :MySkfClass.py
@IDE  :PyCharm 
@Author :羽丶千落
@Date :2022-10-21 19:55 
@content:
"""
from ctypes import *

# ECC 公钥结构体
class Struct_ECCPUBLICKEYBLOB(Structure):
    _fields_ = [("BitLen", c_ulong),
                ("XCoordinate", c_ubyte * 64),
                ("YCoordinate", c_ubyte * 64)]

# 密文数据结构
class Struct_ECCCIPHERBLOB(Structure):
    _fields_ = [("XCoordinate", c_ubyte * 64),
                
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值