Chương 2 : HẠ TẦNG MOBILE PKI
3.2. XÂY DỰNG ỨNG DỤNG KÝ SỐ TRÊN HỆ ĐIỀU HÀNH ANDROID
3.2.3. Xây dựng chương trình
- Giao diện đăng nhập hệ thống
Hình 3.7: Giao diện đăng nhập hệ thống
- Giao diện chính của chương trình
- Giao diện ký số
Hình 3.9: Giao diện ký số
- Giao diện mã hóa
- Giao diện giải mã
Hình 3.11: Giao diện chức năng giải mã
- Giao diện xác thực
Hình 3.12: Giao diện chức năng xác thực
3.2.3.2. Các module chương trình - Mơ hình tạo chữ ký số
Input: đường đẫn tập tin *. P12 + mật khẩu truy cập file *. P12 + đường dẫn tập tin cần ký + đường dẫn tập tin lưu chữ ký.
Output: File chữ ký số (*.sig) Mã chương trình:
public void sign(String spath_pkcs12, String smatkhau, String spath_file, String spath_sigFile){
byte[] signature = null;
File f_file = new File(spath_file); int size_file = (int) f_file.length(); byte[] contentfile = new byte[size_file]; try {
//đọc nội dung tập tin vào mảng contentfile
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(f_file));
buf.read(contentfile, 0, contentfile.length); buf.close();
//lấy khóa bí mật trong P12
PrivateKey prk = module.get_privatekey(spath_pkcs12, smatkhau); //Khởi tạo instance SHA1withRSA để ký
Signature dsa = Signature.getInstance("SHA1withRSA"); dsa.initSign(prk);
dsa.update(contentfile, 0, contentfile.length); signature = dsa.sign();
//ghi chữ ký vào tập tin
File f_sigFile = new File(spath_sigFile); if(!f_sigFile.exists()) {
f_sigFile.createNewFile(); }
FileOutputStream o_sigFile = new FileOutputStream(f_sigFile,
false);
o_sigFile.write(signature); o_sigFile.flush();
o_sigFile.close();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); module.my_messagebox(dlgAlert, "Ký số thành công"); } catch (Exception e) { Log.d(TAG, "Error"); } }
Trong đoạn mã trên sử dụng thư viện hàm băm SHA1 để lấy giá trị file đầu vào => chữ ký tạo ra bởi khóa bí mật + giá trị băm và được ghi ra file *.sig
- Mơ hình mã hóa
Input: đường dẫn chứng thư số + đường dẫn tập tin để mã hóa + đường dẫn để lưu tập tin mã hóa.
Mã chương trình:
public void encrypt(String spath_cert, String spath_file, String spath_encFile){
byte[] plaintext = null; byte[] cipherText = null; try {
//đọc tập tin để mã hóa
plaintext = module.readFiletoBytes(spath_file); PublicKey puk = module.get_publickey(spath_cert); //khởi tạo instance RSA
final Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, puk);
cipherText = cipher.doFinal(plaintext); File f_enfile = new File(spath_encFile); if(!f_enfile.exists()) {
f_enfile.createNewFile(); }
FileOutputStream o_encFile = new FileOutputStream(f_enfile,
false);
o_encFile.write(cipherText); o_encFile.flush();
o_encFile.close();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); module.my_messagebox(dlgAlert, "Mã hóa thành cơng");
} catch (Exception e) { Log.d(TAG, "Error"); } } - Mơ hình giải mã
Input: đường dẫn tập tin *.P12 + mật khẩu truy cập file *.P12 + đường tập tin mã hóa + đường dẫn lưu tập tin giải mã.
Output: File dữ liệu đã giải mã Mã chương trình:
public void decrypt(String spath_pkcs12, String smatkhau, String spath_encFile, String spath_decFile) {
byte[] cipherText = null; byte[] dectyptedText = null; try {
// lấy khóa bí mật trong P12
PrivateKey prk = module.get_privatekey(spath_pkcs12, smatkhau); cipherText = module.readFiletoBytes(spath_encFile);
//khởi tạo instance RSA
final Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, prk);
dectyptedText = cipher.doFinal(cipherText); //lưu nội dung đã giải mã ra tập tin
File f_decryptedFile = new File(spath_decFile); if(!f_decryptedFile.exists()) {
f_decryptedFile.createNewFile(); }
o_encFile.write(dectyptedText); o_encFile.flush();
o_encFile.close();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); module.my_messagebox(dlgAlert, "Giải mã thành công");
} catch (Exception ex) { Log.d(TAG, "Error"); }
}
- Mơ hình xác thực
Input: đường dẫn chứng thư số + đường dẫn tập tin lưu chữ ký số + đường dẫn tập tin gốc
Output: Tính đúng đắn của chữ ký số Mã chương trình:
public void verify(String spath_cert, String spath_sig, String spath_plain)
{
byte[] contentfile = null; byte[] signature = null; try {
//đọc tập tin gốc và tập tin chữ ký số
contentfile = module.readFiletoBytes(spath_plain); signature = module.readFiletoBytes(spath_sig); //Lấy khóa cơng khai trong chứng thư số
PublicKey puk = module.get_publickey(spath_cert);
Signature dsa = Signature.getInstance("SHA1withRSA"); //khởi tạo instance SHA1withRSA để xác thực
dsa.initVerify(puk); //nhập khoa công khai
dsa.update(contentfile, 0, contentfile.length); //xác thực AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); if (!dsa.verify(signature)) {
module.my_messagebox(dlgAlert, "Chữ ký không đúng"); Log.e(TAG,"Signature verification failed.");
} else {
module.my_messagebox(dlgAlert, "Chữ ký chính xác"); Log.e(TAG, "Signature verification true.");
} } catch (Exception e) { Log.d(TAG, "Error"); } } KẾT LUẬN CHƯƠNG 3
Chương trình ứng dụng chạy rất tốt trên hệ điều hành android 4.0 trở lên. Tuy nhiên chương trình demo vẫn chưa xây dựng được xác thực thơng qua hạ tầng PKI bên ngồi. Đây sẽ là hướng phát triển của chương trình ứng dụng.
PHỤ LỤC
1. Giao diện chính
Hình: Giao diện ứng dụng
Ứng dụng này có 4 chức năng chính là: ký số, xác thực, mã hóa, xác thực 2. Mã nguồn của một số module
2.1. Mã nguồn một số hàm liên quan
2.1.1. Hàm lấy khóa cơng khai trong chứng thư số
public static PublicKey get_publickey(String spath_chungchiso){ PublicKey puk = null;
try {
FileInputStream fin = new FileInputStream(spath_chungchiso); CertificateFactory f = CertificateFactory.getInstance("X.509"); Certificate certificate = f.generateCertificate(fin);
puk = certificate.getPublicKey(); fin.close();
}
catch (Exception e) { //thong bao loi Log.d(TAG, "Error"); }
return puk; }
2.1.2. Hàm lấy khóa bí mật trong P12
spath_PKCS12: đường đẫn tập tin P12 smatkhau: mật khẩu mở P12
public static PrivateKey get_privatekey(String spath_PKCS12, String smatkhau){
PrivateKey prk = null; try {
FileInputStream f_chungchiso = new FileInputStream(spath_PKCS12);
InputStream in_chungchiso = new BufferedInputStream(f_chungchiso);
KeyStore keystore = KeyStore.getInstance("PKCS12"); keystore.load(in_chungchiso, smatkhau.toCharArray());
Enumeration enum1 = keystore.aliases();
String sAlias = (String) enum1.nextElement(); while (enum1.hasMoreElements()) {
sAlias = (String) enum1.nextElement(); } prk = (PrivateKey) (keystore.getKey(sAlias, smatkhau.toCharArray())); f_chungchiso.close(); } catch (Exception e) { //thong bao loi Log.d(TAG, "Error"); }
return prk; }
2.2. Mã nguồn thực hiện ký
spath_pkcs12: đường đẫn tập tin P12 smatkhau: mật khẩu mở P12
spath_file: đường dẫn tập tin để ký
spath_sigFile: đường dẫn tập tin lưu chữ ký
public void sign(String spath_pkcs12, String smatkhau, String spath_file, String spath_sigFile){
byte[] signature = null;
File f_file = new File(spath_file); int size_file = (int) f_file.length(); byte[] contentfile = new byte[size_file]; try {
//đọc nội dung tập tin vào mảng contentfile
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(f_file));
buf.read(contentfile, 0, contentfile.length); buf.close();
//lấy khóa bí mật trong P12
PrivateKey prk = module.get_privatekey(spath_pkcs12, smatkhau); //Khởi tạo instance SHA1withRSA để ký
Signature dsa = Signature.getInstance("SHA1withRSA"); dsa.initSign(prk); //nhập khóa bí mật
dsa.update(contentfile, 0, contentfile.length); //nhập nội dung để ký
signature = dsa.sign(); //ký số và chữ ký được trả về và lưu vào signature
//ghi chữ ký vào tập tin
File f_sigFile = new File(spath_sigFile); if(!f_sigFile.exists()) {
f_sigFile.createNewFile(); }
FileOutputStream o_sigFile = new FileOutputStream(f_sigFile,
false);
o_sigFile.write(signature); o_sigFile.flush();
o_sigFile.close();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); module.my_messagebox(dlgAlert, "Ký số thành công"); } catch (Exception e) { Log.d(TAG, "Error"); } } 2.3. Mã nguồn thực hiện xác thực chữ ký
spath_cert: đường dẫn chứng thư số
spath_sig: đường dẫn tập tin lưu chữ ký số spath_plain: đường dẫn tập tin gốc
public void verify(String spath_cert, String spath_sig, String spath_plain)
{
byte[] contentfile = null; byte[] signature = null;
try {
//đọc tập tin gốc và tập tin chữ ký số
contentfile = module.readFiletoBytes(spath_plain); signature = module.readFiletoBytes(spath_sig); //Lấy khóa cơng khai trong chứng thư số
PublicKey puk = module.get_publickey(spath_cert);
Signature dsa = Signature.getInstance("SHA1withRSA"); //khởi tạo instance SHA1withRSA để xác thực
dsa.initVerify(puk); //nhập khoa công khai
dsa.update(contentfile, 0, contentfile.length); //xác thực AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); if (!dsa.verify(signature)) {
module.my_messagebox(dlgAlert, "Chữ ký không đúng"); Log.e(TAG,"Signature verification failed.");
} else {
module.my_messagebox(dlgAlert, "Chữ ký chính xác"); Log.e(TAG, "Signature verification true.");
} }
catch (Exception e) { Log.d(TAG, "Error"); }
2.3. Mã nguồn thực hiện mã hóa
spath_cert: đường dẫn chứng thư số spath_file: đường dẫn tập tin để mã hóa
spath_encFile: đường dẫn để lưu tập tin mã hóa
public void encrypt(String spath_cert, String spath_file, String spath_encFile){
byte[] plaintext = null; byte[] cipherText = null; try {
//đọc tập tin để mã hóa
plaintext = module.readFiletoBytes(spath_file); PublicKey puk = module.get_publickey(spath_cert); //khởi tạo instance RSA
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, puk);//nhập khóa cơng khai cipherText = cipher.doFinal(plaintext); //mã hóa, kết quả được trả về và lưu trong cipherText
//ghi nội dung cipherText ra tập tin File f_enfile = new File(spath_encFile); if(!f_enfile.exists()) {
f_enfile.createNewFile(); }
FileOutputStream o_encFile = new FileOutputStream(f_enfile,
false);
o_encFile.write(cipherText); o_encFile.flush();
o_encFile.close();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); module.my_messagebox(dlgAlert, "Mã hóa thành cơng");
}
catch (Exception e) { Log.d(TAG, "Error"); }
}
2.3. Mã nguồn thực hiện giải mã
spath_pkcs12: đường dẫn tập tin P12 smatkhau: mật khẩu mở P12
spath_encFile: đường tập tin mã hóa
spath_decFile: đường dẫn lưu tập tin giải mã
public void decrypt(String spath_pkcs12, String smatkhau, String spath_encFile, String spath_decFile) {
byte[] cipherText = null; byte[] dectyptedText = null; try {
// lấy khóa bí mật trong P12
PrivateKey prk = module.get_privatekey(spath_pkcs12, smatkhau); cipherText = module.readFiletoBytes(spath_encFile);
//khởi tạo instance RSA
final Cipher cipher = Cipher.getInstance("RSA");
dectyptedText = cipher.doFinal(cipherText);//giải mã và kết quả được lưu vào mảng dectyptedText
//lưu nội dung đã giải mã ra tập tin
File f_decryptedFile = new File(spath_decFile); if(!f_decryptedFile.exists()) {
f_decryptedFile.createNewFile(); }
FileOutputStream o_encFile = new FileOutputStream(f_decryptedFile, false); o_encFile.write(dectyptedText); o_encFile.flush();
o_encFile.close();
AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this); module.my_messagebox(dlgAlert, "Giải mã thành công");
} catch (Exception ex) { Log.d(TAG, "Error"); }
KẾT LUẬN
Mobile PKI là một bộ phận mở rộng của hệ thống PKI truyền thống. Đó cũng là một cơ chế để cho một bên thứ ba (thường là nhà cung cấp chứng thư số) đáng tin cậy cung cấp và xác thực định danh các bên tham gia vào quá trình trao đổi thông tin. Mobile PKI là một hệ thống tương đối lớn và phức tạp còn nhiều hạn chế về cấu hình và cơ sở hạ tầng mạng. Hơn nữa với điều kiện thực tế tại Việt Nam vẫn chưa có cơ sở hạ tầng Mobile PKI hồn chỉnh. Do đó việc tìm hiểu, nghiên cứu và nắm vững về Mobile PKI gặp nhiều khó khăn.
Tuy nhiên trong thời gian thực hiện đề tài em đã nghiên cứu và tìm hiểu về Mobile PKI và thu được một số kết quả sau:
Về lý thuyết em đã tìm hiểu và nắm vững các vấn đề sau:
Các kiến thức cơ bản về hạ tầng khóa cơng khai - PKI và các mơ hình kiến trúc và các giải pháp an toàn đối với hệ thống PKI.
Tìm hiểu tổng quan về hệ thống Mobile PKI cũng như các ứng dụng của Mobile PKI trong thương mại điện tử, các giải pháp ứng dụng hạ tầng PKI trên điện thoại di động được sử dụng hiện nay. Về mặt thực nghiệm, luận văn đã thực hiện được các kết quả sau:
Xây dựng phần mềm ký số và xác thực đơn giản trên hệ điều hành Android với ngôn ngữ Java.
Mã hóa, ký số, giải mã, xác thực chứng thư số.
Vì đây là một cơng nghệ mới, chưa được triển khai sâu rộng tại Việt Nam, nên mặc dù đã đạt được mục tiêu đề ra của luận văn nhưng những kết quả thu được chỉ ở mức độ tìm hiểu. Luận văn còn nhiều hạn chế như ứng dụng xây dựng mới chỉ kiểm tra được tính tồn vẹn của dữ liệu mà chưa kiểm tra tình trạng chứng thư qua OCSP hoặc CRL, bài toán lưu chứng thư số trên thiết bị di động chưa thực sự an toàn, việc gán nhãn thời gian chưa thực hiện được. Hướng phát triển của luận văn được đưa ra là hoàn thiện ứng dụng ký số và xác thực trên điện thoại di động có sự xác thực thơng qua hạ tầng PKI bên ngồi đáng tin cậy. Giải quyết bài toàn kiểm tra tình trạng chứng thư trực tuyến qua giao thức OCSP và CRL, từ đó đánh giá chính xác hơn khả năng áp dụng trong thực tiễn, xây dựng thuật toán ký số bằng một thuật toán tối ưu hơn.
Em rất mong nhận được những góp ý và sự chỉ bảo của các thầy cô cùng các bạn để em hồn thiện luận văn của mình và có thể tiếp tục nghiên cứu sâu hơn về Mobile PKI nhằm đưa ra các giải pháp an toàn, thiết thực và hiệu quả. Một lần nữa em xin chân thành cảm ơn TS. Nguyễn Viết Thế đã nhiệt tình giúp đỡ em trong suốt thời gian thực hiện luân văn này.
TÀI LIỆU THAM KHẢO Tiếng Việt
1. TS. Hồ Văn Hương, KS. Hoàng Chiến Thắng-Cục QLKTNVMM, Ban Cơ
yếu Chính phủ, Ký số và xác thực trên nền tảng web, Tạp trí An tồn thơng
tin, số 2 (026) năm 2013.
2. Hồ Văn Hương, Hoàng Vĩnh Hà, Cao Thị Linh, Trịnh Văn Anh, Mobile PKI và ứng dụng trong thực tế, Kỷ yếu Hội nghị Quốc gia Một số vấn đề chọn
lọc của Công nghệ thông tin lần thứ XVII, năm 2014.
3. Hồ Văn Hương, Hoàng Chiến Thắng, Nguyễn Quốc Uy, Giải pháp bảo mật
và xác thực cho văn phòng điện tử, Hội nghị Quốc gia về điện tử và truyền
thông (REV 2013-KC01).
4. Hồ Văn Hương, Hoàng Chiến Thắng, Nguyễn Quốc Uy, Giải pháp bảo mật
và xác thực thư điện tử, Tạp chí An tồn thơng tin số 04 (028), 2013.
5. Hồ Văn Hương, Hồng Vĩnh Hà, Ngơ Thị Linh, Trịnh Văn Anh, Hộ chiếu
điện tử và ứng dụng chữ ký số cho Hộ chiếu điện tử, Kỷ yếu hội thảo Khoa
học cơng nghệ và an tồn thơng tin, lần thứ nhất, 12/ 2014.
6. Nguyen Thi Hoang Lan et al, “Nghiên cứu xây dựng hệ thống kiểm soát truy cập mạng và an ninh thông tin dựa trên sinh trắc học sử dụng công nghệ nhúng”, 2010, KC.01.11/06-10.
7. ThS. Lê Quang Hùng, Hạ tầng PKI di động và tích hợp dịch vụ chứng chực điện tử cho thiết bị đi động, Tạp trí An tồn thơng tin, năm 2012.
8. http://vi.wikipedia.org/ Tiếng Anh
9. Carlisle Adams & Steve Lloyd, Understanding PKI: Concepts, Standards and Deployment Considerations, Addison-Wesley, 2003.
10. Suranjan Choudhury, Kartik Bhatnagar, and Wasim Haque, Public Key Infrastructure Implementation and Design, Published by M&T Books.
11. Yong Lee a,*, Jeail Lee a, JooSeok Song b, Design an implementation of wireless PKI technology suitable for mobile phone in mobile-commerce,
Received 1 May 2006.
12. William Stallings, Cryptography and Network Security Principles and Practices, Fourth Edition, 2005.
13. Wireless Public Key Infrastructure for Mobile Phones, International Journal
of Network Security & Its Applications (IJNSA), Vol.4, No.6, November 2012.