VD: HCRYPTPROV hProvider;

Một phần của tài liệu slike bài giảng lập trình an toàn lương ánh hoàng (Trang 72 - 81)

Chương 4 Mã hóa đối xứng

VD: HCRYPTPROV hProvider;

HCRYPTPROV    hProvider;   if  (!CryptAcquireContext(&hProvider,            0,            MS_ENH_RSA_AES_PROV,            PROV_RSA_AES,                                                        CRYPT_VERIFYCONTEXT))  

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

•  Sử  dụng  Key  thông  qua  một  trong  ba  hàm.  Kết  quả  trả  về  là  đối  tượng   HCRYPTKEY  

•  CryptGenKey(  ):  Sinh  khóa  ngẫu  nhiên.  

•  CryptDeriveKey(  ):  Sinh  khóa  từ  mật  khẩu.  

•  CryptImportKey(  )  :  Sinh  khóa  từ  một  đối  tượng  trong  bộ  nhớ.  

 

VD1.  Sinh  khóa  ngẫu  nhiên  

 

DWORD  dwFlags;     HCRYPTKEY  hKey;    

DWORD  dwSize  =  256;    

dwFlags  =  ((dwSize  <<  16)  &  0xFFFF0000)  |  CRYPT_EXPORTABLE;    

if  (!CryptGenKey(hProvider,  CALG_AES_256,  dwFlags,  &hKey))  return  0;  

     

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

VD2.  Sinh  khóa  từ  mật  khẩu:  Cần  phải  băm  mật  khẩu  và  truyền  vào  hàm  CryptDeriveKey  

char    *  password  =  “nopass”;      

BOOL  bResult;     DWORD  cbData;    

HCRYPTKEY  hKey;      //  Lưu  Key  

HCRYPTHASH  hHash;    //  Lưu  giá  trị  băm  của  mật  khẩu  

if  (!CryptCreateHash(hProvider,  CALG_SHA1,  0,  0,  &hHash))  //  Khởi  tạo  hàm  băm  

 return  0;    

cbData  =  lstrlen(password)  *  sizeof(TCHAR);    

if  (!CryptHashData(hHash,  (BYTE  *)password,  cbData,  0))    //  Băm  mật  khẩu  

 {    

   CryptDestroyHash(hHash);    

   return  0;      }  

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

•  Thiết  lập  chế  độ  mã  hóa  CBC  với  hàm  CryptSetKeyParam  

 DWORD  dwMode  =  CRYPT_MODE_CBC;  

 CryptSetKeyParam(hKey,  KP_MODE,  (BYTE  *)&dwMode,  0);  

•  Sinh  ngẫu  nhiên  vector  khởi  tạo  (IV)  

BOOL  bResult;        //  Lưu  kết  quả  

BYTE  *pbTemp;      //  Lưu  vector  khởi  tạo  

DWORD  dwBlockLen,  dwDataLen;     dwDataLen  =  sizeof(dwBlockLen);  

//  Lấy  kích  thước  block  của  thuật  toán  mã  hóa  

 if  (!CryptGetKeyParam(hKey,  KP_BLOCKLEN,  (BYTE  *)&dwBlockLen,  &dwDataLen,   0))  return  0;  

dwBlockLen  /=  8;    

if  (!(pbTemp  =  (BYTE  *)LocalAlloc(LMEM_FIXED,  dwBlockLen)))    return  FALSE;  

//  Sinh  ngẫu  nhiên  IV    

bResult  =  CryptGenRandom(hProvider,  dwBlockLen,  pbTemp);  

//  Thiết  lập  IV  

bResult  =  CryptSetKeyParam(hKey,  KP_IV,  pbTemp,  0);    

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

•  Mã  hóa  với  CryptEncrypt  

•  Với  các  giải  thuật  mã  hóa  dòng  thì  kích  thước  dữ  liệu  ra  =  kích  thước  dữ  liệu  vào.  

•  Với  các  giải  thuật  mã  hóa  khối  thì  kích  thước  dữ  liệu  ra  <=    kích  thước  dữ  liệu  vào   +  kích  thước  khối.  

•  Hàm  CryptEncrypt  sẽ  ghi  đè  dữ  liệu  mã  hóa  được  vào  bộ  đệm  chứa  dữ  liệu  vào.  

•  Đoạn  chương  trình  thực  hiện  mã  hóa  chung  cho  cả  hai  loại.  

