Chương 5. Hàm băm và xác thực thông điệp Hashes and Message Authentication Lương Ánh Hoàng hoangla@soict.hut.edu.vn
Nội dung
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
82
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
83
5.1 Các hàm băm và MAC thông dụng
• Hàm băm (hashes)
Algorithm Digest size Security conqidence Uses block cipher Small message speed (64 bytes), in cycles per byte[2] Large message speed (8K), in cycles per byte
46.7 cpb 57.8 cpb Good Yes Davies-‐Meyer-‐ AES-‐128 128 bits (same length as cipher block size)
MD2 128 bits Good to low 392 cpb No 184 cpb
MD4 128 bits Insecure 32 cpb No 5.8 cpb
MD5 128 bits 40.9 cpb No 7.7 cpb Very low, may be insecure
MDC-‐2-‐AES-‐128 256 bits Very high 93 cpb Yes 116 cpb
MDC-‐2-‐DES 128 bits Good 444 cpb Yes 444 cpb
RIPEMD-‐160 160 bits High 62.2 cpb No 20.6 cpb
SHA1 160 bits High 53 cpb No 15.9 cpb
SHA-‐256 256 bits Very high 119 cpb No 116 cpb
SHA-‐384 384 bits Very high 171 cpb No 166 cpb
84
SHA-‐512 512 bits Very high 171 cpb No 166 cpb
5.1 Các hàm băm và MAC thông dụng
• 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
85
5.1 Các hàm băm và MAC thông dụng
• Xác thực thông điệp (Message Authentication Code)
MAC
Built upon
Parallel-‐izable
Large message speed (8K)
Appropriate for hardware
Patent restric-‐ tions
Small message speed (64 bytes)[4]
CMAC
~18 cpb
~18 cpb
Yes
Yes
No
A universal hash and AES
HMAC-‐SHA1
90 cpb
20 cpb
Yes
No
No
Message digest function
MAC127
hash127 + AES ~6 cpb
~6 cpb
Yes
Yes
No
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
Yes
No
XMACC-‐SHA1
162 cpb
29 cpb
Yes
Yes
Yes
Any cipher or MD function
86
5.2 Băm dữ liệu với OpenSSL
• 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:
– 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.
87
5.2 Băm dữ liệu với OpenSSL
• VD:
Băm
với
SHA1
#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");
88
5.2 Băm dữ liệu với OpenSSL
• VD: Băm với giao diện EVP
#include
89
5.3 Băm dữ liệu với CryptoAPI
• 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
90
5.3 Băm dữ liệu với CryptoAPI
• Ví dụ: Băm dữ liệu với thuật toán SHA-‐256
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…
91
5.3 Băm dữ liệu với CryptoAPI
• Ví dụ: Băm dữ liệu với thuật toán SHA-‐256 (tiếp)
// 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);
92
5.4 Xác thực thông điệp với HMAC
• Với OpenSSL
– Tệp
tiêu
đều
giải thuật và so sánh kết quả
93
5.4 Xác thực thông điệp với HMAC
keylen = strlen((char*)key);
• Với OpenSSL int i; HMAC_CTX ctx; unsigned int len; unsigned char out[20]; unsigned char * key = (unsigned char*)"secret"; int // 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");
94
5.4 Xác thực thông điệp với HMAC
• 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
95
5.4 Xác thực thông điệp với HMAC
• Với CryptAPI 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);
96
5.4 Xác thực thông điệp với HMAC
• Với CryptAPI
// 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);
97
5.5 Sử dụng Salt
• 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.
98
Bài tập
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
99
Bài tập
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.
100