这几日工作需要研究 windows 的 CrptoAPI 实现3DES加密解密,着实耗费了一番功夫
除了windows CrptoAPI之外还是openssl可以实现3des比较便捷,可是需要配置,于是我选择使用的是windows的API
我们实现的简单的ECB模式 补码模式选用PKCS#7
3DES 对应的是 24位秘钥
windows提供了自己生成 Session key 方法,利用自己的 password ,经过hash,derive等方法生成
但是我们是已经拥有了key,并不需要自己生成
所以需要自己构建
struct keyBlob{
BLOBHEADER hdr;
DWORD cbKeySize;
BYTE rgbKeyData[24];
}keyBlob;
这个结构体是为了 CryptImportKey 使用,需要满足windows内部的格式才如此麻烦
下面是初始化
keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
keyBlob.hdr.reserved = 0;
keyBlob.hdr.aiKeyAlg = CALG_3DES;
keyBlob.cbKeySize = 24;
DWORD dwLength = key.length();
for(int i = 0; i < 24; ++i)
{
keyBlob.rgbKeyData[i] = (BYTE)key[i];
}
注意 keyBlob.hdr.aiKeyAlg = CALG_3DES 这句话, 后面对应的 CALG_3DES 就是对应你选的算法。
rgbKeyData 就是你所使用的key
HCRYPTPROV hProv;
CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)
这是初始化你的秘钥池,是为了Import key,import的时候需要一个池子。
如果你想知道各个参数的意义,上MSDN吧
接下去就是 Imoprt Key了;
HCRYPTKEY hKey;
CryptImportKey(hProv, (BYTE*)(&keyBlob), sizeof(keyBlob), 0, 0, &hKey)
当明文不满八位分组的时候需要对明文进行补位处理
这里我是自己添加的,因为我没有找到windows 的api如何设置padding 模式
为了对应 JAVA的 PKCS#7 八位分组
也就是当 缺7位补7位0x7,6为补6位0x6,以此类推,到1位的时候补1位0x1
但是当不缺位的时候能 你就要补一组0x8