#include ".\opencsp_key.h"
#include ".\opencsp_m$csp.h"
#include ".\opencsp_alg.h"
OPENCSP_M$CSP* OPENCSP_Key::_csp;
OPENCSP_Key::OPENCSP_Key(ALG_ID algId, DWORD dwFlags)
:_hKey(0), _perms(0), _algId(algId), _flags(dwFlags), _hKeyOfMSCSP(0)
{
_hKey = getHandle();
_csp = OPENCSP_M$CSP::createM$Instance();
}
OPENCSP_Key::~OPENCSP_Key(void)
{
if (_hKeyOfMSCSP)
_csp->destroyKey(_hKeyOfMSCSP);
}
DWORD OPENCSP_Key::generate(ALG_ID algId, DWORD dwFlags, OPENCSP_Key*& pKey) //产生密钥
{
DWORD dwRet;
switch(algId)
{
case CALG_RC2: //微软提供产生私钥的算法
case CALG_RC4:
case CALG_DES:
case CALG_3DES:
case CALG_3DES_112:
{
//会话密钥,会话密钥有时称对称密钥,因为同一密钥用于加密和解密。
OPENCSP_Key* key = new OPENCSP_SessionKey(algId, dwFlags);
if (!key)
return NTE_NO_MEMORY;
dwRet = key->_csp->genKey(algId, dwFlags, &key->_hKeyOfMSCSP);
if (dwRet != S_OK)
{
delete key;
return dwRet;
}
pKey = key;
}
break;
//容器里的密钥对有两种类型:AT_KEYEXCHANGE,表示交换的密钥对,AT_SIGNATURE表示签名的密钥对。
case AT_KEYEXCHANGE:
case AT_SIGNATURE:
{
OPENCSP_Key* key = new OPENCSP_RSAKeyInMemory(algId, dwFlags); //RSA:"非对称加密算法"
if (!key)
return NTE_NO_MEMORY;
dwRet = key->_csp->genKey(algId, dwFlags, &key->_hKeyOfMSCSP);
if (dwRet != S_OK)
{
delete key;
return dwRet;
}
pKey = key;
}
break;
}
return S_OK;
}
DWORD OPENCSP_Key::generate(ALG_ID algId, DWORD dwFlags, OPENCSP_CardAccess* pCard,
const KEYSET_NAME& kn, OPENCSP_Key*& pKey)
{
DWORD fOK = S_OK;
switch(algId)
{
case CALG_RSA_KEYX:
case CALG_RSA_SIGN:
{
BYTE bObjectStatus = 0, bKeyUsage = 0;
//读取密钥容器状态
fOK = pCard->getKeysetIdObjectStatus(kn.c_str(), &bObjectStatus, &bKeyUsage);
if (fOK != S_OK)
{
return fOK;
}
if (bObjectStatus & 0x04)
{
return NTE_EXISTS; // in the keyset there is a key pairs already
}
KEY_GEN_PARAM kpg;
kpg.algId = (algId == CALG_RSA_KEYX ? AT_KEYEXCHANGE : AT_SIGNATURE);
kpg.keySize = ((dwFlags & KEY_LENGTH_MASK) >> 16);
fOK = pCard->generateKeys(kn.c_str(), kpg); ////////////产生密钥对,ID,参数
if (fOK != S_OK) return fOK;
OPENCSP_Key* key = new OPENCSP_RSAKeyInCard(pCard, kn, algId, dwFlags);//非对称卡实现
if (!key) return NTE_NO_MEMORY;
pKey = key;
}
break;
default:
return NTE_BAD_ALGID;
}
return S_OK;
}
DWORD OPENCSP_Key::getUserKey(DWORD dwKeySpec, OPENCSP_Key*& pKey) //获得会话密钥
{
ALG_ID algId = (dwKeySpec == AT_KEYEXCHANGE ? CALG_RSA_KEYX : CALG_RSA_SIGN);
DWORD dwFlags = CRYPT_EXPORTABLE;
OPENCSP_Key* key = new OPENCSP_RSAKeyInMemory(algId, dwFlags);
if (!key) return NTE_NO_MEMORY;
DWORD dwRet = key->_csp->getUserKey(dwKeySpec, &(key->_hKeyOfMSCSP));
if (dwRet == NTE_BAD_KEY)
{
key->_csp->genKey(dwKeySpec, RSA1024BIT_KEY | dwFlags, &(key->_hKeyOfMSCSP));
}
pKey = key;
return S_OK;
}
DWORD OPENCSP_Key::getUserKey(DWORD dwKeySpec, OPENCSP_CardAccess* pCard,
const KEYSET_NAME& kn, OPENCSP_Key*& pKey)
{
DWORD fOK = S_OK;
ALG_ID algId = (dwKeySpec == AT_KEYEXCHANGE ? CALG_RSA_KEYX : CALG_RSA_SIGN);
BYTE bObjectStatus = 0, bKeyUsage = 0;
fOK = pCard->getKeysetIdObjectStatus(kn.c_str(), &bObjectStatus, &bKeyUsage);//读取密钥容器状态
if (S_OK != fOK) goto END;
if (!(bObjectStatus & 0x04))
{
fOK = NTE_NO_KEY;
goto END;
}
if (bKeyUsage != dwKeySpec)
{
fOK = NTE_NO_KEY;
goto END;
}
OPENCSP_Key* p = new OPENCSP_RSAKeyInCard(pCard, kn, algId);
if (!p)
{
fOK = NTE_NO_MEMORY;
goto END;
}
pKey = p;
END:
return fOK;
}
DWORD OPENCSP_Key::importKey(const BYTE* pbData, DWORD dwDataLen, HCRYPTKEY hPubKey,
DWORD dwFlags, OPENCSP_CardAccess* pCard, const KEYSET_NAME& kn, OPENCSP_Key*& pKey)
{ //导入会话密钥hKey
BYTE bData[1024] = {0x0};
DWORD dwLen = 0;
BLOBHEADER bh;
DWORD dwKeySpec = 0;
DWORD fOK = S_OK;
BYTE bObjectStatus = 0, bKeyUsage = 0;
fOK = pCard->getKeysetIdObjectStatus(kn.c_str(), &bObjectStatus, &bKeyUsage);//读取密钥容器状态
if (S_OK != fOK) return fOK;
if (bObjectStatus & 0x04)
{
return NTE_EXISTS;
}
// get key usage
memcpy(&bh, pbData, sizeof(PUBLICKEYSTRUC));
dwKeySpec = (bh.aiKeyAlg == CALG_RSA_KEYX ? AT_KEYEXCHANGE : AT_SIGNATURE);
memcpy(bData, (LPBYTE)pbData + sizeof(PUBLICKEYSTRUC),
dwDataLen - sizeof(PUBLICKEYSTRUC));//移到内存
dwLen = dwDataLen - sizeof(PUBLICKEYSTRUC);
if (hPubKey)
{
fOK = _csp->decrypt(hPubKey, 0, TRUE, dwFlags, bData, &dwLen);
if (S_OK != fOK) return fOK;
{
return fOK;
}
}
DWORD dwIndex = 0, dwKeyLen;
RSAPUBKEY rsapubkey;
MY_DATA_BLOB pubExponent, modulus, prime1, prime2, exponent1, exponent2, coefficient;
memcpy(&rsapubkey, bData, sizeof(RSAPUBKEY));
if (rsapubkey.magic != 0x32415352) //数据不对
{
// Not PRIVATEKEYBLOB
return NTE_BAD_DATA;
}
if (OPENCSP_Alg::getKeyLen(CALG_RSA_KEYX) != rsapubkey.bitlen) //长度不对
{
// key length is not expected!
return NTE_BAD_DATA;
}
/* java中RSA加解密的实现
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
HashMap<String, Object> map = RSAUtils.getKeys();
//生成公钥和私钥
RSAPublicKey publicKey = (RSAPublicKey) map.get("public");
RSAPrivateKey privateKey = (RSAPrivateKey) map.get("private");
//模
String modulus = publicKey.getModulus().toString();
//公钥指数
String public_exponent = publicKey.getPublicExponent().toString();
//私钥指数
String private_exponent = privateKey.getPrivateExponent().toString();
//明文
String ming = "123456789";
//使用模和指数生成公钥和私钥
RSAPublicKey pubKey = RSAUtils.getPublicKey(modulus, public_exponent);
RSAPrivateKey priKey = RSAUtils.getPrivateKey(modulus, private_exponent);
//加密后的密文
String mi = RSAUtils.encryptByPublicKey(ming, pubKey);
System.err.println(mi);
//解密后的明文
ming = RSAUtils.decryptByPrivateKey(mi, priKey);
System.err.println(ming);
}
*/
/*
(1)选择一对不同的、足够大的素数p,q。
(2)计算n=pq。
(3)计算f(n)=(p-1)(q-1),同时对p, q严加保密,不让任何人知道。
(4)找一个与f(n)互质的数e,且1<e<f(n)。
(5)计算d,使得de≡1 mod f(n)。
(6)公钥KU=(e,n),私钥KR=(d,n)。
(7)加密时,先将明文变换成0至n-1的一个整数M。若明文较长,
可先分割成适当的组,然后再进行交换。设密文为C,加密
(8)解密
*/
// Now collect key pair components 非对称加密算法:RSA加密算法。RSA密钥数据结构
dwKeyLen = rsapubkey.bitlen; //模数的实际位长度,8的倍数
pubExponent.insert(pubExponent.end(), bData + 2 * (sizeof(DWORD)),
bData + 3 * (sizeof(DWORD))); //公开密钥e
dwIndex += sizeof(RSAPUBKEY);
modulus.insert(modulus.end(), bData + dwIndex,
bData + dwIndex + dwKeyLen / 8); //模数,实际长度bitlen/8字节
dwIndex += dwKeyLen / 8;
prime1.insert(prime1.end(), bData + dwIndex,
bData + dwIndex + dwKeyLen / 16); //素数p,实际长度bitlen/16字节
dwIndex += dwKeyLen / 16;
prime2.insert(prime2.end(), bData + dwIndex,
bData + dwIndex + dwKeyLen / 16); //素数q,实际长度bitlen/16字节
dwIndex += dwKeyLen / 16;
exponent1.insert(exponent1.end(), bData + dwIndex,
bData + dwIndex + dwKeyLen / 16);//d mod (p-1)的值,实际长度bitlen/16字节
dwIndex += dwKeyLen / 16;
exponent2.insert(exponent2.end(), bData + dwIndex,
bData + dwIndex + dwKeyLen / 16);//d mod (q-1)的值,实际长度bitlen/16字节
dwIndex += dwKeyLen / 16;
coefficient.insert(coefficient.end(), bData + dwIndex,
bData + dwIndex + dwKeyLen / 16);//q模p的乘法逆元,实际长度bitlen/16字节
dwIndex += dwKeyLen / 16;
// In MS, it's always little endian, so reverse it.
// At the same time, construct them to meet with smart card requirement
MY_DATA_BLOB rsakeyblob;
// PUBLIC KEY: N + E
reverse(modulus.begin(), modulus.end());
//填充数据结构后,翻转是改变字节序,与与卡传送数据有关
rsakeyblob.insert(rsakeyblob.end(), modulus.begin(), modulus.end());
reverse(pubExponent.begin(), pubExponent.end());
rsakeyblob.insert(rsakeyblob.end(), pubExponent.begin(), pubExponent.end());
// PRIVATE KEY: Q + P + Qi + DQ + DP
reverse(prime2.begin(), prime2.end());
rsakeyblob.insert(rsakeyblob.end(), prime2.begin(), prime2.end());
reverse(prime1.begin(), prime1.end());
rsakeyblob.insert(rsakeyblob.end(), prime1.begin(), prime1.end());
reverse(coefficient.begin(), coefficient.end());
rsakeyblob.insert(rsakeyblob.end(), coefficient.begin(), coefficient.end());
reverse(exponent2.begin(), exponent2.end());
rsakeyblob.insert(rsakeyblob.end(), exponent2.begin(), exponent2.end());
reverse(exponent1.begin(), exponent1.end());
rsakeyblob.insert(rsakeyblob.end(), exponent1.begin(), exponent1.end());
fOK = pCard->importKey(kn.c_str(), (BYTE)dwKeySpec, (LPBYTE)&rsakeyblob[0],
(DWORD)rsakeyblob.size());////将密钥对导入特定的密钥容器
if (fOK != S_OK) return fOK;
pKey = new OPENCSP_RSAKeyInCard(pCard, kn, CALG_RSA_KEYX);
return fOK;
}
DWORD OPENCSP_Key::importKey(const BYTE* pbData, DWORD dwDataLen,
//导入密钥from a key binary large object (BLOB) to CSP
HCRYPTKEY hPubKey, DWORD dwFlags, OPENCSP_Key*& pKey)
{
OPENCSP_Key* key;
BLOBHEADER bh;
memcpy(&bh, pbData, sizeof(bh));
switch (bh.bType)
{
case SIMPLEBLOB:
{
key = new OPENCSP_SessionKey(bh.aiKeyAlg, dwFlags);
if (!key) return NTE_NO_MEMORY;
DWORD dwRet = key->_csp->importKey(pbData, dwDataLen, hPubKey,
dwFlags, &key->_hKeyOfMSCSP);
if (S_OK != dwRet)
{
delete key;
return dwRet;
}
pKey = key;
}
}
return S_OK;
}
const BOOL OPENCSP_Key::isSessionKey() const //是否是会话密钥
{
return (!(GET_ALG_TYPE(_algId) ^ ALG_TYPE_RSA) ? TRUE : FALSE);
}
const BOOL OPENCSP_Key::isBlockCipherKey() const
{
return (!(GET_ALG_TYPE(_algId) ^ ALG_TYPE_BLOCK) ? TRUE : FALSE);
}
const BOOL OPENCSP_Key::isExportable() const //是否可以导出
{
return (_flags ^ CRYPT_EXPORTABLE ? TRUE : FALSE);
}
//----------------------------------------------------------------------------------------
OPENCSP_SessionKey::OPENCSP_SessionKey(ALG_ID algId, DWORD dwFlags)
:OPENCSP_Key(algId, dwFlags)
{
}
OPENCSP_SessionKey::~OPENCSP_SessionKey()
{
}
DWORD OPENCSP_SessionKey::exportKey(HCRYPTKEY hKey, DWORD dwBlobType, DWORD dwFlags,
BYTE* pbData, DWORD* pdwDataLen)//从CSP导出密钥
{
_csp->exportKey(_hKeyOfMSCSP, hKey, dwBlobType, dwFlags, pbData, pdwDataLen);
return GetLastError();
}
DWORD OPENCSP_SessionKey::encrypt(BOOL Final, DWORD dwFlags, BYTE* pbData,
DWORD* pdwDataLen, DWORD dwBufLen) //加密
{
_csp->encrypt(_hKeyOfMSCSP, 0, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
return GetLastError();
}
DWORD OPENCSP_SessionKey::decrypt(BOOL Final, DWORD dwFlags, BYTE* pbData,
DWORD* pdwDataLen) //解密
{
_csp->decrypt(_hKeyOfMSCSP, 0, Final, dwFlags, pbData, pdwDataLen);
return GetLastError();
}
DWORD OPENCSP_SessionKey::signHash(OPENCSP_Hash* pHash, LPCTSTR sDescription,
DWORD dwFlags, BYTE* pbSignature, DWORD* pdwSigLen)//哈希值签名
{
return E_NOTIMPL;
}
DWORD OPENCSP_SessionKey::verifySignature(OPENCSP_Hash* pHash, const BYTE* pbSignature,
DWORD dwSigLen, LPCTSTR szDescription, DWORD dwFlags)//验证签名
{
return E_NOTIMPL;
}
const DWORD OPENCSP_SessionKey::getBlockLen() const
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_BLOCKLEN, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
const DWORD OPENCSP_SessionKey::getKeyLen() const //获取密钥长度
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_KEYLEN, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
const DWORD OPENCSP_SessionKey::getPerms() const //获取权限
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_PERMISSIONS, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
DWORD OPENCSP_SessionKey::setPerms(BYTE* pbData) //设置访问权限
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_PERMISSIONS, pbData, 0);
}
DWORD OPENCSP_SessionKey::getSaltValue(SALT_VALUE& sv) const //获取混淆值,哈希算法中唯一
{
DWORD fOK;
BYTE bData[64] = {0};
DWORD dwLen = sizeof(bData);
fOK = _csp->getKeyParam(_hKeyOfMSCSP, KP_SALT, bData, &dwLen, 0);
if (S_OK != fOK) return fOK;
sv.insert(sv.end(), bData, bData + dwLen);
return S_OK;
}
DWORD OPENCSP_SessionKey::setSaltValue(BYTE* pbData) //设置混淆值
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_SALT, pbData, 0);
}
DWORD OPENCSP_SessionKey::getIV(IV_VALUE& iv) const //获取算法的初始向量
{
DWORD fOK;
BYTE bData[64] = {0};
DWORD dwLen = sizeof(bData);
fOK = _csp->getKeyParam(_hKeyOfMSCSP, KP_IV, bData, &dwLen, 0);
if (!fOK) return fOK;
iv.insert(iv.end(), bData, bData + dwLen);
return S_OK;
}
DWORD OPENCSP_SessionKey::setIV(BYTE* pbData) //设置算法的初始向量
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_IV, pbData, 0);
}
//算法填充,No padding加密以一个完整的块结束,而没有多余的数据
DWORD OPENCSP_SessionKey::setPadding(BYTE* pbData)
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_PADDING, pbData, 0);
}
DWORD OPENCSP_SessionKey::setMode(BYTE* pbData) //设置加密模式
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_MODE, pbData, 0);
}
DWORD OPENCSP_SessionKey::setModeBits(BYTE* pbData) //设置加密模式位数
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_MODE_BITS, pbData, 0);
}
DWORD OPENCSP_SessionKey::getPadding(PADDING_VALUE& pv) const //获取算法填充
{
DWORD fOK;
BYTE bData[32] = {0};
DWORD dwLen = sizeof(bData);
fOK = _csp->getKeyParam(_hKeyOfMSCSP, KP_PADDING, bData, &dwLen, 0);
if (S_OK != fOK) return fOK;
pv.insert(pv.end(), bData, bData + dwLen);
return S_OK;
}
const DWORD OPENCSP_SessionKey::getMode() const //获取加密模式
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_MODE, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
const DWORD OPENCSP_SessionKey::getModeBits() const //得到加密模式位数
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_MODE_BITS, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
const DWORD OPENCSP_SessionKey::getEffectiveLen() const //得到加密有效位
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_EFFECTIVE_KEYLEN, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
DWORD OPENCSP_SessionKey::setEffectiveLen(BYTE* pbData) //设置加密有效位
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_EFFECTIVE_KEYLEN, pbData, 0);
}
//----------------------------------------------------------------------------------------
OPENCSP_RSAKeyInMemory::OPENCSP_RSAKeyInMemory(ALG_ID algId, DWORD dwFlags)
:OPENCSP_Key(algId, dwFlags)
{
}
OPENCSP_RSAKeyInMemory::~OPENCSP_RSAKeyInMemory()
{
}
DWORD OPENCSP_RSAKeyInMemory::exportKey(HCRYPTKEY hKey, DWORD dwBlobType,
DWORD dwFlags, BYTE* pbData, DWORD* pdwDataLen)
{
_csp->exportKey(_hKeyOfMSCSP, hKey, dwBlobType, dwFlags, pbData, pdwDataLen);
return GetLastError();
}
DWORD OPENCSP_RSAKeyInMemory::encrypt(BOOL Final, DWORD dwFlags, BYTE* pbData,
DWORD* pdwDataLen, DWORD dwBufLen)
{
_csp->encrypt(_hKeyOfMSCSP, 0, Final, dwFlags, pbData, pdwDataLen, dwBufLen);
return GetLastError();
}
DWORD OPENCSP_RSAKeyInMemory::decrypt(BOOL Final, DWORD dwFlags, BYTE* pbData,
DWORD* pdwDataLen)
{
_csp->decrypt(_hKeyOfMSCSP, 0, Final, dwFlags, pbData, pdwDataLen);
return GetLastError();
}
DWORD OPENCSP_RSAKeyInMemory::signHash(OPENCSP_Hash* pHash, LPCTSTR sDescription,
DWORD dwFlags, BYTE* pbSignature, DWORD* pdwSigLen)
{
_csp->signHash(pHash->getMSHash(), AT_KEYEXCHANGE, sDescription, dwFlags,
pbSignature, pdwSigLen);
return GetLastError();
}
DWORD OPENCSP_RSAKeyInMemory::verifySignature(OPENCSP_Hash* pHash, const BYTE* pbSignature,
DWORD dwSigLen, LPCTSTR szDescription, DWORD dwFlags)
{
_csp->verifySignature(pHash->getMSHash(), pbSignature, dwSigLen, getKeyOfMSCSP(),
szDescription, dwFlags);
return GetLastError();
}
const DWORD OPENCSP_RSAKeyInMemory::getBlockLen() const
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_BLOCKLEN, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
const DWORD OPENCSP_RSAKeyInMemory::getKeyLen() const
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_KEYLEN, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
const DWORD OPENCSP_RSAKeyInMemory::getPerms() const
{
DWORD dwRet = 0;
BYTE bData[4] = {0};
DWORD dwLen = sizeof(bData);
_csp->getKeyParam(_hKeyOfMSCSP, KP_PERMISSIONS, bData, &dwLen, 0);
memcpy(&dwRet, &bData[0], dwLen);
return dwRet;
}
DWORD OPENCSP_RSAKeyInMemory::setPerms(BYTE* pbData)
{
return _csp->setKeyParam(_hKeyOfMSCSP, KP_PERMISSIONS, pbData, 0);
}
//------------------------------------------------------------------------------------
DWORD OPENCSP_RSAKeyInCard::_perm = CRYPT_ENCRYPT | CRYPT_DECRYPT | CRYPT_READ;
OPENCSP_RSAKeyInCard::OPENCSP_RSAKeyInCard(OPENCSP_CardAccess* pCardAccess,
const KEYSET_NAME& kn, ALG_ID algId, DWORD dwFlags)
:OPENCSP_Key(algId, dwFlags), _cardPtr(pCardAccess), _keysetName(kn)
{
}
OPENCSP_RSAKeyInCard::~OPENCSP_RSAKeyInCard()
{
}
const DWORD OPENCSP_RSAKeyInCard::getBlockLen() const
{
return OPENCSP_Alg::getKeyLen(_algId);
}
const DWORD OPENCSP_RSAKeyInCard::getKeyLen() const
{
return OPENCSP_Alg::getKeyLen(_algId);
}
const DWORD OPENCSP_RSAKeyInCard::getPerms() const
{
return _perm;
}
DWORD OPENCSP_RSAKeyInCard::setPerms(BYTE* pbData)
{
return NTE_PERM;
}
DWORD OPENCSP_RSAKeyInCard::exportKey(HCRYPTKEY hKey, DWORD dwBlobType,
DWORD dwFlags, BYTE* pbData, DWORD* pdwDataLen) //从卡到电脑
{
DWORD fOK = S_OK;
switch(dwBlobType) //二进制容器的类型
{
case PUBLICKEYBLOB:
{
if (hKey != 0)
return NTE_BAD_KEY;
if (pbData == NULL)
{
*pdwDataLen = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + 128;
return S_OK;
}
if (pbData && (*pdwDataLen < sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + 128))
{
*pdwDataLen = sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + 128;
return ERROR_MORE_DATA;
}
BYTE bData[512] = {0};
DWORD dwDataLen = 512;
fOK = _cardPtr->readPublicKey(_keysetName.c_str(), bData, &dwDataLen); //读公钥
if (fOK != S_OK)
return fOK;
// now construct public key blob //造个存储公钥的BIOB
DWORD dwIndex = 0;
PUBLICKEYSTRUC pks = {0};
pks.aiKeyAlg = CALG_RSA_KEYX;
pks.bType = PUBLICKEYBLOB;
pks.bVersion = CUR_BLOB_VERSION;
pks.reserved = 0;
RSAPUBKEY rpk = {0};
rpk.bitlen = 1024;
rpk.magic = 0x31415352; //Microsoft's magic number
MY_DATA_BLOB mdb;
mdb.insert(mdb.end(), bData, bData + sizeof(DWORD));
reverse(mdb.begin(), mdb.end());
memcpy(&(rpk.pubexp), &mdb[0], sizeof(DWORD));
memcpy(pbData, &pks, sizeof(PUBLICKEYSTRUC));
dwIndex += sizeof(PUBLICKEYSTRUC);
memcpy(pbData + dwIndex, &rpk, sizeof(RSAPUBKEY));
dwIndex += sizeof(RSAPUBKEY);
/* BIG -> LITTLE endian transform */
mdb.clear();
mdb.insert(mdb.end(), bData + sizeof(DWORD),
bData + sizeof(DWORD) + dwDataLen - sizeof(DWORD));
reverse(mdb.begin(), mdb.end());
memcpy(pbData + dwIndex, &mdb[0], mdb.size());
/*pubExponent has already assigned*/
*pdwDataLen = dwIndex + dwDataLen - sizeof(DWORD);
}
break;
case PRIVATEKEYBLOB:
// not support export private key from card!
return NTE_BAD_DATA;
default:
return NTE_BAD_TYPE;
}
return fOK;
}
DWORD OPENCSP_RSAKeyInCard::encrypt(BOOL Final, DWORD dwFlags, BYTE* pbData,
DWORD* pdwDataLen, DWORD dwBufLen)
{
DWORD fOK = S_OK;
if (dwFlags != 0)
return NTE_BAD_FLAGS;
if (!pbData) return NTE_BAD_DATA;
if (*pdwDataLen > 0x80 - 2 - 1) return NTE_BAD_DATA;
if (dwBufLen < 0x80) return NTE_BAD_LEN;
BYTE bIn[128] = {0x00, 0x02}, bOut[128] = {0};
DWORD dwInLen, dwOutLen = 128, dwPadding;
dwInLen = *pdwDataLen;
dwPadding = 0x80 - 2 - 1 - dwInLen;
memset(bIn + 2, 0xff, dwPadding);
memcpy(bIn + 2 + dwPadding + 1, pbData, dwInLen);
MY_DATA_BLOB mdb;
mdb.insert(mdb.end(), bIn, bIn + 0x80);
reverse(mdb.begin(), mdb.end());
memcpy(bIn, &mdb[0], mdb.size());
fOK = _cardPtr->computeCrypt(_keysetName.c_str(), CARD_OPER_RSA_VERYIFY, bIn,
0x80, bOut, &dwOutLen);////////用密钥计算
if (fOK != S_OK)
return fOK;
memcpy(pbData, bOut, dwOutLen);
*pdwDataLen = dwOutLen;
return S_OK;
}
DWORD OPENCSP_RSAKeyInCard::decrypt(BOOL Final, DWORD dwFlags, BYTE* pbData,
DWORD* pdwDataLen)
{
// use private key to decrypt(SIGN)
DWORD fOK = S_OK;
if (dwFlags != 0) return NTE_BAD_FLAGS;
if (!pbData) return NTE_BAD_DATA;
if (*pdwDataLen != 0x80) return NTE_BAD_DATA;
MY_DATA_BLOB mdb;
BYTE bOut[128] = {0};
DWORD dwInLen, dwOutLen = 128;
dwInLen = *pdwDataLen;
mdb.clear();
mdb.insert(mdb.end(), pbData, pbData + dwInLen);
reverse(mdb.begin(), mdb.end());
fOK = _cardPtr->computeCrypt(_keysetName.c_str(), CARD_OPER_RSA_SIGN, &mdb[0],
dwInLen, bOut, &dwOutLen);//用密钥计算
if (fOK != S_OK)
return fOK;
// get the actual data
if (bOut[0] == 0x00 && bOut[1] == 0x02)
{
DWORD dwIndex = 2;
while (1)
{
if (bOut[dwIndex] == 0)
{
break;
}
dwIndex++;
}
*pdwDataLen = dwOutLen - dwIndex - 1;
memcpy(pbData, bOut + dwIndex + 1, *pdwDataLen);
}
else
return NTE_BAD_DATA;
return S_OK;
}
DWORD OPENCSP_RSAKeyInCard::signHash(OPENCSP_Hash* pHash, LPCTSTR sDescription,
DWORD dwFlags, BYTE* pbSignature, DWORD* pdwSigLen)
{
DWORD fOK = S_OK;
HASH_VALUE hv;
hv.clear();
if (dwFlags == 0)
{
if (pHash->getHashAlg() == CALG_MD5)
hv.insert(hv.end(), s_bMD5DigestInfo, s_bMD5DigestInfo + sizeof(s_bMD5DigestInfo));
if (pHash->getHashAlg() == CALG_SHA1)
hv.insert(hv.end(), s_bShaDigestInfo, s_bShaDigestInfo + sizeof(s_bShaDigestInfo));
}
fOK = pHash->getHashValue(hv);
if (fOK != S_OK)
return fOK;
BYTE bIn[0x80] = {0x00, 0x01}, bOut[0x80] = {0};
DWORD dwInLen, dwOutLen = 0x80, dwPaddings = 0;
dwInLen = (DWORD)hv.size();
dwPaddings = 0x80 - 2 - dwInLen - 1;
memset(bIn + 2, 0xff, dwPaddings);
memcpy(bIn + 2 + dwPaddings + 1, &hv[0], dwInLen);
fOK = _cardPtr->computeCrypt(_keysetName.c_str(), CARD_OPER_RSA_SIGN, bIn,
0x80, bOut, &dwOutLen);//用密钥计算
if (fOK != S_OK) return fOK;
MY_DATA_BLOB mdb;
mdb.clear();
mdb.insert(mdb.end(), bOut, bOut + 0x80);
reverse(mdb.begin(), mdb.end());
*pdwSigLen = 0x80;
memcpy(pbSignature, &mdb[0], 0x80);
return fOK;
}
DWORD OPENCSP_RSAKeyInCard::verifySignature(OPENCSP_Hash* pHash, const BYTE* pbSignature,
DWORD dwSigLen, LPCTSTR szDescription, DWORD dwFlags)
{
DWORD fOK = S_OK;
BYTE bIn[128] = {0x00}, bOut[128] = {0x00};
DWORD dwInLen = dwSigLen, dwOutLen = 0x80;
MY_DATA_BLOB mdb;
if (dwInLen != 0x80) return ERROR_BAD_LENGTH;
if (pbSignature == NULL) return NTE_BAD_DATA;
HASH_VALUE hv;
hv.clear();
if (dwFlags == 0)
{
if (pHash->getHashAlg() == CALG_MD5)
hv.insert(hv.end(), s_bMD5DigestInfo, s_bMD5DigestInfo + sizeof(s_bMD5DigestInfo));
if (pHash->getHashAlg() == CALG_SHA1)
hv.insert(hv.end(), s_bShaDigestInfo, s_bShaDigestInfo + sizeof(s_bShaDigestInfo));
}
fOK = pHash->getHashValue(hv);
if (fOK != S_OK)
return fOK;
mdb.clear();
mdb.insert(mdb.end(), pbSignature, pbSignature + 0x80);
reverse(mdb.begin(), mdb.end());
fOK = _cardPtr->computeCrypt(_keysetName.c_str(), CARD_OPER_RSA_VERYIFY, &mdb[0],
0x80, bOut, &dwOutLen);//用密钥计算
if (fOK != S_OK)
return fOK;
// discard off padding(PKCS#1 type 1)
if (bOut[0] == 0x00 && bOut[1] == 0x01)
{
DWORD dwIndex = 2;
while(1)
{
if (bOut[dwIndex] == 0)
{
break;
}
dwIndex ++;
}
if (memcmp(&bOut[dwIndex + 1], &hv[0], 0x80 - dwIndex - 1) != 0)
{
return NTE_BAD_SIGNATURE;
}
}
else
return NTE_BAD_DATA;
return fOK;
}
DWORD OPENCSP_RSAKeyInCard::getCertificate(BYTE* pbCert, LPDWORD lpdwCertSize)
{
DWORD fOK = S_OK;
BYTE bObjStatus = 0, bKeyUsage = 0;
fOK = _cardPtr->getKeysetIdObjectStatus(_keysetName.c_str(), &bObjStatus,
&bKeyUsage);//读取密钥容器状态
if (fOK != S_OK)
{
return fOK;
}
if ((bObjStatus & 0x01) != 0)
{
// certificate doesn't exist yet
return NTE_BAD_KEY;
}
fOK = _cardPtr->readCertificate(_keysetName.c_str(), pbCert, lpdwCertSize);//读取证书
if (fOK != S_OK)
{
return fOK;
}
return S_OK;
}
DWORD OPENCSP_RSAKeyInCard::setCertificate(LPCBYTE pbCert, DWORD dwCertSize)
{
DWORD fOK = S_OK;
BYTE bObjStatus = 0, bKeyUsage = 0;
fOK = _cardPtr->getKeysetIdObjectStatus(_keysetName.c_str(), &bObjStatus, &bKeyUsage);
if (fOK != S_OK)
{
return fOK;
}
if (bObjStatus & 0x01)
{
// certificate doesn't exist yet
return NTE_EXISTS;
}
fOK = _cardPtr->writeCertificate(_keysetName.c_str(), pbCert, dwCertSize);//写证书到密钥容器
if (fOK != S_OK)
{
return fOK;
}
return S_OK;
}