Giáo trình 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
– 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.
20 trang |
Chia sẻ: huongthu9 | Lượt xem: 498 | Lượt tải: 0
Bạn đang xem nội dung tài liệu Giáo trình 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 về máy bạn click vào nút DOWNLOAD ở trên
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
Các file đính kèm theo tài liệu này:
- giao_trinh_lap_trinh_an_toan_chuong_5_ham_bam_va_xac_thuc_th.pdf