Giáo trình Lập trình An toàn - Chương 4: Mã hóa đối xứng - Lương Ánh Hoàng

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.

pdf26 trang | Chia sẻ: huongthu9 | Lượt xem: 554 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Giáo trình Lập trình An toàn - Chương 4: Mã hóa đối xứng - Lương Ánh Hoàng, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Lương  Ánh  Hoàng   hoangla@soict.hut.edu.vn   Chương  4.  Mã  hóa  đối  xứng   Symmetric  Crytography   4.1  Biểu  diễn  khóa  4.2  Chuyển  đổi  chuỗi  hexa  và  khóa  nhị  phân.  4.3  Mã  hóa  và  giải  mã  Base64    4.4  Các  phương  pháp  mã  hóa  đối  xứng  4.5  Mã  hóa  đối  xứng  với  OpenSSL  4.6  Mã  hóa  đối  xứng  với  Microsoft  Crypto  API   Nội  dung   56   •  Khóa  đối  xứng:    Một  số  rất  lớn  sử  dụng  để  mã  hóa  và  giải  mã  thông  điệp.   •  Biểu  diễn  khóa:   •  Phân  tách  thành  các  byte  và  lưu  dưới  dạng  một  mảng.   unsigned  char    key[KEYLEN_BYTES]   •  Biểu  diễn  dưới  dạng  số  nguyên  lớn  nếu  khóa  có  chiều  dài  64-­‐bit   long            long              key   •  Biểu  diễn  dưới  dạng  chuỗi  chữ  số  hexa    char  key[]=“AF12B5C7E0”   •  Biểu  diễn  dưới  dạng  xâu  ASCII  (mật  khẩu).    char  key[]=“secret!!!”   •  Lưu  ý  về  tính  “endian”  của  máy  thực  hiện  mã  hóa.   4.1  Biểu  diễn  khóa   57   •  Chuyển  đổi  khóa  nhị  phân  sang  dạng  chuỗi  chữ  số  hexa    #define  MAX_KEY_LEN  32    unsigned  char  key[MAX_KEY_LEN];    char    result[MAX_KEY_LEN*2+1];    for  (int  i=0;i<MAX_KEY_LEN;i++)      sprintf(result+i*2,"%2X",key[i]);    printf("Key:%s",result);     4.2  Chuyển  đổi  chuỗi  hexa  và  khóa  nhị   phân     58   •  Chuyển  đổi  chuỗi  hexa  sang  khóa  nhị  phân   char  Hex2Dec(char  c)   {            if  (('a'<=c)&&(c<='z'))  return  c  -­‐  'a'+10;            if  (('A'<=c)&&(c<='Z'))  return  c  -­‐  'A'+10;            if  (('0'<=c)&&(c<='9'))  return  c  -­‐  '0';            return  -­‐1;   }   #define  MAX_KEY_LENGTH  32     char  hexa[]="AF125C4D8E";   unsigned  char  key[MAX_KEY_LENGTH];   int  keylen  =  strlen(hexa);   char  c1,c2;   if  ((keylen%2!=0)||(keylen/2  >     MAX_KEY_LENGTH))   printf("Invalid  key  length");   keylen  =  keylen/2;   for  (int  i=0;i<keylen;i++)   {    c1  =  Hex2Dec(hexa[i*2]);    c2  =  Hex2Dec(hexa[i*2+1]);    if  ((c1==-­‐1)||(c2==-­‐1))    {                      printf("Invalid  character  !!!");                      break;    };    key[i]  =  (c1<<4)|c2;   };     4.2  Chuyển  đổi  chuỗi  hexa  và  khóa  nhị   phân     59   •  Mã  hóa  Base64       •  Sử  dụng  6-­‐bit  để  mã  hóa  dữ  liệu  và  biểu  diễn  dưới  dạng  các  chữ  cái  ASCII.   •  Cứ  3  byte  dữ  liệu  vào  sẽ  được  biểu  diễn  thành  4  byte  dữ  liệu  ra.   •  Các  ký  tự  ra  nằm  trong  khoảng:     •  ‘A’  –  ‘Z’  tương  đương  các  giá  trị  của  từ  mã  từ  0-­‐25.   •  ‘a’  –  ‘z’  tương  đương  các  giá  trị  của  từ  mã  từ  26-­‐51.   •  ‘0’-­‐  ‘9’  tương  đương  các  giá  trị  từ  mã  từ  52-­‐61.   •  ‘+’  ,  ‘-­‐’  tương  ứng  với  các  giá  trị  mã  62,63.   •  Nếu  dữ  liệu  vào  có  kích  thước  không  chia  hết  cho  3  sẽ  thì  được  thêm  vào  bằng  ký  tự  ‘=‘.   •  VD    Dữ  liệu  gốc:  ‘A’  –  0100.0001    Dữ  liệu  mã  hóa  dạng  Base64:  010000.010000.000000.000000  ~  QQ==    Dữ  liệu  gốc:  ‘AA’  –  0100.0001.0100.0001    Dữ  liệu  mã  hóa  dạng  Base64:  010000.010100.000100.000000  ~  QUE=    Dữ  liệu  gốc:  ‘AAA’  –  0100.0001.0100.0001.0100.0001    Dữ  liệu  dạng  mã  hóa  Base64:  010000.010100.000101.000001  ~  QUFB                         4.3  Mã  hóa  và  giải  mã  Base64   60   •  Mã  hóa  Base64                           4.3  Mã  hóa  và  giải  mã  Base64   61   Value   Char   Value   Char   Value   Char   Value   Char   0   A   16   Q   32   g   48   w   1   B   17   R   33   h   49   x   2   C   18   S   34   i   50   y   3   D   19   T   35   j   51   z   4   E   20   U   36   k   52   0   5   F   21   V   37   l   53   1   6   G   22   W   38   m   54   2   7   H   23   X   39   n   55   3   8   I   24   Y   40   o   56   4   9   J   25   Z   41   p   57   5   10   K   26   a   42   q   58   6   11   L   27   b   43   r   59   7   12   M   28   c   44   s   60   8   13   N   29   d   45   t   61   9   14   O   30   e   46   u   62   +   15   P   31   f   47   v   63   /   •  Đoạn  chương  trình  mã  hóa  Base64:    P4.5  –  Secure  C  Programming  Cookbook   •  Đoạn  chương  trình  giải  mã  Base64:  P4.6  –  Secure  C  Programming  Cookbook   4.3  Mã  hóa  và  giải  mã  Base64   62   •  Mã  hóa  đối  xứng:  Sử  dụng  chung  một  khóa  cho  mã  hóa  và  giải  mã   •  Có  hai  loại:  Mã  khối  và  mã  dòng   •  Có  nhiều  chế  độ  mã  hóa:  ECB,  CBC,  CFB,  OFB,  CTR,  CWC     •  Có  nhiều  giải  thuật:     4.4  Các  phương  pháp  mã  hóa  đối  xứng   63   Cipher   Key  size   Speed[4]   Implementation   Notes   AES   128  bits[5]   14.1  cpb  in  asm,  22.6  cpb  in   C   Brian  Gladman's[6]   The  assembly  version  currently  works  only   on  Windows.   AES   128  bits   41.3  cpb   OpenSSL   Triple  DES   192  bits[7]   108.2  cpb   OpenSSL   SNOW  2.0   128  or  256  bits   6.4  cpb   Fast  reference   implementation[8]   This  implementation  is  written  in  C.   RC4   Up  to  256  bits   (usually  128  bits)   10.7  cpb   OpenSSL   Serpent   128,  192,  or  256  bits   35.6  cpb   Fast  reference   implementation   It  gets  a  lot  faster  on  64-­‐bit  platforms  and   is  at  least  as  fast  as  AES  in  hardware.   Blowfish   Up  to  256  bits   (usually  128  bits)   23.2  cpb   OpenSSL   •  Thư  viện  OpenSSL:  Thư  viện  mã  nguồn  mở,  mạnh  mẽ  và  dễ  sử  dụng.   •  OpenSSL  hỗ  trợ:   •  Nhiều  thuật  toán  mã  hóa:  AES,  DES  ,  3DES,  Blow}ish,  CAST,  Idea,  RC2,  RC5.   •  Nhiều  chế  độ  mã  hóa:  ECB,  CBC,  CFB,  OFB,  CTR   •  Mã  hóa  dòng:  RC4.   •  Các  giải  thuật  băm:  MD2,  MD4,  MD5,SHA-­‐1,SHA-­‐224,SHA-­‐256   •  MAC:  HMAC.  MDC2   •  Các  giải  thuật  mã  hóa  công  khai:  DH,  DSA,  RSA,  ECC   •  Sử  dụng  thư  viện:   •  Trên  Unix/Linux:  Tải  source  về  và  biên  dịch.  Kết  quả  là  }ile    libcrypto.[so/a],  libssl.[so/a]  và  các  }ile  .h  để  include  vào  chương  trình.   •  Trên  Windows:  Tải  bản  binary  đã  biên  dịch  sẵn:  libeay32.dll,  ssleay32.dll,  tệp  tiêu  đề  (.h)  và  tệp  thư  viện  (.lib).  Link   openssl.html     4.5  Mã  hóa  đối  xứng  với  OpenSSL   64   •  Giao  diện  OpenSSL  EVP   •  Là  API  mức  cao  của  OpenSSL,  cho  phép  truy  nhập  đến  các  thuật  toán  ở  mức  thấp  một  cách  tập  trung,  dễ  dàng.   •  Tệp  tiêu  đề  .   •  Tệp  thư  viện:  libeay32.lib,  ssleay32.lib   •  Mã  hóa  AES  với  OpenSSL  EVP.   •  Khởi  tạo  khóa,  vector  khởi  tạo,  salt  với  EVP_BytesToKey  hoặc  tự  chọn  một  bộ  Key,  IV  nào  đó.   •  Khởi  tạo  ngữ  cảnh  mã  hóa  với  hàm  EVP_EncryptInit_ex.   •  Khởi  tạo  ngữ  cảnh  giải  mã  với  hàm  EVP_DecryptInit_ex.   •  Mã  hóa  dữ  liệu  bằng  việc  liên  tục  gọi  hàm  EVP_EncryptUpdate,  kết  thúc  quá  trình  mã  hóa  bằng  hàm  EVP_EncryptFinal_ex.   •  Giải  mã  dữ  liệu  bằng  việc  liên  tục  gọi  hàm  EVP_DecryptUpdate,  kết  thúc  quá  trình  giải  mã  bằng  hàm  EVP_DecryptFinal_ex.   4.5  Mã  hóa  đối  xứng  với  OpenSSL   65   •  VD   •  Sinh  key  và  iv  bằng  hàm  EVP_BytesToKey   char          key[32];   char          iv[32];       char  *  key_data  =  “nopass”;     unsigned  int  salt[]  =  {12345,  54321};   EVP_BytesToKey(EVP_aes_256_cbc(),  EVP_sha1(),  salt,  key_data,  6,  1,  key,   iv);   •  Khởi  tạo  ngữ  cảnh  mã  hóa  với  key  và  iv  đã  chọn   EVP_CIPHER_CTX  e_ctx;   EVP_CIPHER_CTX_init(&e_ctx);   EVP_EncryptInit_ex(&e_ctx,  EVP_aes_256_cbc(),NULL,  key,  iv);   •  Khởi  tạo  ngữ  cảnh  giải  mã  với  key  và  iv  đã  chọn   EVP_CIPHER_CTX  d_ctx;   EVP_CIPHER_CTX_init(&d_ctx);   EVP_DecryptInit_ex(&d_ctx,  EVP_aes_256_cbc(),NULL,  key,  iv);   4.5  Mã  hóa  đối  xứng  với  OpenSSL   66   •  VD  (tiếp)   •  Mã  hóa  với  ngữ  cảnh  đã  được  khởi  tạo   char  *    plaintext=“Hello”;   int  len  =  strlen(plaintext);   char  ciphertext[1024];   int    c_len  =  0,  f_len  =  0;   /*  Gọi  lại  hàm  này  để  cho  phép  OpenSSL  sử  dụng  lại  ngữ  cảnh  phiên  mã     hóa  trước  */   EVP_EncryptInit_ex(e,  NULL,  NULL,  NULL,  NULL);   //  Mỗi  chu  kỳ  Update,  c_len  sẽ  chứa  số  byte  của  xâu  mã  được   EVP_EncryptUpdate(e,  ciphertext,  &c_len,  plaintext,  len);   //  Cuối  chu  kỳ  Update,  f_len  sẽ  chưa  số  byte  còn  lại  của  xâu  mã   EVP_EncryptFinal_ex(e,  ciphertext+c_len,  &f_len);   4.5  Mã  hóa  đối  xứng  với  OpenSSL   67   •  VD  (tiếp)   •  Giải  mã  với  ngữ  cảnh  đã  được  khởi  tạo   char  plaintext[1024];   int  p_len  =  0;   /*  Gọi  lại  hàm  này  để  cho  phép  OpenSSL  sử  dụng  lại  ngữ  cảnh  phiên  giãi   mã    hóa  trước  */   EVP_DecryptInit_ex(e,  NULL,  NULL,  NULL,  NULL);   //  Giải  mã  với  ciphertext  và  len  được  cung  cấp  trước   EVP_DecryptUpdate(e,  plaintext,  &p_len,  ciphertext,  *len);   //  Kết  thúc  quá  trình  giải  mã,  cập  nhật  dữ  liệu  còn  lại  vào  plaintext.   EVP_DecryptFinal_ex(e,  plaintext+p_len,  &f_len);   4.5  Mã  hóa  đối  xứng  với  OpenSSL   68   •  Thư  viện  CryptoAPI   •  Cung  cấp  các  hàm  mật  mã  học  cơ  bản  thông  qua  các  Cryptographic  Service  Providers  (CSP).     •  Microsoft  Base  Cryptographic  Service  Provider:  RC2,  RC4,  DES   •  Microsoft  Enhanced  Cryptographic  Service  Provider:  Triple-­‐DES   •  Microsoft  AES  Cryptographic  Service  Provider:  AES   •    •  Cung  cấp  các  hàm  mã  hóa  và  giải  mã  chứng  thư  số,  và  đồng  thời  bổ  sung  các  hàm  băm.   •  Cung  cấp  các  hàm  quản  lý  và  lưu  trữ  chứng  thư  số.   •  Các  hàm  mã  thông  điệp  hóa  mức  cao  (Simpli}ied  Message  Functions).   •  Các  hàm  mã  hóa  thông  điệp  mức  thấp  (Low-­‐Level  Message  Functions).   4.6  Microsoft  Crypto  API   69   •  Thư  viện  CryptoAPI   4.6  Microsoft  Crypto  API   70   •  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.   •  Tệp  tiêu  đề  wincript.h   •  Thư  viện  Crypt32.lib   •  Trình  tự  sử  dụng     4.6  Microsoft  Crypto  API   71   Khởi  tạo   Provider   Tạo  khóa   • Ngẫu  nhiên   • Từ  mật  khẩu   • Từ  bên  ngoài   Đặt  chế  độ  mã   • CBC   • ECB   •    Thiết  lập  vector   khởi  tạo   Thực  hiện  Mã   hóa/Giải  mã   •  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.   •  Khởi  tạo  ngữ  cảnh  Provider  thông  qua  hàm  CryptAcquireContext    BOOL  WINAPI  CryptAcquireContext(__out  HCRYPTPROV*  phProv,            __in  LPCTSTR  pszContainer,            __in  LPCTSTR  pszProvider,            __in  DWORD  dwProvType,            __in  DWORD  dwFlags  );  VD:   HCRYPTPROV    hProvider;   if  (!CryptAcquireContext(&hProvider,            0,            MS_ENH_RSA_AES_PROV,            PROV_RSA_AES,                                                        CRYPT_VERIFYCONTEXT))        return  0;       4.6  Microsoft  Crypto  API   72   •  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;   4.6  Microsoft  Crypto  API   73   •  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;      }   //  Tạo  key  từ  giá  trị  băm  của  mật  khẩu   bResult  =  CryptDeriveKey(hProvider,  CALG_AES_256,  hHash,  CRYPT_EXPORTABLE,   &hKey);     CryptDestroyHash(hHash);     4.6  Microsoft  Crypto  API   74   •  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);     LocalFree(pbTemp);     4.6  Microsoft  Crypto  API   75   •  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   76   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);   //  Lấy  thông  tin  về  giải  thuật  mã  hóa  với  key  cho  trước      if  (!CryptGetKeyParam(hKey,  KP_ALGID,  (BYTE  *)&Algid,  &dwDataLen,  0))      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.   •  Mã  hóa  với  CryptEncrypt     4.6  Microsoft  Crypto  API   77   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   78   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   79   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   CryptDecrypt(hKey,0,TRUE,0,pbResult,&dwDataLen);   •  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.     4.6  Microsoft  Crypto  API   80  

Các file đính kèm theo tài liệu này:

  • pdfgiao_trinh_lap_trinh_an_toan_chuong_4_ma_hoa_doi_xung_luong.pdf