Bài giảng Lập trình an toàn - Chương 5: Hàm băm và xác thực thông điệp - Lương Ánh Hoàng
5.1 Các hàm băm và MAC thông dụng
Hàm băm (hashes). - Nhận đầu vào là một xâu và đầu ra là một chuỗi bit có chiều dài xác
định. - Tỉ lệ đụng độ rất nhỏ. - Dùng để kiểm tra tính toàn vẹn của dữ liệu nhưng không đảm bảo
tính xác thực của dữ liệu. - Thường kết hợp với mô hình mã hóa công khai chứ không sử dụng
một mình. - Các giải thuật bằm thông dụng: MD5, SHA1
Bạn đang xem tài liệu "Bài giảng Lập trình an toàn - Chương 5: Hàm băm và xác thực thông điệp - Lương Ánh Hoàng", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Bài giảng Lập trình an toàn - Chương 5: Hàm băm và xác thực thông điệp - Lương Ánh Hoàng
Lương Ánh Hoàng hoangla@soict.hut.edu.vn Chương 5. Hàm băm và xác thực thông điệp Hashes and Message Authentication 5.1 Các loại hàm băm và MAC thông dụng 5.2 Băm với OpenSSL 5.3 Băm dữ liệu với CryptoAPI 5.4 Xác thực thông điệp với HMAC 5.5 Salt Nội dung 82 • Hàm băm (hashes) – Nhận đầu vào là một xâu và đầu ra là một chuỗi bit có chiều dài xác định. – Tỉ lệ đụng độ rất nhỏ. – Dùng để kiểm tra tính toàn vẹn của dữ liệu nhưng không đảm bảo tính xác thực của dữ liệu. – Thường kết hợp với mô hình mã hóa công khai chứ không sử dụng một mình. – Các giải thuật băm thông dụng: MD5, SHA1 5.1 Các hàm băm và MAC thông dụng 83 • Hàm băm (hashes) 5.1 Các hàm băm và MAC thông dụng 84 Algorithm Digest size Security conqidence Small message speed (64 bytes), in cycles per byte[2] Large message speed (8K), in cycles per byte Uses block cipher Davies-‐Meyer-‐ AES-‐128 128 bits (same length as cipher block size) Good 46.7 cpb 57.8 cpb Yes MD2 128 bits Good to low 392 cpb 184 cpb No MD4 128 bits Insecure 32 cpb 5.8 cpb No MD5 128 bits Very low, may be insecure 40.9 cpb 7.7 cpb No MDC-‐2-‐AES-‐128 256 bits Very high 93 cpb 116 cpb Yes MDC-‐2-‐DES 128 bits Good 444 cpb 444 cpb Yes RIPEMD-‐160 160 bits High 62.2 cpb 20.6 cpb No SHA1 160 bits High 53 cpb 15.9 cpb No SHA-‐256 256 bits Very high 119 cpb 116 cpb No SHA-‐384 384 bits Very high 171 cpb 166 cpb No SHA-‐512 512 bits Very high 171 cpb 166 cpb No • Xác thực thông điệp (Message Authentication Code) – Nhận đầu vào là một xâu và một khóa bí mật, đầu ra là một mã có chiều dài xác định. – Dùng để kiểm tra tính toàn vẹn và xác thực của dữ liệu. – Các giải thuật thông dụng: OMAC, CMAC, HMAC 5.1 Các hàm băm và MAC thông dụng 85 • Xác thực thông điệp (Message Authentication Code) 5.1 Các hàm băm và MAC thông dụng 86 MAC Built upon Small message speed (64 bytes)[4] Large message speed (8K) Appropriate for hardware Patent restric-‐ tions Parallel-‐izable CMAC A universal hash and AES ~18 cpb ~18 cpb Yes No Yes HMAC-‐SHA1 Message digest function 90 cpb 20 cpb Yes No No MAC127 hash127 + AES ~6 cpb ~6 cpb Yes No Yes OMAC1 AES 29.5 cpb 37 cpb Yes No No OMAC2 AES 29.5 cpb 37 cpb Yes No No PMAC-‐AES Block cipher 72 cpb 70 cpb Yes Yes Yes RMAC Block cipher 89 cpb 80 cpb Yes No No UMAC32 UHASH and AES 19 cpb cpb No No Yes XMACC-‐SHA1 Any cipher or MD function 162 cpb 29 cpb Yes Yes Yes • OpenSSL cung cấp hai loại giao diện với các hàm băm – Giao diện riêng rẽ với mỗi giải thuật băm cụ thể. • Mỗi giải thuật băm có tệp tiêu đề riêng • Tên gọi các hàm là khác nhau cho các giải thuật băm. – Giao diện chung EVP cho mọi loại hàm băm. • Tệp tiêu đề chung: • Trình tự sử dụng như nhau: – Khởi tạo ngữ cảnh: EVP_DigestInit – Cập nhật dữ liệu băm: EVP_DigestUpdate – Lấy kết quả: EVP_DigestFinal. 5.2 Băm dữ liệu với OpenSSL 87 • VD: Băm với SHA1 5.2 Băm dữ liệu với OpenSSL 88 #include int i; SHA_CTX ctx; unsigned char result[SHA_DIGEST_LENGTH]; /* SHA1 has a 20-‐byte digest. */ unsigned char *s1 = (unsigned char*)"Testing"; unsigned char *s2 = (unsigned char*)"...1...2...3..."; SHA1_Init(&ctx); SHA1_Update(&ctx, s1, strlen((char*)s1)); SHA1_Update(&ctx, s2, strlen((char*)s2)); /* Yes, the context object is last. */ SHA1_Final(result, &ctx); printf("SHA1(\"%s%s\") = ", s1, s2); for (i = 0; i < SHA_DIGEST_LENGTH; i++) printf("%02x", result[i]); printf("\n"); • VD: Băm với giao diện EVP 5.2 Băm dữ liệu với OpenSSL 89 #include #include #include int i , ol; EVP_MD_CTX ctx; unsigned char *result; unsigned char *s1 = (unsigned char*)"Testing"; unsigned char *s2 = (unsigned char*)"...1...2...3..."; EVP_DigestInit(&ctx, EVP_sha1()); EVP_DigestUpdate(&ctx, s1, strlen((char*)s1)); EVP_DigestUpdate(&ctx, s2, strlen((char*)s2)); if (!(result = (unsigned char *)malloc(EVP_MD_CTX_block_size(&ctx))))abort(); EVP_DigestFinal(&ctx, result, &ol); printf("SHA1(\"%s%s\") = ", s1, s2); for (i = 0; i < ol; i++) printf("%02x", result[i]); printf("\n"); free(result); • Trình tự băm với CryptoAPI – Tệp tiêu đề: Wincrypt.h – Khởi tạo ngữ cảnh Provider: CryptAcquireContext – Tạo đối tượng hash: CryptCreateHash – Băm liên tiếp với: CryptHashData – Lấy kết quả: CryptGetHashParam – Giải phóng đói tượng hash: CryptDestroyHash 5.3 Băm dữ liệu với CryptoAPI 90 • Ví dụ: Băm dữ liệu với thuật toán SHA-‐256 5.3 Băm dữ liệu với CryptoAPI 91 BYTE *pbData; DWORD cbData = sizeof(DWORD), cbHashSize, i; HCRYPTHASH hSHA256; HCRYPTPROV hProvider; unsigned char *s1 = (unsigned char*)"Testing"; unsigned char *s2 = (unsigned char*)"...1...2...3..."; // Khởi tạo ngữ cảnh Provider CryptAcquireContext(&hProvider, 0, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0); // Tạo đối tượng hàm băm CryptCreateHash(hProvider, CALG_SHA_256, 0, 0, &hSHA256); // Thực hiện băm CryptHashData(hSHA256, s1, strlen((char*)s1), 0); CryptHashData(hSHA256, s2, strlen((char*)s2), 0); // Thực hiện băm • Ví dụ: Băm dữ liệu với thuật toán SHA-‐256 (tiếp) 5.3 Băm dữ liệu với CryptoAPI 92 // Lấy kích thước dữ liệu băm được CryptGetHashParam(hSHA256, HP_HASHSIZE, (BYTE *)&cbHashSize, &cbData, 0); pbData = (BYTE *)LocalAlloc(LMEM_FIXED, cbHashSize); // Lấy dữ liệu băm được CryptGetHashParam(hSHA256, HP_HASHVAL, pbData, &cbHashSize, 0); // Giải phóng đối tượng băm và ngữ cảnh Provider CryptDestroyHash(hSHA256); CryptReleaseContext(hProvider, 0); printf("SHA256(\"%s%s\") = ", s1, s2); for (i = 0; i < cbHashSize; i++) printf("%02x", pbData[i]); printf("\n"); LocalFree(pbData); • Với OpenSSL – Tệp tiêu đều – Gọi hàm HMAC_Init để khởi tạo ngữ cảnh và key sẽ sử dụng – Liên tục gọi hàm HMAC_Update để cập nhật dữ liệu. – Gọi hàm HMAC_Final để kết thúc quá trình băm – Gọi hàm HMAC_cleanup để xóa key khỏi bộ nhớ. – Có thể gọi hàm All-‐in-‐one HMAC – Bên nhận kiểm tra lại bằng cách thực hiện băm với với cùng một key và giải thuật và so sánh kết quả 5.4 Xác thực thông điệp với HMAC 93 • Với OpenSSL 5.4 Xác thực thông điệp với HMAC 94 int i; HMAC_CTX ctx; unsigned int len; unsigned char out[20]; unsigned char * key = (unsigned char*)"secret"; int keylen = strlen((char*)key); // Khởi tạo HMAC với key là secret HMAC_Init(&ctx, key, keylen, EVP_sha1( )); // Thực hiện băm xâu "fr HMAC_Update(&ctx, (unsigned char*)"hash me pls", 11); // Lấy kết quả HMAC_Final(&ctx, out, &len); for (i = 0; i < len; i++) printf("%02x", out[i]); printf("\n"); • Với CryptAPI – Tạo đối tượng Hash với hàm CryptCreateHash, trong đó tham số hKey là một key đã được tạo trước. – Thiết lập thông tin về giải thuật băm với hàm CryptSetHashParam. – Thực hiện băm với hàm CryptHashData – Lấy kích thước, nội của dữ liệu băm được với hàm CryptGetHashParam. – Giải phóng đói tượng Hash và Key 5.4 Xác thực thông điệp với HMAC 95 • Với CryptAPI 5.4 Xác thực thông điệp với HMAC 96 BYTE out[20]; DWORD cbData = sizeof(out), i; HCRYPTKEY hKey; HMAC_INFO HMACInfo; HCRYPTHASH hHash; HCRYPTPROV hProvider; // Lấy ngữ cảnh provider CryptAcquireContext(&hProvider,0,MS_ENH_RSA_AES_PROV,PROV_RSA_AES,CRYPT_VERIFYCONTEXT); // Sinh key từ mật khẩu hKey = CreateKeyFromPassword(hProvider,"secret"); // Tạo đối tượng băm CryptCreateHash(hProvider, CALG_HMAC, hKey, 0, &hHash); • Với CryptAPI 5.4 Xác thực thông điệp với HMAC 97 // Thiết lập giải thuật băm HMACInfo.HashAlgid = CALG_SHA1; HMACInfo.pbInnerString = HMACInfo.pbOuterString = 0; HMACInfo.cbInnerString = HMACInfo.cbOuterString = 0; CryptSetHashParam(hHash, HP_HMAC_INFO, (BYTE *)&HMACInfo, 0); // Thực hiện băm CryptHashData(hHash, (BYTE *)"Hash me plz", 11, 0); // Lấy kết quả CryptGetHashParam(hHash, HP_HASHVAL, out, &cbData, 0); for (i = 0; i < cbData; i++) printf("%02x", out[i]); printf("\n"); CryptDestroyHash(hHash); CryptDestroyKey(hKey); CryptReleaseContext(hProvider, 0); • Salt – Chuỗi dữ liệu thêm vào để tăng không gian khóa và chống lại hình thức replay-‐attack. – Hai bên có thể thỏa thuận chung một salt nào đó thay đổi theo thời gian. – Salt thường được thêm vào đầu thông điệp gốc, sau đó thực hiện băm cả salt cả thông điệp. 5.5 Sử dụng Salt 98 1. Viết chương trình mã hóa và giải mã tệp tin bằng giải thuật AES-‐256 bit. Mật khẩu nhập từ bàn phím. Kiểm tra tính đúng đắn của kết quả bằng giải thuật SHA-‐256. Sử dụng thư viện OpenSSL. Khuôn dạng dữ liệu của tệp tin sau khi mã hóa có thể như sau: 2. Viết chương trình chat client-‐server đơn giản trong đó kênh truyền được mã hóa theo giải thuật AES-‐256. Key được sinh ra từ mật khẩu thỏa thuận trước và không truyền qua mạng, Vector khởi tạo là mã BCD được thiết lập từ ngày và giờ hiện tại của hệ thống (Hàm API GetSystemTime). Ví dụ: Nếu hiện tại là 07h ngày 10/10/2011 thì giá trị dưới dạng hexa của vector khởi tạo là 2011101007000.00 Bài tập 99 3. Viết chương trình băm nội dung một }ile bằng giải thuật HMAC-‐AES256, sử dụng thư viện OpenSSL. Mật khẩu để băm nhập từ bàn phím.Kết quả băm được lưu vào cuối }ile. 4. Viết chương trình kiểm tra tính toàn vẹn của một }ile bằng giải thuật HMAC-‐AES256. Mật khẩu để kiểm tra nhập từ bàn phím. Bài tập 100
File đính kèm:
- bai_giang_lap_trinhantoan_chuong_5_ham_bam_va_xac_thuc_thong.pdf