Cryptography API: Next Generation(CNG)使用梳理——非对称加密算法应用(二)非对称密钥导入并保存及公钥加密私钥解密

本文介绍了如何在CNG和BCrypt之间保存、导出和导入密钥对,特别是BCrypt创建的私钥的导出与CNG的导入。同时,展示了RSA公钥加密私钥解密的示例,包括BCRYPT_PAD_PKCS1和BCRYPT_PAD_OAEP填充方式。文中还提到了设置密钥属性以允许导出的必要步骤。

CNG中NCrypt创建的密钥对会默认会保存在本地,而BCrypt创建的密钥对并不会保存

NCrypt创建的密钥默认不能导出私钥

此篇主要聊一下,

一、如何保存BCrypt创建并导出的私钥(公钥能导入CNG但不能保存)

二、RSA公钥加密私钥解密(BCRYPT_PAD_PKCS1填充

三、导出(备份)NCrypt创建的密钥(私钥)

另附:RSA公钥加密私钥解密(BCRYPT_PAD_OAEP填充)代码

理论上基于BCrypt导出密钥的内存BLOB结构,任何其它加密导出的密钥都是可以被导入的,后面我会单独写一篇导入OpenSSL3生成的密钥(RSA和ECC)与CNG内存BLOB结构之间做转换

关于导入持久化密钥,MSDN中导入持久化密钥的流程为:

    使用 NCryptCreatePersistedKey 函数创建持久密钥。
    使用 NCryptSetProperty 函数设置键对象上的任何所需属性。
    将导入密钥 BLOB 设置为密钥上的属性,将 BLOB 类型设置为属性名称。
    使用 NCryptFinalizeKey 函数完成持久密钥导入。

此流程或许我解读有误,实际操作后没有成功,一下为我成功的流程

以RSA加密(公钥加密,私钥解密)为例,基本流程

1、生成密钥对(BCrypt)

2、加密数据

3、导出私钥

4、导入私钥(NCrypt),非私钥NCrypt不会保存

5、解密

相关函数和结构

//导入密钥函数
SECURITY_STATUS NCryptImportKey(
  [in]           NCRYPT_PROV_HANDLE hProvider,
  [in, optional] NCRYPT_KEY_HANDLE  hImportKey,
  [in]           LPCWSTR            pszBlobType,
  [in, optional] NCryptBufferDesc   *pParameterList,
  [out]          NCRYPT_KEY_HANDLE  *phKey,
  [in]           PBYTE              pbData,
  [in]           DWORD              cbData,
  [in]           DWORD              dwFlags
);

//NCryptBufferDesc结构,NCryptBufferDesc结构为BCryptBufferDesc结构的别名
typedef struct _BCryptBufferDesc {
  ULONG         ulVersion;
  ULONG         cBuffers;
  PBCryptBuffer pBuffers;
} BCryptBufferDesc, *PBCryptBufferDesc;

//BCryptBuffer结构,部分MSDN中使用NCryptBuffer来描述,实际NCryptBuffer为此结构的别名
typedef struct _BCryptBuffer {
  ULONG cbBuffer;
  ULONG BufferType;
  PVOID pvBuffer;
} BCryptBuffer, *PBCryptBuffer;

NCryptBufferDesc结构很简单

ulVersion 结构的版本
    BCRYPTBUFFER_VERSION     默认版本号。

cBuffers pBuffers数组中的元素数。

pBuffers 包含缓冲区的 BCryptBuffer 结构的数组的地址。 cBuffers 包含此数组中的元素数。

而NCryptBuffer(BCryptBuffer)就比较复杂了,根据不同应用场景,具体参数不同,此处主要填写BufferType、pvBuffer、cbBuffer,分别对应NCryptBuffer(BCryptBuffer)内容的类型、密钥名字和密钥名字长度(包含字符串最后的\0结束符)

BufferType = NCRYPTBUFFER_PKCS_KEY_NAME;//设置密钥名
pvBuffer = (PVOID)pszKeyName;
cbBuffer = (::lstrlenW(pszKeyName) + 1) * sizeof(wchar_t);//需要包含\0

实际代码如下:(只包含基本流程的代码,并未对每

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值