4.6  Microsoft  Crypto  API  

ALG_ID  Algid;      //  Giải  thuật  mã  

char  *  pbData  =  "Hello  CryptAPI";    //  Xâu  nguồn  cần  mã  

char  *  pbResult  =  0;    //  Xâu  kết  quả  

DWORD  dwDataLen  =  0,dwBlockLen  =  0;  

 cbData  =  strlen(pbData);  //  Chiều  dài  xâu  nguồn  

   dwDataLen  =  sizeof(ALG_ID);  

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

•  Mã  hóa  với  CryptEncrypt    

4.6  Microsoft  Crypto  API  

if  (GET_ALG_TYPE(Algid)  !=  ALG_TYPE_STREAM)    //  Mã  hóa  khối  

   {  

         dwDataLen  =  sizeof(DWORD);      

         ret  =  CryptGetKeyParam(hKey,    KP_BLOCKLEN,  (BYTE*)&dwBlockLen,          &dwDataLen,  0);  //  Lấy  kích  thước  block  theo  bit  

 dwBlockLen  =  dwBlockLen/8;  //  Đổi  kích  thước  block  ra  đơn  vị  byte  

   //  Cấp  phát  bộ  nhớ  để  chứa  kết  quả      

 pbResult  =  (char*)malloc(cbData+dwBlockLen);    memcpy(pbResult,pbData,cbData);  

 //  Thực  hiện  mã  hóa,  kết  quả  là  dwDataLen  byte  lưu  trong  pbResult  

 dwDataLen  =  cbData;    

 CryptEncrypt(hKey,  0,  TRUE,  0,  (BYTE*)pbResult,  &dwDataLen,      

   cbData+16))  ;  

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

•  Mã  hóa  với  CryptEncrypt  (tiếp)    

4.6  Microsoft  Crypto  API  

else  //  Mã  hóa  dòng  

{  

 //  Cấp  phát  bộ  nhớ  lưu  kết  quả  

 pbResult  =  (char*)malloc(cbData);    //  Bảo  toàn  dữ  liệu  nguồn  

 memcpy(pbResult,pbData,cbData);    //  Thực  hiện  mã  hóa  

 CryptEncrypt(hKey,0,TRUE,0,pbResult,&dwDataLen,cbData);    

•  Sử  dụng  thư  viện  CryptoAPI  để  thực  hiện  mã  hóa  đối  xứng  thông  điệp   với  thuật  toán  AES.  

•  Giải  mã  với  CryptDecrypt  

•  Kích  thước  dữ  liệu  đích  <=  kích  thước  dữ  liệu  nguồn  

•  Thực  hiện  đơn  giản  hơn  so  với  CryptEncrypt  

•  Ví  dụ    

4.6  Microsoft  Crypto  API  

char  *  pbData  ;      //  Dữ  liệu  nguồn  

DWORD  cbData;    //  Kích  thước  nguồn  

char  *  pbResult;      //  Dữ  liệu  đích  

DWORD  dwDataLen;  //  Kích  thước  đích  

…  

//  Cấp  phát  bộ  nhớ  và  sao  chép  dữ  liệu  nguồn  vào  đích  

pbResult  =  (char*)malloc(cbData);   memcpy(pbResult,  pbData,  cbData);   dwDataLen  =  cbDataLen;  

//  Giải  mã,  kết  quả  là  dwDataLen  byte  lưu  trong  pbResult  

•  Trao  đổi  khóa  với  OpenSSL  

•  CryptoAPI  không  cho  phép  nhập  và  xuất  khóa  dạng  thô  như  OpenSSL.  

•  Để  trao  đổi  khóa  với  thư  viện  khác,  cần  mã  hóa  khóa  theo  giải  thuật   AT_KEYEXCHANGE,  và  thực  hiện  nhập  xuất  dưới  dạng  cấu  trúc  BLOB.  

•  Hàm  CryptImportKeyvà  CryptExportKey  dùng  để  thực  hiện  nhập  xuất   khóa.  

•  Xem  thêm  phần  5.26,  5.27  trong  Secure  Programming  Cookbook.    

Lương  Ánh  Hoàng  

hoangla@soict.hut.edu.vn  

Một phần của tài liệu slike bài giảng lập trình an toàn lương ánh hoàng (Trang 72 - 81)

Tải bản đầy đủ (PDF)

(131 trang)