CryptoAPI 로 DES 암호 화 복호화 실현

3341 단어 복호화
#include 
#include 
#include 
 
BOOL DES(__in const BYTE* pbKey,
         __in DWORD cbKeyLen,
         __in const BYTE* pbData,
         __in DWORD cbDataLen,
         __out BYTE* pbBuf,
         __inout DWORD* pcbBufLen,
         __in BOOL bIsDecrypt = FALSE  
         )
/*
  DES  、    ,  PKCS 5 padding,CBC  
 
    :
  pbKey       DES  
  cbKeyLen    pbKey    
  pbData         、     
  cbDataLen   pbData    
  pbBuf            ,     、      ,   NULL
  pcbBufLen   pbBuf    
                 pbBuf  NULL ,       pbBuf     
                 pbBuf NULL ,     pbBuf    
  bIsDecrypt   TRUE       ,        
 
    :
      TRUE,    FALSE
*/
{
  struct
  {
    BLOBHEADER hdr;
    DWORD cbKeySize;
    BYTE rgbKeyData[8];
  } keyBlob;    //    MSDN - CryptImportKey
 
  keyBlob.hdr.bType = PLAINTEXTKEYBLOB;
  keyBlob.hdr.bVersion = CUR_BLOB_VERSION;
  keyBlob.hdr.reserved = 0;
  keyBlob.hdr.aiKeyAlg = CALG_DES;
  keyBlob.cbKeySize = 8;
  ZeroMemory(keyBlob.rgbKeyData, 8);
  CopyMemory(keyBlob.rgbKeyData, pbKey, cbKeyLen > 8 ? 8 : cbKeyLen);
 
  HCRYPTPROV hProv;
  if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
    return FALSE;
 
  HCRYPTKEY hKey;
  if (!CryptImportKey(hProv, (BYTE*)&keyBlob, sizeof(keyBlob), 0, 0, &hKey))
  {
    CryptReleaseContext(hProv, 0);
    return FALSE;
  }
 
  BOOL bRet;
  BYTE pbBlock[16];
  DWORD dwBlock, dwOut = 0;
  BOOL bEOF;
  for (DWORD i = 0; i < cbDataLen; i += 8)
  {
    bEOF = cbDataLen - i <= 8;    //       
    dwBlock = bEOF ? cbDataLen - i : 8;
 
    CopyMemory(pbBlock, pbData + i, dwBlock);    //    、  ,  8  
    if (bIsDecrypt)
      bRet = CryptDecrypt(hKey, NULL, bEOF, 0, pbBlock, &dwBlock);
    else
      bRet = CryptEncrypt(hKey, NULL, bEOF, 0, pbBlock, &dwBlock, sizeof(pbBlock));
 
    if (!bRet)
      break;
 
    if (pbBuf)
    {
      if (dwOut + dwBlock > *pcbBufLen)
      {
        bRet = FALSE;
        break;
      } 
      else
      {
        CopyMemory(pbBuf + dwOut, pbBlock, dwBlock);
        dwOut += dwBlock;
      }
    } 
    else    // pbBuf NULL ,        pbBuf
      dwOut += dwBlock;
  }
 
  *pcbBufLen = dwOut;
  CryptDestroyKey(hKey);
  CryptReleaseContext(hProv, 0);
 
  return bRet;
}
 
int _tmain()
{
  BYTE pbKey[] = "1204",
    pbPlain[] = "StarsunYzL";
  DWORD dwLen;
 
  DES(pbKey, 4, pbPlain, 10, NULL, &dwLen);  //            
 
  BYTE* pbCipher = new BYTE[dwLen];
  DES(pbKey, 4, pbPlain, 10, pbCipher, &dwLen);  //  
 
  for (size_t i = 0; i != dwLen; ++i)
    _tprintf(_T("%02X"), pbCipher[i]);
  _tprintf(_T("\r
")); ZeroMemory(pbPlain, sizeof(pbPlain)); DES(pbKey, 4, pbCipher, dwLen, pbPlain, &dwLen, TRUE); // delete [] pbCipher; for (size_t i = 0; i != dwLen; ++i) _tprintf(_T("%c"), pbPlain[i]); _tprintf(_T("\r
")); return 0; }

테스트:키:1204 데이터:StarsunYzl 암호 화 결과:CA3C24E48DD8AA 551 E98F3A 989 D38A 49
이 코드 는 PKCS 5 padding 을 사용 합 니 다.인터넷 의 일부 알고리즘 테스트 도 구 는 ZERO padding 을 사용 하기 때문에 얻 은 결 과 는 반드시 같 지 않 습 니 다.마이크로소프트 가 제공 하 는 CSP 는 ZERO padding 을 지원 하지 않 습 니 다.ZERO padding 을 사용 하려 면 마지막 그룹 수 를 8 바이트 로 보충 한 후에 암호 화하 고 암호 화 결과 의 8 바이트 데이터 만 가 져 와 야 합 니 다.왜냐하면 뒷 8 바이트 가 많이 나 오 는 패 딩 이 니까.

좋은 웹페이지 즐겨찾기