实验一-密码引擎-加密API研究
实验一-密码引擎-加密API研究
密码引擎API的主要标准和规范包括:
1 微软的Crypto API
2 RAS公司的PKCS#11标准
3 中国商用密码标准:GMT 0016-2012 智能密码钥匙密码应用接口规范,GMT 0018-2012密码设备应用接口规范等
研究以上API接口,总结他们的异同,并以龙脉GM3000Key为例,写出调用不同接口的代码,提交博客链接和代码链接。
内容:
0 查找各种标准的原始文档,研究学习(至少包含Crypto API,PKCS#11,GMT 0016-2012,GMT 0018-2012)(5分)
1 总结这些API在编程中的使用方式(5分)
2 列出这些API包含的函数,进行分类,并总结它们的异同(10分)
3 以龙脉GM3000Key为例,写出调用不同接口的代码(Crypto API,PKCS#11,SKF接口),把运行截图加入博客,并提供代码链接(10分)
CryptoAPI
CryptoAPI 是微软提供的一组加密函数。其功能是为应用程序开发者提供在 Win32环境下使用加密、验证等安全服务时的标准加密接口。CryptoAPI 处于应用程序和CSP (CryptographicService Provider)之间。
CryptoAPI 的组成
CryptoAPI由简单消息函数(Simplified Message Functions)、低层消息函数(Low-level MessageFunctions)、基本加密函数(Base Cryptographic Functions)、证书编解码函数(Certificate EncodelDecode Functions)和证书库管理函数(Certificate Store Functions)5部分组成。其中前三者可用于对敏感信息进行加密或签名处理,从而保证网络传输信息的保密、防篡改、防抵赖等;后两者是对证书的操作,实现身份的认证。
密码服务提供者 CSP函数
CryptoAPI 的密码服务提供者函数主要包括6个函数。连接或断开 CSP函数CryptAcquireContext、CryptReleaseContext,枚举CSP函数 CryptEnumProviders,获得或设置默认CSP函数CryptGetDefaultProvider、CryptSetProvider,获取或设置CSP参数函数CryptGetProvParam、CryptSetProvParam。
1.接CSP函数CryptAcquireContext
函数功能:连接CSP,获得指定CSP的密钥容器的句柄。函数定义:
BOOL WINAPI CryptAcquireContext(HCRYPTPROV *phProv,
LPCTSTR pszContainer,
LPCTSTRpszProvider,
DWORD.dwProvType,
DWORD dwFlags);
参数说明:
phProv: [OUT] CSP句柄指针。
pszContainer:[IN]密钥容器名称,指向密钥容器的字符串指针。如果dwFlags为CRYPTVERIFYCONTEXT,pszContainer必须为NULL。
pszProvider:[IN]指向CSP名称的字符串指针。如果为NULL,就使用默认的 CSP。dwProvType:[IN] CSP类型。
2.枚举CSP函数CryptEnumProviders
BOOL WINAPI CryptEnumProviders(
DWORD dwIndex,
DWORD *pdwReserved,
DWORD dwFlags,
DWORD *pdwProvType,
LPTSTR pSzProvName,
DWORD *pcbProvName);
参数说明:
dwIndex:[IN]枚举下一个CSP的索引。
pdwReserved:[IN]保留参数,必须为NULL。pdwProvType:[OUT] CSP的类型。
pszProvName:[OUT]指向接收CSP名称的缓冲区字符串指针。pcbProvName:[IN/OUT]指出pszProvName字符串的大小。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以使用GetLastError()函数获得错误码。
3.获得默认CSP函数CryptGetDefaultProvider
BOOL WINAPI CryptGetDefaultProvider (
DWORD dwProvType,
DWORD *pdwReserved,
DWORD dwFlags,
LPTSTR pszProvName,
DWORD *pcbFrovName
};
参数说明:
dwProvType:[IN] CSP类型。
pdwReserved:. [IN]保留参数,必须为NULL。dwFlags:[IN]标志位。
pszProvName: [OUT] 指向接收CSP名称的缓冲区字符串指针。pcbProvName: [IN/OUT]指出pszProvName字符串的大小。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过 GetLastError()函数获得错误码。
4.设置默认CSP函数CryptSetProvider
BOOL WINAPI CryptsetProvider(
LPCTSTRpszProvName,
DWORD dwProvType
};
参数说明:
dwProvType:[IN]CSP类型。
pszProvName:[IN]CSP名称的缓冲区字符串指针。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
5.获得CSP参数属性函数CryptGetProvParam
BOOL WINAPI CryptGetProvParam(
HCRYPTPROV hProv,
DWORD dwParam,
BYTE *pbData,
DWORD *pdwDataLen,DWORD dwFlags
};
参数说明:
hProv:[IN] CSP句柄。
dwParam:[IN]指定查询的参数。
可选择的值和意义
pbData:[OUT] 指向接收数据的缓冲区指针。
pdwDataLen: [IN/OUT]指出pbData数据长度。
dwFlags:[IN]标志位。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastErrorO)函数获得错误码。
6.设置CSP参数函数CryptSetProvParam
BOOL WINAPI CryptSetProvParam(
HCRYPTPROV hProv,
DWORD dwParam,
BYTE *pbData,
DWORD dwFlags
};
hProv: [IN] CSP句柄。
dwParam:[IN]指定设置的参数。
可选择的值和意义
pbData:[IN]指向设置数据的缓冲区指针。dwFlags:[IN]标志位。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
7.断开CSP函数 CryptReleaseContext
BOOL WINAPT CryptReleaseContext(
HCRYPTPROV hProv,
DWORDdwFlags
);
参数说明:
hProv :[IN] CSP句柄。
dwFlags: [IN]标志位,保留参数,必须为0。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastErrorO)函数获得错误码。
密钥的产生和交换函数
CryptoAPI密钥产生和交换函数主要有生成密钥函数 CryptGenKey、派生密钥函数CryptDeriveKey、销毁密钥函数CryptDestoryKey、夏制出钥图效 TypLDupalcaeKey、Vuuot四数CryptExportKey、导入密钥函数CryptImportKey、获得密钥参效函效UrypietKeyraran、以且密钥参数函数 CryptSetKeyParam、产生随机函数 CryptGenRandom。
1.生成函数 CryptGenKey
BOOL WINAPI CryptGenKey (
HCRYPTPROV hProv,
ALG_ID Algid,
DWORD dwFlags,
HCRYPTKEY *phKey
);
参数说明:
phProv:[IN] CSP句柄指针。
Algid:[IN]密码算法标示。
Algid支持的参数
dwFlags: [IN]标志位,指定生成密钥的参数,如对称密钥的长度,RSA密钥的长度。phKey:[OUT] 新产生的密钥句柄。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以使用GetLastError()函数获得错误码。
2.派生密钥函数CryptDeriveKey
函数功能:根据基础数据派生一对称密钥(会话密钥)。
BOOL WINAPI CryptDeriveKey (
HCRYPTPROV hProv,
ALG ID Algid,
HCRYPTHASH hBaseData,
DWORD dwFlags,
HCRYPTKEY *phKey
};
参数说明:
phProv: [IN] CSP句柄指针。Algid:[IN]密码算法标识。
hBaseData:[IN]基础数据的摘要句柄。dwFlags:[IN]标志位。
phKey: [IN/OUT] 新产生的会话密钥句柄。
3.销毁密钥函数CryptDestroyKey
BOOL WINAPI Crypt DestroyKey (
HCRYPTKEY hKey
);
hKey:[IN]密钥句柄。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
4.复制密钥函数CryptDuplicateKey
函数功能:复制一个密钥。产生一个密钥的铂贝,包括其状态。
BOOL WINAPI Crypt DuplicateKey(
HCRYPTKEY hKey,
DWORD *pdwReservea,
DWORD dwFlags,
HCRYPTKEY *phKey
);
参数说明:
hKey:[IN]密钥句柄。
pdwReserved:[IN]保留参数,必须为NULL。dwFlags:[IN]保留参数,必须为0。
phKey:[OUT]复制后的密钥句柄。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以使用GetLastError()函数获得错误码。
5.导出密钥函数CryptExportKey
函数功能:从 CSP导出密钥或密钥对。函数定义:
BOOL WINAPICryptExportKey (
HCRYPTKEY hKey,版
HCRYPTKEY hExpKey,
DWORD dwBlobType,DWORD dwFlags,
BYTE*pbData,
DWORD *pdwDataLen
);
hKey:[IN] 密钥句柄。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
6.导入密钥函数CryptlmportKey
函数功能:把 BLOB数据导入的CSP。该函数可以导入会话密钥、公钥、或者公/私钥对。
函数定义:
BOOL WINAPI Crypt ImportKey(
HCRYPTPROV hProv,
BYTE *pbData,
DWORD dwDataLen,HCRYPTKEY hPubKey,DWORD dwFlags,
HCRYPTKEY *phKey);
参数说明:
hProv:[IN] CSP句柄。pbData: [IN] BLOB数据。
dwDataLen:[IN] BLOB数据长度。
hPubKey:[N]此函数的意义根据CSP的类型以及导入的BLOB数据的类型不同而不同。如果BLOB 数据是由交换密钥加密的,该参数就是交换密钥的句柄。
如果BLOB数据是由会话密钥加密的,该参数就是会话密钥的句柄。如果BLOB数据没有被加密,则该参数为NULL。
dwFlags:[IN]标志位。
phKey:[IN]导入密钥的句柄。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
数据的加密和解密函数
CryptoAPI利用CryptEncrypt函数实现数据加密,利用CryptDecrypt实现数据解密。调用这2个函数前必须指定一个密钥,这个密钥可以由 CryptGenKey、CryptDeriveKey或CryptImportKey产生。也可用CryptSetKeyParam函数指定额外的加密参数。
1.数据加密函数CryptEncrypt
函数功能:使用hKey 指定的密钥和算法加密数据。函数定义:
BOOL WINAPI CryptEncrypt(
HCRYPTKEY hKey,
HCRYPTHASH hHash,BOOL Final,
DWORD dwFlags,BYTE *pbData,
DWORD *pdwDataLen,DWORD dwBufLen
);
参数说明:
hKey:[IN]密钥句柄。该句柄指定了加密的密钥和算法。
hHash:[IN] HASH对象的句柄。如果数据需要同时被哈希和加密,hHash则指定了哈希对象。
Final:[IN]指出是否是最后一次加密操作。
dwFlags:[IN]保留参数。
pbData:[IN/OUT]作为输入参数为被加密数据的缓冲区指针,其长度由dwBufLen指定。作为输出参数为加密后的数据缓冲区指针,其长度由pdwDataLen指定。此函数会把pbData数据加密后的结果覆盖到pbData缓冲区中。
pdwDataLen:[OUT] 加密后的数据长度。
dwBufLen:[IN]被加密数据的长度。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
2.数据解密函数CryptDecrypt
函数功能:使用hKey指定的密钥和算法对加密数据解密。函数定义:
BOOL WINAPI Crypt Decrypt (
HCRYPTKEY hKey,
HCRYPTHASH hHash,
BOOL Final,
DWORD dwFlags,
BYTE *pbData,
DWORD *pdwDataLen
);
参数说明:
hKey:[IN]密钥句柄。该句柄指定了解密的密钥和算法。
hHash: [IN HASH对象的句柄。如果数据需要同时被解密和哈希,hHash则指定了哈希对象。
Final:[IN]指出是否是最后一次解密操作。时深个欢国药dwFlags:[IN]保留参数。
pbData: [IN/OUT]作为输入参数为被解密数据的缓冲区指针,其长度由pdwDataLen指定。作为输出参数为解密后的明文数据缓冲区指针,其长度由pdwDataLen 指定。此函数会把pbData数据解密后的结果覆盖到pbData缓冲区中。
pdwDataLen:[IN/OUT]解密前为被解密数据长度,解密后为明文数据长度。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过 GetLastError()函数获得错误码。
哈希和数字签名函数
CryptoAPI提供的哈希和数字签名函数包括创建哈希函数CryptCreateHash、销毁哈希CryptDestroyHash、复制哈希函数CryptDuplicateHash、获得哈希参数函数CryptGetHashParam、设置哈希参数函数CryptSetHashParam、哈希会话密钥函数CryptHashSessionKey、哈希数据函数CryptHashData、对哈希签名函数CryptSignHash和对哈希验证签名函数CryptVerifySignature.
1.创建哈希函数CryptCreateHash
函数功能:创建哈希。函数定义:
BOOL WINAPI CryptCreateHash(
HCRYPTPROV hProv,
ALG_ID Algid,
HCRYPTKEY hKey,DWORD dwFlags,
HCRYPTHASH *phHash
);
参数说明:
hProv: [IN] CSP句柄。Algid:[IN指定哈希算法。
hKey: [N]如果哈希算法是密钥哈希,如HMAC或 MAC算法,就用此密钥句柄传递密钥。对于非密钥算法,此参数为NULL。
dwFlags:[IN]保留参数。
phHash:[OUT] 输出的哈希对象指针。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
2.肖毁哈希CryptDestroyHash
BOOL WINAPI CryptDestroyHash (
HCRYPTHASH hHash
);
参数说明:
hHash:[IN]哈希对象句柄。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过GetLastError()函数获得错误码。
3. 复制哈希函数CryptDuplicateHash
函数功能:复制一个哈希对象。
函数定义:
BOOL WINAPI CryptDuplicateHash(
HCRYPTHASH hHash,
DWORD *pdwReserved,DWORD dwFlags,
HCRYPTHASH *phHash);
参数说明:
hHash:[IN]哈希对象句柄。
pdwReserved:[IN]保留参数,必须为0。dwFlags:[IN]保留参数。
phHash:[OUT]输出的哈希对象句柄指针。
返回值:操作成功返回TRUE,否则返回FALSE。出错可以通过 GetLastError()函数获得错误码。
证书和证书库函数
CryptoAPI 证书和证书库函数主要包括打开证书库函数 CertOpenStore、关闭证书库函数CertCloseStore、从证书库枚举证书函数 CertEnumCertificatesInStore、从证书库查找证书函数CertFindCertificateInStore、创建证书句柄函数 CertCreateCertificateContext、释放证书句柄函数CertFreeCertificateContext、获得证书句柄属性函数CertGetCertificateContextProperty、设置证书句柄属性函数CertSetCertificateContextProperty 和获得证书主题名称函数CertGetNameString.
1.打开证书库函数CertOpenStore
函数功能:根据证书库类型,打开证书库。函数定义:
HCERTSTORE WINAPI CertOpenstore(
LPCSTR 1pszStoreProvider,
DWORD dwMsgAndCertEncodingType,HCRYPTPROV hCryptProv,
DWORD dwFlags,
const void *pvPara
};
参数说明:
lpszStoreProvider:[IN]指定证书库的类型。可选参数如表17.1所示
dwMsgAndCertEncodingType:[N]指定证书的编码类型,通常为X509_ASN_ENCODINGPKCS 7_ASN_ ENCODING。
2.关闭证书库函数 CertCloseStore
函数功能:关闭证书库。函数定义:
BOOL WINAPI CertCloseStore(
HCERTSTORE hCertStore,
DWORD dwFlags
);
参数说明:
hCertStore: [IN]证书库句柄。
dwFlags:[IN]标志位。
可选的参数
返回值:操作成功返回TRUE,否则返回NULL。出错可以使用GetLastError()函数获得错误码。
RAS公司的PKCS#11标准
PKCS#11
架构
会话状态
对象
机制
根据机制标记,可以分为几类:
CKF_ENCRYPT:加密类
CKF_DECRYPT:解密类
CKF_DIGEST:摘要类
CKF_SIGN:签名类
CKF_SIGN_RECOVER:可恢复签名类
CKF_VERIFY:验证类
CKF_VERIFY_RECOVER:可恢复验证类
CKF_GENERATE:密钥产生
CKF_GENERATE_KEY_PAIR:密钥对产生
CKF_WRAP:密钥封装
CKF_UNWRAP:密钥解封
CKF_DERIVE:密钥派生
操作
调用流程
下列缩略语适用于本部分:
ECC:椭圆曲线算法(Elliptic Curve Cryptography)
IPK:内部加密公钥(Internal Public Key)
ISK:内部加密私钥(Internal Private Key)
EPK:外部加密公钥(External Public Key)
KEK:密钥加密密钥(Key Encrypt Key)
GM/T 0006设备定义信息如下
实际数字结构定义:
typedef struct DeviceInfo_st{
unsigned char IssuerName[40];
unsigned char DeviceName[16];
unsigned char DeviceSerial[16];
unsigned int DeviceVersion;
unsigned int StandardVersion;
unsigned int AsymAlgAbility[2];
unsigned int SymAlgAbility;
unsigned int HashAlgAbility;
unsigned int BufferSize;
}DEVICEINFO;
GB/T 0018-2012
# define RSAref_MAX_BIT S2048
# define RSAref_MAX_LEN
((RSAref_MAX_BITS+7)/8)
# define RSAref_MAX_PBITS
((RSAref_MAX_BITS+1)/2)
#define RSAref_MAX_PLEN
((RSAref_MAX_PBITS+7)/8)
typedef struct RSArefPublicKey_st
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
}RSArefPublicKey;
typedef struct RSArefPrivateKey_st
{
unsigned int bits;
unsigned char m[RSAref_MAX_LEN];
unsigned char e[RSAref_MAX_LEN];
unsigned char d[RSAref_MAX_LEN];
unsigned char prime[2][RSAref_MAX_PLEN]; u
nsigned char pexp[2][RSAref_MAX_PLEN];
unsigned char coef RSArefMAX_PLEN];
}RSArefPrivateKey;
ECC加密如下:
#define ECCref MAX BITS 512
#define ECCref MAX LEN ((ECCrefMAX BITS+7)/8)
typedef struct ECCrefPublicKey_st{
unsigned int bits;
unsigned char x[ECCrefMAXLEN]; unsigned char y[ECCref_MAX_LEN];
}ECCrefPublicKey;
typedef struct ECCrefPrivateKey_st{
unsigned int bits;
unsigned char K[ECCrefMAXLEN];
}ECCrefPrivateKey;
//******************************************
//设备管理
//******************************************
/*
功能:打开密码设备,返回设备句柄。
参数:
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_OpenDevice(void* phDeviceHandle);
/*
功能:关闭密码设备,并释放相关资源。
参数:hDeviceHandle[in] 已打开的设备句柄
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_CloseDevice(void hDeviceHandle);
/*
功能: 创建与密码设备的会话。
已打开的设备句柄
hDeviceHandlein]参数:h
phessionHiandle[out]
返回与密码设备建立的新会话句柄成功
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_OpenSession(void hDeviceHandle, void** phSessionHandle);
/*
功能:关闭与密码设备已建立的会话,并释放相关资源。
参数:hSessionHandle[in] 与密码设备已建立的会话句柄
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_CloseSesson(void hSessionHandle);
/*
功能:获取密码设备能力描述。
参数:hSessionHandle[in] 与设备建立的会话句柄
pstDevicelnfo[our] 设备能力描述信息,内容及格式见设备信息定义成功
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_GetDeviceInfo(
void hSessionHandle,
DEVICEINFO* pstDeviceInfo);
/*
功能:获取指定长度的随机数。
参数:
hSessonHandle[in] 与设备建立的会话句柄
uiLegth[in] 欲获取的随机数长度
pucRandom[out] 缓冲区指针,用于存放获取的随机数
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_GenerateRandom(
void hSessionHandle,
unsigned int uiLength,
unsigned char* pucRandom);
/*
功能:获取密码设备内部存储的指定索引私钥的使用权。
参数:
hSessionHandle[in] 与设备建立的会话句柄
uiKeyIndex[in] 密码设备存储私钥的索引值
pucPassword[in] 使用私钥权限的标识码
uiPwdLength[in] 私钥访问控制码长度,不少于8 字节
返回值:0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_GetPrivateKeyAccessRight(
void hSessionHandle,
unsigned int uiKeyIndex,
unsigned char* pucPassword,
unsigned int uiPwdLength);
/*
功能:释放密码设备存储的指定索引私钥的使用授权。
参数:
hSessonHandle[in] 与设备建立的会话句柄
uiKeyIndex[in] 密码设备存储私钥索引值成功
返回值∶0(SDR OK) 成功
非0 失败,返回错误代码
/
int SDF_ReleasePrivateKeyAccessRight(
void hSessionHandle,
unsigned int uiKeyIndex);
列出这些API包含的函数,进行分类,并总结它们的异同
- 异:Crypto API与PKCS#11
CryptoAPI是通过容器来组织密钥。一个容器可以存放两个RSA密钥对,一个用于签名验证,一个用于加解密。此外每个用户在加密对话其间还会随机产生许多会话密钥。
PKCS#11没有容器概念,它对密钥数据的保存和组织主要通过对象。p11定义了三种对象类型:数据对象,证书对象和密钥对象。
在CryptoAPI中的证书和证书库函数对应着PKCS#11中槽和令牌管理函数,其中CryptoAPI中多了证书库回调函数,可以进行返回操作。 - 同:
有最基本的加解密函数,以及签名和验证函数,以及证书的管理函数、密钥管理函数、信息处理函数。
龙脉测试
Crypto API
Signa_Verify
Enum_certs
EncryptFile
PKCS#11
GetUSBInfos
enumobj:
exportcert:
PKCSDEMO
TEST
SKF接口
DevAuth --------------设备认证例程
EncryptData --------------数据加解密例程
RemoteUnblock ------------远程解锁例程
Signature -------------签名验证例程