日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MicroSoft CryptoAPI data/file encrypt/decrypt

發布時間:2025/3/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MicroSoft CryptoAPI data/file encrypt/decrypt 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

linux 用第三方庫 Crypto++, 還未實戰。

CryptoAPI使用兩種密鑰:會話密鑰與公共/私人密鑰對。會話密鑰使用相同的加密和解密密鑰,這種算法較快,但必須保證密鑰的安全傳遞。公共/私人密鑰對使用一個公共密鑰和一個私人密鑰,私人密鑰只有專人才能使用,公共密鑰可以廣泛傳播。如果密鑰對中的一個用于加密,另一個一定用于解密。公共/私人密鑰對算法很慢,一般只用于加密小批數據,例如用于加密會話密鑰。

?

#include <tchar.h> #include <stdio.h> #include <windows.h> #include <wincrypt.h>

//#include <conio.h>

//#pragma comment (lib, "advapi32")

#define KEYLENGTH? 0x00800000

#define ENCRYPT_ALGORITHM CALG_RC4?

#define ENCRYPT_BLOCK_SIZE 8

?

常用步驟:

一. 獲取容器handle

CryptAcquireContext( ??

   &hCryptProv, //返回的CSP句柄,密鑰容器 ??

   NULL,?? //密鑰容器的名字 ??

   MS_ENHANCED_PROV, //這個參數這里用的是缺省值,指得是缺省得CSP模塊,你也可以傳入一個LPCTSTR類型的字符串,指定CSP模塊 ??

   PROV_RSA_FULL, //這里為使用的加密策略 ??0

);

返回true, 則正常; false, 則異常

?

二. 創建密鑰

1. 根據固定password, 主要用于對稱加密

        //初始化一個HASH對象,產生一個空的HASH對象

CryptCreateHash( ??

  hCryptProv,?? //密鑰容器句柄 ??

  CALG_MD5, //指定的hash算法

  0, ??

  0, ??

  &hHash? //hash句柄

);

//對數據使用hash后, 保存在hHash中

CryptHashData( ??

  hHash, ??

  (BYTE *)pszPassword,?? //LPTSTR pszPassword ??

  lstrlen(pszPassword), ??

  0

);

//利用hash對象生成密鑰

CryptDeriveKey(? //從某一數據產生會話密鑰。有點類似CryptGenKey,但是產生的會話密鑰來自固定數據,而CryptGenKey是隨機產生的。并且不能產生公 / 私鑰對 ??

  hCryptProv,?? //密鑰容器句柄 ??

  ENCRYPT_ALGORITHM, //in,指定的算法,類似CryptGenKey ??

  hHash, //in,HASH對象的句柄 ??

  KEYLENGTH, //in,指定產生密鑰的類型 ??

  &hKey);??? //in, out, 產生的密鑰句柄地址

?

2. 隨機產生, 每次產生都不一樣,解密時,要根據獲取的blob解密, 主要用于非對稱加密

//產生一個隨機的交換密鑰或者公/私鑰對

CryptGenKey(?

  hCryptProv,?? //密鑰容器句柄 ??

  ENCRYPT_ALGORITHM,? //表明產生私鑰所使用的算法或者公鑰生成的算法 ??

  KEYLENGTH | CRYPT_EXPORTABLE, //表示密鑰使用的長度,參數可以為0,采用默認的密鑰長度 ??

  &hKey? //獲取密鑰句柄

);

?

//獲取交換密鑰

CryptGetUserKey( ??

  hCryptProv,?? //密鑰容器句柄 ??

  AT_KEYEXCHANGE, //AT_KEYEXCHANGE(交換密鑰) or AT_SIGNATURE(簽名密鑰) ??

  &hXchgKey? //獲取交換密鑰

);

//以下3步是用交換密鑰將密鑰加密后,存儲到Blob

a. 導出密鑰只是先獲取導出key Blob的長度

CryptExportKey( ??

  hKey, //需要導出的密鑰句柄 ??

  hXchgKey, //將待導出密鑰用交換密鑰進行加密,假如是公開的BLOG當然就設置為0 ??

  SIMPLEBLOB, // 指定導出的密鑰BLOB類型,BLOB也就是一種存儲結構。六個參數見MSDN ??

  0, ??

  NULL, //導出的數據指針,以后就可以將這個數據寫如磁盤或者別的任務 ??

  &dwKeyBlobLen? //導出的數據長度

);

