CryptoApi под Win 2000 и Win Xp
От: globus000 Украина  
Дата: 12.04.03 06:54
Оценка:
У меня есть код класса, использующий cryptoApi для шифрованя/дешифрования по DES и RSA. когда я запускаю его под WinXp все работает нормально, но когда запускаю под Win2000 шифрование по RSA перестает работать, при попытке зашифровать последовательность выпадает сообщение "Плохой ключ". Непонятно, почему так происходит — ключи инициализируются нормально без ошибок. Может кто поможет?

Код класса:
CZCrypt::CZCrypt()
{
    m_hRSACryptProv = NULL;
    m_hRSAKey = NULL;
    m_hDESKey = NULL;
}

CZCrypt::~CZCrypt()
{
    ReleaseRSA();
}

DWORD CZCrypt::InitRSA(char *UserName)
{
    DWORD err = 0;

    if(!CryptAcquireContext(&m_hRSACryptProv, UserName, MS_DEF_PROV, PROV_RSA_FULL, 0))
    {
        err = GetLastError();
        if(err != 0x80090016)
            return err;
        if(!CryptAcquireContext(&m_hRSACryptProv, UserName, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            return GetLastError();
    }
    return 0;
}

DWORD CZCrypt::GenDESKey()
{
    if(m_hRSACryptProv == NULL)
        return 1;

    if(m_hDESKey)
        CryptDestroyKey(m_hDESKey);
    m_hDESKey = NULL;

    if(!CryptGenKey(m_hRSACryptProv, CALG_DES, CRYPT_EXPORTABLE, &m_hDESKey)) //64 bit
        return GetLastError();
    return 0;
}


void CZCrypt::ReleaseRSA()
{
    if(m_hRSACryptProv)
        CryptReleaseContext(m_hRSACryptProv, 0);
    m_hRSACryptProv = NULL;
    if(m_hRSAKey)
        CryptDestroyKey(m_hRSAKey); 
    m_hRSAKey = NULL;
    if(m_hDESKey)
        CryptDestroyKey(m_hDESKey); 
    m_hDESKey = NULL;
}

DWORD CZCrypt::GenRSAKeys()
{
    if(m_hRSACryptProv == NULL)
        return 1;

    if(m_hRSAKey)
        CryptDestroyKey(m_hRSAKey); 
    m_hRSAKey = NULL;

    if(!CryptGenKey(m_hRSACryptProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE|0x04000000, &m_hRSAKey)) //1024 bit
        return GetLastError();
    return 0;
}

DWORD CZCrypt::GetRSAPublicKey(RSAPublicKey1024* pkey)
{
    if(m_hRSACryptProv==NULL || m_hRSAKey==NULL)
        return 1;

    DWORD actual_data_length = sizeof(RSAPublicKey1024);
    if(!CryptExportKey(m_hRSAKey, NULL, PUBLICKEYBLOB, 0, (BYTE*)pkey, &actual_data_length))
        return GetLastError();
    return 0;
}

DWORD CZCrypt::GetDESKey(DESKEY* dkey)
{
    if(m_hRSACryptProv==NULL || m_hDESKey==NULL)
        return 1;

    DWORD actual_data_length = sizeof(DESKEY);
    if(!CryptExportKey(m_hDESKey, NULL, PLAINTEXTKEYBLOB, 0, (BYTE*)dkey, &actual_data_length))
        return GetLastError();
    return 0;
}

DWORD CZCrypt::EncryptRSA(BYTE* plainbuf, int plainbufsize, DWORD* actual_data_length)
{
    if(m_hRSACryptProv==NULL || m_hRSAKey==NULL)
        return 1;

    if(plainbufsize < 1024/8)
        return 1;

    if(!CryptEncrypt(m_hRSAKey, NULL, TRUE, 0, (BYTE*)plainbuf, actual_data_length, plainbufsize))
        return GetLastError();
    return 0;
}

DWORD CZCrypt::DecryptRSA(BYTE* cipherbuf, DWORD* actual_data_length)
{
    if(m_hRSACryptProv==NULL || m_hRSAKey==NULL)
        return 1;

    if(!CryptDecrypt(m_hRSAKey, NULL, TRUE, 0, (BYTE*)cipherbuf, actual_data_length))
        return GetLastError();
    return 0;
}

DWORD CZCrypt::ImportRSAKey(BYTE* plainRSAkey, DWORD dwExp)
{
    if(m_hRSACryptProv==NULL)
        return 1;

    if(m_hRSAKey != NULL)
    {
        if(!CryptDestroyKey(m_hRSAKey))
            return 1;
        m_hRSAKey = NULL;
    }

    RSAPublicKey1024 rkey;
    CopyMemory(rkey.modulus, plainRSAkey, 1024/8);
    rkey.publickeystruc.aiKeyAlg = ALG_TYPE_RSA|ALG_CLASS_KEY_EXCHANGE;
    rkey.publickeystruc.bType = PUBLICKEYBLOB;
    rkey.publickeystruc.bVersion = CUR_BLOB_VERSION;
    rkey.publickeystruc.reserved = 0;
    rkey.rsapubkey.bitlen = 1024;
    rkey.rsapubkey.magic = 0x31415352; //RSA1
    rkey.rsapubkey.pubexp = dwExp;

    if(!CryptImportKey(m_hRSACryptProv, (BYTE*)&rkey, sizeof(rkey), NULL, CRYPT_EXPORTABLE, &m_hRSAKey))
        return GetLastError();
    return 0;
}

DWORD CZCrypt::ImportDESKey(BYTE* plainDESkey)
{
    if(m_hRSACryptProv==NULL)
        return 1;

    if(m_hDESKey != NULL)
    {
        if(!CryptDestroyKey(m_hDESKey))
            return 1;
        m_hDESKey = NULL;
    }

    DESKEY dkey;
    CopyMemory(dkey.keydata, plainDESkey, 8);
    dkey.pubkey.bType = PLAINTEXTKEYBLOB;
    dkey.pubkey.bVersion = CUR_BLOB_VERSION;
    dkey.pubkey.reserved = 0;
    dkey.pubkey.aiKeyAlg = CALG_DES;
    dkey.keysize = 8;

    if(!CryptImportKey(m_hRSACryptProv, (BYTE*)&dkey, sizeof(dkey), NULL, CRYPT_EXPORTABLE, &m_hDESKey))
        return GetLastError();
    return 0;
}

DWORD CZCrypt::EncryptDES(BYTE* plainbuf, int plainbufsize, DWORD* pActual_data_length)
{
    int blocksize = 64/8;
    if(m_hRSACryptProv==NULL || m_hDESKey==NULL)
        return 1;

    //Check for minimum buffer length (it is necessary to have one additional empty block at the end of buffer)
    //cout<<"Init Ok"<<endl;
    if((DWORD)plainbufsize < (*pActual_data_length&7)+8)
        return 1;

    DWORD bnSize = 0;

    for(DWORD icx=0; icx<*pActual_data_length; icx+=blocksize)
    {
        DWORD block_sz = blocksize;
        BOOL bLast = FALSE;

        if(icx+blocksize >= *pActual_data_length)
        {
            block_sz = *pActual_data_length - icx;
            bLast = TRUE;
        }

        if(!CryptEncrypt(m_hDESKey, NULL, bLast, 0, (BYTE*)plainbuf+icx, &block_sz, plainbufsize-icx))
            return GetLastError();

        bnSize += block_sz;
    }

    *pActual_data_length = bnSize;
    return 0;
}

DWORD CZCrypt::DecryptDES(BYTE* cipherbuf, DWORD* pActual_data_length)
{
    int blocksize = 64/8;

    if(m_hRSACryptProv==NULL || m_hDESKey==NULL)
        return 1;

    DWORD bnSize = 0;

    for(DWORD icx=0; icx<*pActual_data_length; icx+=blocksize)
    {
        DWORD block_sz = blocksize;
        BOOL bLast = FALSE;

        if(icx+blocksize >= *pActual_data_length)
        {
            block_sz = *pActual_data_length - icx;
            bLast = TRUE;
        }

        if(!CryptDecrypt(m_hDESKey, NULL, bLast, 0, (BYTE*)cipherbuf+icx, &block_sz))
            return GetLastError();

        bnSize += block_sz;
    }

    *pActual_data_length = bnSize;

    return 0;
}
Удачи тебе, браток!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.