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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

MicroSoft CryptoAPI data/file encrypt/decrypt

發(fā)布時(shí)間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MicroSoft CryptoAPI data/file encrypt/decrypt 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

linux 用第三方庫(kù) Crypto++, 還未實(shí)戰(zhàn)。

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

?

#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, //這個(gè)參數(shù)這里用的是缺省值,指得是缺省得CSP模塊,你也可以傳入一個(gè)LPCTSTR類型的字符串,指定CSP模塊 ??

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

);

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

?

二. 創(chuàng)建密鑰

1. 根據(jù)固定password, 主要用于對(duì)稱加密

        //初始化一個(gè)HASH對(duì)象,產(chǎn)生一個(gè)空的HASH對(duì)象

CryptCreateHash( ??

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

  CALG_MD5, //指定的hash算法

  0, ??

  0, ??

  &hHash? //hash句柄

);

//對(duì)數(shù)據(jù)使用hash后, 保存在hHash中

CryptHashData( ??

  hHash, ??

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

  lstrlen(pszPassword), ??

  0

);

//利用hash對(duì)象生成密鑰

CryptDeriveKey(? //從某一數(shù)據(jù)產(chǎn)生會(huì)話密鑰。有點(diǎn)類似CryptGenKey,但是產(chǎn)生的會(huì)話密鑰來(lái)自固定數(shù)據(jù),而CryptGenKey是隨機(jī)產(chǎn)生的。并且不能產(chǎn)生公 / 私鑰對(duì) ??

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

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

  hHash, //in,HASH對(duì)象的句柄 ??

  KEYLENGTH, //in,指定產(chǎn)生密鑰的類型 ??

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

?

2. 隨機(jī)產(chǎn)生, 每次產(chǎn)生都不一樣,解密時(shí),要根據(jù)獲取的blob解密, 主要用于非對(duì)稱加密

//產(chǎn)生一個(gè)隨機(jī)的交換密鑰或者公/私鑰對(duì)

CryptGenKey(?

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

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

  KEYLENGTH | CRYPT_EXPORTABLE, //表示密鑰使用的長(zhǎng)度,參數(shù)可以為0,采用默認(rèn)的密鑰長(zhǎng)度 ??

  &hKey? //獲取密鑰句柄

);

?

//獲取交換密鑰

CryptGetUserKey( ??

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

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

  &hXchgKey? //獲取交換密鑰

);

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

a. 導(dǎo)出密鑰只是先獲取導(dǎo)出key Blob的長(zhǎng)度

CryptExportKey( ??

  hKey, //需要導(dǎo)出的密鑰句柄 ??

  hXchgKey, //將待導(dǎo)出密鑰用交換密鑰進(jìn)行加密,假如是公開的BLOG當(dāng)然就設(shè)置為0 ??

  SIMPLEBLOB, // 指定導(dǎo)出的密鑰BLOB類型,BLOB也就是一種存儲(chǔ)結(jié)構(gòu)。六個(gè)參數(shù)見MSDN ??

  0, ??

  NULL, //導(dǎo)出的數(shù)據(jù)指針,以后就可以將這個(gè)數(shù)據(jù)寫如磁盤或者別的任務(wù) ??

  &dwKeyBlobLen? //導(dǎo)出的數(shù)據(jù)長(zhǎng)度

);

b. 為Blob分配內(nèi)存

  pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen);

c. 用交換密鑰加密后,存儲(chǔ)到Blob

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

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

  CryptDestroyKey(hXchgKey);

//創(chuàng)建導(dǎo)出的Keyblob目標(biāo)文件

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

//將keyblob長(zhǎng)度保存到文件中

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

//將keyblob內(nèi)容寫入

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

free(pbKeyBlob);

?

3. 根據(jù)key產(chǎn)生固定的blob產(chǎn)生, 用于對(duì)稱加密

#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;??? //結(jié)構(gòu)參考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)) ?

  {

  }

}

?

三. 解密

經(jīng)過(guò)一和二,the session key(會(huì)話密鑰)就創(chuàng)建好了,如果不是隨機(jī)產(chǎn)生出來(lái)的,the session key(會(huì)話密鑰)就被寫到文件中或保存起來(lái)以便解密時(shí)用

由password或key產(chǎn)生的hKey, 可由CrytImportKey導(dǎo)入

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

?

?四. 代碼

1. 根據(jù)key產(chǎn)生固定的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;??? //結(jié)構(gòu)參考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. 根據(jù)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. 隨機(jī)產(chǎn)生hKey, 每次都不一樣

來(lái)自微軟的例子。

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

?

轉(zhuǎn)載于:https://www.cnblogs.com/henryliublog/p/10287327.html

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。