b. 為Blob分配內存

  pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen);

c. 用交換密鑰加密后,存儲到Blob

  CryptExportKey( ???hKey, ???hXchgKey, ???SIMPLEBLOB, ???0, ???pbKeyBlob, ???&dwKeyBlobLen);

//釋放交換密鑰 if(hXchgKey) ?

  CryptDestroyKey(hXchgKey);

//創建導出的Keyblob目標文件

  hexportkeyDestinationFile ?= CreateFile(pszexportkeyDestination, ??FILE_WRITE_DATA, ??FILE_SHARE_READ, ??NULL, ??OPEN_ALWAYS, ??FILE_ATTRIBUTE_NORMAL, ??NULL);

//將keyblob長度保存到文件中

  WriteFile( ??hexportkeyDestinationFile, ??&dwKeyBlobLen, ??sizeof(DWORD), ??&dwCount, ??NULL)

//將keyblob內容寫入

  WriteFile( ???hexportkeyDestinationFile, ???pbKeyBlob, ???dwKeyBlobLen, ???&dwCount, ???NULL);

free(pbKeyBlob);

?

3. 根據key產生固定的blob產生, 用于對稱加密

#define ENCRYPT_ALGORITHM CALG_DES

#define ENCRYPT_BLOCK_SIZE 8

#define KEYSIZE 8

typedef struct _stKeyBlob

{ ?

  BLOBHEADER hdr; ?

  DWORD cbKeySize; ?

  BYTE rgbKeyData[KEYSIZE];

  ?_stKeyBlob() ?

  { ??

    hdr.bType = PLAINTEXTKEYBLOB; ??

    hdr.bVersion = CUR_BLOB_VERSION; ??

    hdr.reserved = 0; ??

    hdr.aiKeyAlg = ENCRYPT_ALGORITHM; ??

    cbKeySize = KEYSIZE; ??

    memset(rgbKeyData, 0, KEYSIZE); ?

  }

} stKeyBlobType;??? //結構參考MSDN - CryptImportKey

?

XML_EnDecryption::XML_EnDecryption(BYTE pbKey[], DWORD dwKeyLen)

{

?  init(); ?m_pstKeyBlob = new stKeyBlobType(); ?

  ?memcpy(m_pstKeyBlob->rgbKeyData, pbKey, dwKeyLen > KEYSIZE ? KEYSIZE : dwKeyLen);

  ?if (!CryptImportKey(m_hProv, (BYTE*)m_pstKeyBlob, sizeof(stKeyBlobType), 0, 0, &m_hKey)) ?

  {

  }

}

?

三. 解密

經過一和二,the session key(會話密鑰)就創建好了,如果不是隨機產生出來的,the session key(會話密鑰)就被寫到文件中或保存起來以便解密時用

由password或key產生的hKey, 可由CrytImportKey導入

CryptImportKey(m_hProv, (BYTE*)m_pstKeyBlob, sizeof(stKeyBlobType), 0, 0, &m_hKey)); //獲取key句柄

?

?四. 代碼

1. 根據key產生固定的blob

#ifndef _XMLENCDEC_H_EFOFWEJOSDJFJ3933F3F894FJ3F23OFJ230FJFJWEFJWWEFWE

#define _XMLENCDEC_H_EFOFWEJOSDJFJ3933F3F894FJ3F23OFJ230FJFJWEFJWWEFWE

#include <tchar.h>

#include <stdio.h>

#include <windows.h>

#include <wincrypt.h>

//#include <conio.h>

//#pragma comment (lib, "advapi32")

//#define KEYLENGTH? 0x00800000 #define ENCRYPT_ALGORITHM CALG_DES #define ENCRYPT_BLOCK_SIZE 8

#define KEYSIZE 8

typedef struct _stKeyBlob

{ ?

  BLOBHEADER hdr; ?

  DWORD cbKeySize; ?

  BYTE rgbKeyData[KEYSIZE];

?  _stKeyBlob() ?

  { ??

    hdr.bType = PLAINTEXTKEYBLOB; ??

    hdr.bVersion = CUR_BLOB_VERSION; ??

    hdr.reserved = 0; ??

    hdr.aiKeyAlg = ENCRYPT_ALGORITHM; ??

    cbKeySize = KEYSIZE; ??

    memset(rgbKeyData, 0, KEYSIZE); ?

  }

} stKeyBlobType;??? //結構參考MSDN - CryptImportKey

