• 实验一-密码引擎-加密API研究


    实验一-密码引擎-加密API研究

    列出了几个常用密码接口的常用函数,以及函数的分类和评价

    一、Crypto API

    1、摘要

    可以按照如下顺序调用接口实现摘要:

    BOOL CryptAcquireContext (
    HCRYPTPROV* phProv,
    LPCTSTR pszContainer,
    LPCTSTR pszProvider,
    DWORD dwProvType,
    DWORD dwFlags
    )
    
    BOOL CryptCreateHash(
    HCRYPTPROV hProv,
    ALG_ID Algid,
    HCRYPTKEY hKey,
    DWORD dwFlags,
    HCRYPTHASH *phHash
    )
    

    调用此方法生成一个摘要运算的对象。hProv为上一步返回的CSP句柄;Algid为摘要算法,比如可以是CALG_SHA1;hKey和dwFlags都设置成0;phHash为返回的摘要运算对象。返回值同上。

    BOOL CryptHashData(
    HCRYPTHASH hHash,
    BYTE* pbData,
    DWORD dwDataLen,
    DWORD dwFlags
    )
    

    调用CryptHashData方法进行摘要运算。phHash为上一步返回的摘要运算对象;pbData为原文;dwDataLen为原文长度;dwFlags为0。方法返回值同上。

    BOOL CryptGetHashParam(
    HCRYPTHASH hHash,
    DWORD dwParam,
    BYTE *pbData,
    DWORD *pdwDataLen,
    DWORD dwFlags
    )
    

    调用CryptGetHashParam可以返回摘要的各种相关数据信息,这里先返回摘要的数据长度。dwParam设置为HP_HASHSIZE(0x0004);pbData为返回长度值;pdwDataLen为长度值所占字节数;dwFlags为0。调用成功后,再调用一次CryptGetHashParam方法返回摘要值。这次dwParam设置为HP_HASHVAL(0x0002);按照上一次调用返回的长度值为pbData分配空间,它返回的摘要值。

    2、 对称加密

    对称加密中常用的方式是根据用户输入的口令加解密文档,即基于口令派生出加解密密钥,调用步骤如下:

    CryptAcquireContext //返回CSP句柄,参数设置与摘要运算时一致。
    CryptCreateHash //生成摘要运算对象。
    CryptHashData //生成摘要。pbData为调用加密功能的上位程序输入的加密口令。
    BOOL CryptDeriveKey(
    HCRYPTPROV hProv,
    ALG_ID Algid,
    HCRYPTHASH hBaseData,
    DWORD dwFlags,
    HCRYPTKEY* phKey
    )
    

    派生密钥。Algid为加密算法,比如CALG_DES、CALG_3DES什么的;hBaseData就是上一步返回的摘要对象;dwFlags是密钥类型,如果调用的CSP没有特别要求,设置为0;phKey为返回的密钥对象。
    也可以调用CryptGenKey生成一个会话密钥,用来加密数据,而这个会话密钥可以使用数据接收者的公钥加密传输。不过这种方式实际已经包含在非对称加解密中,因此很少直接拿来用。

    BOOL CryptSetKeyParam(
    HCRYPTKEY hKey,
    DWORD dwParam,
    BYTE* pbData,
    DWORD dwFlags
    )
    

    3、 对称解密

    对称解密与加密相对应,调用顺序和参数设置基本一致。

    CryptAcquireContext
    CryptCreateHash
    CryptHashData
    CryptDeriveKey
    CryptSetKeyParam
    BOOL CryptDecrypt(
    HCRYPTKEY hKey,
    HCRYPTHASH hHash,
    BOOL Final,
    DWORD dwFlags,
    BYTE *pbData,
    DWORD *pdwDataLen
    )
    

    此方法前四个参数意义与CryptEncrypt相同;pbData输入密文,调用后输出明文;pdwDataLen输入为密文长度,调用后输出明文长度。此方法返回值与CryptEncrypt一致。
    另外,对同一数据的加密和解密可以采用不同的分块方式。比如,加密时不分块,解密时分块,不影响最后的解密结果。

    二、 PKCS#11

    1、 加密函数

    Cryptoki 为加密数据提供了以下的函数:

    C_EncryptInit
    
    CK_DEFINE_FUNCTION(CK_RV, C_EncryptInit)(
      CK_SESSION_HANDLE hSession,
      CK_MECHANISM_PTR pMechanism,
      CK_OBJECT_HANDLE hKey
     );
    

    C_EncryptInit 初始化一个加密操作。hSession 是对话的句柄;pMechanism 指向加密机制; hKey 是加密密钥的句柄。

    加密密钥的CKA_ENCRYPT 属性——说明密钥是否支持加密——必须为TRUE。

    C_Encrypt
    
    CK_DEFINE_FUNCTION(CK_RV, C_Encrypt)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pData,
      CK_ULONG ulDataLen,
      CK_BYTE_PTR pEncryptedData,
      CK_ULONG_PTR pulEncryptedDataLen
     );
    

    C_Encrypt加密单部分数据。HSession是对话句柄;pData指向数据;ulDataLen是数据字节的长度;pEncryptedData指向接收加密数据的单元;pulEncryptedDatedLen指向包含加密数据字节长度的单元。

    C_EncryptUpdate
    
    CK_DEFINE_FUNCTION(CK_RV, C_EncryptUpdate)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pPart,
      CK_ULONG ulPartLen,
      CK_BYTE_PTR pEncryptedPart,
      CK_ULONG_PTR pulEncryptedPartLen
     );
    
    C_EncryptFinal
    CK_DEFINE_FUNCTION(CK_RV, C_EncryptFinal)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pLastEncryptedPart,
      CK_ULONG_PTR pulLastEncryptedPartLen
    );
    

    2、解密函数

    Cryptoki 为解密数据提供了以下的函数:

    ¨   C_DecryptInit
    
    CK_DEFINE_FUNCTION(CK_RV, C_DecryptInit)(
      CK_SESSION_HANDLE hSession,
      CK_MECHANISM_PTR pMechanism,
      CK_OBJECT_HANDLE hKey
     );
    

    C_DecryptInit 启动一项加密操作。hSession 是对话句柄;pMechanism 指向解密机制;hKey 是解密密钥的句柄。

    解密密钥的CKA_DECRYPT属性,——说明密钥是否支持解密——必须为TRUE。

    ¨   C_Decrypt
    
    CK_DEFINE_FUNCTION(CK_RV, C_Decrypt)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pEncryptedData,
      CK_ULONG ulEncryptedDataLen,
      CK_BYTE_PTR pData,
      CK_ULONG_PTR pulDataLen
     );
    

    C_Decrypt 解密单部分中的加密数据。hSession 是对话句柄;pEncryptedData 指向加密数据;ulEncryptedDataLen是加密数据的长度;pData 指向接收恢复数据的单元;pulDataLen 指向包含恢复数据长度的单元。

    ¨   C_DecryptUpdate
    
    CK_DEFINE_FUNCTION(CK_RV, C_DecryptUpdate)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pEncryptedPart,
      CK_ULONG ulEncryptedPartLen,
      CK_BYTE_PTR pPart,
      CK_ULONG_PTR pulPartLen
     );
    

    C_DecryptUpdate 继续一项多部分的解密操作,处理另一个加密数据部分。hSession 是数据句柄;pEncryptedPart 指向加密数据部分;ulEncryptedPartLen 是加密数据部分的长度;pPart 指向接收恢复数据部分的单元;pulPartLen 指向包含恢复的数据部分的长度。

    ¨   C_DecryptFinal
    
    CK_DEFINE_FUNCTION(CK_RV, C_DecryptFinal)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pLastPart,
      CK_ULONG_PTR pulLastPartLen
     );
    

    C_DecryptFinal结束多部分解密操作。hSession 是对话句柄;pLastPart 指向接收最终恢复数据部分的单元,如果有的话;pulLastPartLen 指向包含最后恢复的数据部分的长度。

    3、 消息摘要函数

    Cryptoki 为摘要数据提供了以下的函数:

    ¨   C_DigestInit
    
    CK_DEFINE_FUNCTION(CK_RV, C_DigestInit)(
      CK_SESSION_HANDLE hSession,
      CK_MECHANISM_PTR pMechanism
     );
    

    C_DigestInit预置消息摘要操作。hSession 是对话句柄;pMechanism 指向摘要机制。

    调用C_DigestInit 后,应用可以调用C_Digest 摘要单部分中的数据,或者先调用C_DigestUpdate 零次或多次,接着调用C_DigestFinal 来摘要多部分中的数据。消息摘要操作是现用的,直到应用调用C_DigestC_DigestFinal 确实获得最后的密文。要处理另外的数据(单部分或多部分),应用必须再次调用C_DigestInit

    ¨   C_DigestUpdate
    
    CK_DEFINE_FUNCTION(CK_RV, C_DigestUpdate)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pPart,
      CK_ULONG ulPartLen
     );
    

    C_DigestUpdate 继续多部分消息摘要操作,处理另一个数据部分。hSession 是对话句柄;pPart 指向数据部分;ulPartLen 是数据部分的长度。

    ¨   C_DigestFinal
    
    CK_DEFINE_FUNCTION(CK_RV, C_DigestFinal)(
      CK_SESSION_HANDLE hSession,
      CK_BYTE_PTR pDigest,
      CK_ULONG_PTR pulDigestLen
     );
    

    C_DigestFinal 结束多部分消息摘要操作,返回消息摘要。hSession 是对话句柄;pDigest 指向接收消息摘要的单元;pulDigestLen 指向包含消息摘要长度的单元。

    三、GMT 00116-2012

    1、概述

    密码服务函数提供对称算法运算、非对称算法运算、密码杂凑运算、密钥管理、消息鉴别码计算等功能。密码服务系列函数如表21所示:

    表1 密码服务系列函数

    函数名称 功能
    SKF_GenRandom 生成随机数
    SKF_GenExtRSAKey 生成外部RSA密钥对
    SKF_GenRSAKeyPair 生成RSA签名密钥对
    SKF_ImportRSAKeyPair 导入RSA加密密钥对
    SKF_RSASignData RSA签名
    SKF_RSAVerify RSA验签
    SKF_RSAExportSessionKey RSA生成并导出会话密钥
    SKF_ExtRSAPubKeyOperation RSA外来公钥运算
    SKF_ExtRSAPriKeyOperation RSA外来私钥运算
    SKF_GenECCKeyPair 生成ECC签名密钥对
    SKF_ImportECCKeyPair 导入ECC加密密钥对
    SKF_ECCSignData ECC签名
    SKF_ECCVerify ECC验签
    SKF_ECCExportSessionKey ECC生成并导出会话密钥
    SKF_ExtECCEncrypt ECC外来公钥加密
    SKF_ExtECCDecrypt ECC外来私钥解密
    SKF_ExtECCSign ECC外来私钥签名
    SKF_ExtECCVerify ECC外来公钥验签
    SKF_GenerateAgreementDataWithECC ECC生成密钥协商参数并输出
    SKF_GenerateKeyWithECC ECC计算会话密钥
    SKF_GenerateAgreementDataAndKeyWithECC ECC产生协商数据并计算会话密钥
    SKF_ExportPublicKey 导出公钥
    SKF_ImportSessionKey 导入会话密钥
    SKF_SetSymmKey 明文导入会话密钥
    SKF_EncryptInit 加密初始化
    SKF_Encrypt 单组数据加密
    SKF_EncryptUpdate 多组数据加密
    SKF_EncryptFinal 结束加密
    SKF_DecryptInit 解密初始化
    SKF_Decrypt 单组数据解密
    SKF_DecryptUpdate 多组数据解密
    SKF_DecryptFinal 结束解密
    SKF_DigestInit 密码杂凑初始化
    SKF_Digest 单组数据密码杂凑
    SKF_DigestUpdate 多组数据密码杂凑
    SKF_DigestFinal 结束密码杂凑
    SKF_MacInit 消息鉴别码运算初始化
    SKF_Mac 单组数据消息鉴别码运算
    SKF_MacUpdate 多组数据消息鉴别码运算
    SKF_MacFinal 结束消息鉴别码运算
    SKF_CloseHandle 关闭密码对象句柄

    2、生成随机数

    函数原型 ULONG DEVAPI SKF_GenRandom (DEVHANDLE hDev, BYTE *pbRandom, ULONG ulRandomLen)
    功能描述 产生指定长度的随机数。
    参数 hDev [IN] 设备句柄。
    pbRandom [OUT]返回的随机数。
    ulRandomLen [IN] 随机数长度。
    返回值 SAR_OK: 成功。 其他: 错误码。

    3、生成外部RSA密钥对

    函数原型 ULONG DEVAPI SKF_GenExtRSAKey (DEVHANDLE hDev, ULONG ulBitsLen, RSAPRIVATEKEYBLOB *pBlob)
    功能描述 由设备生成RSA密钥对并明文输出。
    参数 hDev [IN]设备句柄。
    ulBitsLen [IN] 密钥模长。
    pBlob [OUT] 返回的私钥数据结构。
    返回值 SAR_OK: 成功。 其他: 错误码。
    备注: 生成的私钥只用于输出,接口内不做保留和计算。

    4、生成RSA签名密钥对

    函数原型 ULONG DEVAPI SKF_GenRSAKeyPair (HCONTAINER hContainer, ULONG ulBitsLen , RSAPUBLICKEYBLOB *pBlob)
    功能描述 生成RSA签名密钥对并输出签名公钥。
    参数 hContainer [IN] 容器句柄。
    ulBitsLen [IN] 密钥模长。
    pBlob [OUT] 返回的RSA公钥数据结构。
    返回值 SAR_OK: 成功。 其他: 错误码。
    备注 权限要求:需要用户权限。

    5、导入RSA加密密钥对

    函数原型 ULONG DEVAPI SKF_ImportRSAKeyPair ( HCONTAINER hContainer, ULONG ulSymAlgId, BYTE *pbWrappedKey, ULONG ulWrappedKeyLen, BYTE *pbEncryptedData, ULONG ulEncryptedDataLen)
    功能描述 导入RSA加密公私钥对。
    参数 hContainer [IN] 容器句柄。
    ulSymAlgId [IN] 对称算法密钥标识。
    pbWrappedKey [IN] 使用该容器内签名公钥保护的对称算法密钥。
    ulWrappedKeyLen [IN] 保护的对称算法密钥长度。
    pbEncryptedData [IN] 对称算法密钥保护的RSA加密私钥。私钥的格式遵循PKCS #1 v2.1: RSA Cryptography Standard中的私钥格式定义。
    ulEncryptedDataLen [IN] 对称算法密钥保护的RSA加密公私钥对长度。
    返回值 SAR_OK: 成功。 其他: 错误码。
    备注 权限要求:需要用户权限。

    6、RSA签名

    函数原型 ULONG DEVAPI SKF_RSASignData(HCONTAINER hContainer, BYTE *pbData, ULONG ulDataLen, BYTE *pbSignature, ULONG *pulSignLen)
    功能描述 使用hContainer指定容器的签名私钥,对指定数据pbData进行数字签名。签名后的结果存放到pbSignature缓冲区,设置pulSignLen为签名的长度。
    参数 hContainer [IN] 用来签名的私钥所在容器句柄。
    pbData [IN] 被签名的数据。
    ulDataLen [IN] 签名数据长度,应不大于RSA密钥模长-11。
    pbSignature [OUT] 存放签名结果的缓冲区指针,如果值为NULL,用于取得签名结果长度。
    pulSignLen [IN,OUT] 输入时表示签名结果缓冲区大小,输出时表示签名结果长度。
    返回值 SAR_OK: 成功。 其他: 错误码。
    备注 权限要求:需要用户权限。

    7、RSA验签

    函数原型 ULONG DEVAPI SKF_RSAVerify (DEVHANDLE hDev , RSAPUBLICKEYBLOB* pRSAPubKeyBlob, BYTE *pbData, ULONG ulDataLen, BYTE *pbSignature, ULONG ulSignLen)
    功能描述 验证RSA签名。用pRSAPubKeyBlob内的公钥值对待验签数据进行验签。
    参数 hDev [IN] 设备句柄。
    pRSAPubKeyBlob [IN] RSA公钥数据结构。
    pbData [IN] 待验证签名的数据。
    ulDataLen [IN] 数据长度,应不大于公钥模长-11。
    pbSignature [IN] 待验证的签名值。
    ulSignLen [IN] 签名值长度,必须为公钥模长。
    返回值 SAR_OK: 成功。 其他: 错误码。

    一、尝试使用龙脉


    运行错误...看不懂代码..

  • 相关阅读:
    vue.js环境配置步骤及npm run dev报错解决方案
    消息处理之performSelector
    iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
    iOS手机号正则表达式并实现344格式 (正则的另一种实现方式)
    IOS开发——正则表达式验证手机号、密码
    iOS网络请求之---GET和POST
    CLLocation
    ios本地文件内容读取,.json .plist 文件读写
    UITableViewCell的4种样式
    iOS开发通过代码方式使用AutoLayout (NSLayoutConstraint + Masonry)
  • 原文地址:https://www.cnblogs.com/yanglao/p/14701381.html
Copyright © 2020-2023  润新知