?

class XML_EnDecryption

{

public: ?

  XML_EnDecryption(BYTE pbKey[] = NULL, DWORD dwKeyLen = 0); ?

  virtual ~XML_EnDecryption();

?  void GetLastCryptError(LPTSTR psz, int nErrorNumber);

?  BOOL DES(__in const BYTE* pbData, __in DWORD cbDataLen, __out BYTE* pbBuf, __inout DWORD* pcbBufLen, __in BOOL bIsDecrypt = FALSE, __in BOOL isLast = TRUE);

?  void GetBufferLen(__in const BYTE* pbData, __in DWORD cbDataLen, DWORD* pBufferLen);

?  BOOL XmlEncDec(LPTSTR pszSourceFile, LPTSTR pszDestinationFile, BOOL isDecrypt = FALSE);

private: ? 

  bool init(); ?

  bool InitialCSP(); ?

  bool IsCSPValided(); ?

  bool ReleaseCSP();

private: ?

  HCRYPTPROV?m_hProv; ?

  bool??m_bAcquireContextOK;

?  HCRYPTKEY?m_hKey;

?  DWORD m_dwLastError;

?  stKeyBlobType* m_pstKeyBlob;

};

#endif? //_PUBLIC_H_EFOFWEJOSDJFJ3933F3F894FJ3F23OFJ230FJFJWEFJWWEFWE

?

2. 根據password, hash后得到hKey

#ifndef _XMLENCDEC_H_EFOFWEJOSDJFJ3933F3F894PEPROGEPROGPOEPWEOVWOEVOWEV

#define _XMLENCDEC_H_EFOFWEJOSDJFJ3933F3F894PEPROGEPROGPOEPWEOVWOEVOWEV

#include <tchar.h>

#include <stdio.h>

#include <windows.h>

#include <wincrypt.h>

//#include <conio.h>

//#pragma comment (lib, "advapi32")

?

#define KEYLENGTH? 0x00800000

#define ENCRYPT_ALGORITHM CALG_RC4?

#define ENCRYPT_BLOCK_SIZE 8

?

class XML_EnDecryption

{

public: ?

  XML_EnDecryption(LPTSTR m_pszPassword); ?

  virtual ~XML_EnDecryption();

?  void GetBufferLen(__in const BYTE* pbData, __in DWORD cbDataLen, DWORD* pBufferLen);

?  BOOL DES(__in const BYTE* pbData, __in DWORD cbDataLen, __out BYTE* pbBuf, __inout DWORD* pcbBufLen, __in BOOL bIsDecrypt = FALSE, __in BOOL isLast = TRUE);

?  BOOL XmlDes(LPTSTR pszSourceFile, LPTSTR pszDestinationFile, BOOL isDecrypt = FALSE);

?  void GetLastCryptError(LPTSTR psz, int nErrorNumber); ? private: //?int getKey(); ?bool HashPassword();

private: ?

  bool init(); ?

  bool ReleaseCSP(); ?

  bool InitialCSP(); ?

  bool IsCSPValided();

private: ?

  HCRYPTPROV?m_hProv; ?

  bool??m_bAcquireContextOK; ?

  HCRYPTHASH? m_hHash; ?

  HCRYPTKEY?m_hKey; ?

  DWORD m_dwLastError; ?

  LPTSTR m_pszPassword;

};

#endif? //_XMLENCDEC_H_EFOFWEJOSDJFJ3933F3F894PEPROGEPROGPOEPWEOVWOEVOWEV

?

3. 隨機產生hKey, 每次都不一樣

來自微軟的例子。

https://docs.microsoft.com/zh-cn/windows/desktop/SecCrypto/example-c-program-encrypting-a-file

https://docs.microsoft.com/zh-cn/windows/desktop/SecCrypto/example-c-program-decrypting-a-file

?

轉載于:https://www.cnblogs.com/henryliublog/p/10287327.html

總結

以上是生活随笔為你收集整理的MicroSoft CryptoAPI data/file encrypt/decrypt的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。