Chủ Nhật, 7 tháng 9, 2014

[Java Security] Phần 7 : Digital Signtures (Chữ ký điện tử)

Phần 7 : Digital Signtures (Chữ ký điện tử)
Ở  phần 6 Message Digest, trong phần ví dụ “bạn gởi thông điệp đến người môi giới chứng khoán để mua 500 cổ phần ABC” , thông điệp bạn gởi bằng Message Digest nên người môi giới chứng khoán biết chắc chắn đây là thông điệp chính xác. Vài ngày sau, người môi giới đến tìm bạn để lấy tiền, bạn ngạc nhiên “Tôi đâu có nhờ anh mua 500 cổ phần ABC”. Bạn lưu ý, message digest chỉ bảo đảm trên thông điệp từ người gởi đến người nhận không bị làm giả trong quá trình vận chuyển, chứ không đảm bảo trên người gởi, tức là không thể xác nhận được người gởi chính xác là ai.
Trên mặt pháp lý, mỗi người có chữ ký hoặc dấu vân tay để xác nhận bạn là ai, thì chữ ký điện tử cũng vậy được dùng để xác nhận chính xác bạn là ai trên từng thông điệp bạn gởi đi.
Digital signatures (DH) sử dụng thuật toán public-key với chiều ngược lại thông thường, tức là private-key được sử dụng để mã hóa và public-key được sử dụng để giải mã. Thuật toán này được thực hiện như sau:
- Bên gởi:
+ bước 1 : tạo ra message digest trên thông điệp muốn gởi
+ bước 2 : mã hóa message digest bằng private-key để cung cấp 1 digital signature trên thông điệp và gởi nó đi.
- Bên nhận :
+ bước 1 : giải mã digital signature bằng public-key để có được 1 message digest.
+ bước 2 : đem message digest này so sánh với message digest được tạo ra từ thông điệp chính.
Từ quá trình thực hiện phía trên của DH, bạn sẽ thấy các khả năng sau:
- Mạo nhận người gởi : không thể nào, bởi private key là bảo mật, chỉ có chính bạn mới có mà thôi
- Xác nhận người gởi : public-key luôn được công khai, bất cứ người nào có được public-key đều có thể xác nhận chính xác bạn là ai.
I. Thuật toán Digital Signature :
Digital Signature Algorithm (DSA) là một trong những thuật toán nổi tiếng về Digital Signature do NIST phát triển, nó thực hiện qua các bước:
+ Tạo khóa.
+ Tạo Digital Signature.
+ Xác nhận.
a. Tạo khóa :
- q là số nguyên tố có chiều dài khoảng 160 bits.
- p là số nguyên tố, sao cho p = qz+1  trong đó z là số nguyên bất kỳ từ 512 ->1024.
- g = h(p-1)/q mod p , trong đó h là số bất kỳ thỏa mãn 1<h<p-1 và g > 1
- x là một số nguyên ngẫu nhiên , thỏa mãn 0<x<q
- y=gx mod p
Trong đó :
+ Các giá trị p,q,g và y được công khai đến nhiều người dùng.
+ Public-key là y và private-key là x .
b. Tạo Digital Signature:
- k là một số ngẫu nhiên thỏa mãn 0 < k<q
- r  = (gk mod p) mod q
- s = (k-1(SHA-1(m) + x*r)) mod q , trong đó SHA-1(m) là hàm băm được mã hóa theo thuật toán SHA-1 trên thông điệp m.
- Digital Signature trên thông điệp m là (r,s).
c. Xác nhận :
- w = (s)-1 mod q
- u1 = (SHA-1(m)*w) mod q
- u2 = (r*w) mod q
- v = ((gu1*yu2) mod p) mod q
- Xác nhận thành công nếu v = r.
II. Digital Signature trong java:
Digital Signature được thực hiện trong java thông qua các class và Interface sau:
- class SignatureSpi : cho phép bạn định nghĩa thuật toán dành cho Digital Signature theo ý của bạn. (class này không cần thiết trong phần hướng dẫn nên chúng tôi không trình bày về class này, các bạn hãy tự nghiên cứu thêm).
- class Signature : cung cấp 1 sự thực hiện mặc định dành cho Digital Signature.
- class SignedObject : cung cấp khả năng để tạo các đối tượng được đăng ký (bên gởi) để bảo đảm tính toàn vẹn khi kiểm tra (bên nhận).
- class SignatureException : được sử dụng để miêu tả các lỗi xảy ra trong quá trình đăng ký và kiểm tra.
1. class Signature :
Class Signature kế thừa từ class SignatureSpi, cung cấp các đặc tính dành một thuật toán Digital Signature, nó hổ trợ cho cả bên gởi và bên nhận.
Đối tượng Signature của Class Signature được tạo bởi phương thức getInstace(), phương thức này nhận tham số đầu vào kiểu String là tên thuật toán dành cho class Signature, các giá trị dành cho kiểu String này là:
   Ví dụ :  Signature sign = Signature.getInstance(“SHA1withDSA”);
Một số phương thức khác của class Signature:
Ví dụ : cung cấp 1 thông điệp, private-key, public-key và sử dụng thuật toán DSA Digital Signature.

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

public class SignApp1 {
   public static void main(String[] args){
       try {
           //thong diep can goi
           String thongdiep = "Happy new year 2014";
           
           //cung cap public-key va private-key cho thuat toan Signature
           KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
           KeyPair keyPair = keyPairGenerator.generateKeyPair();
           PrivateKey privateKey = keyPair.getPrivate();
           PublicKey publicKey = keyPair.getPublic();
           
           //ten thuat toan danh cho Signature
           String tenthuattoan = "SHA1withDSA";
           
           //nguoi goi
           byte[] bSignature = sign_nguoigoi(thongdiep, tenthuattoan, privateKey);
           
           //nguoi nhan
           verify_nguoinhan(thongdiep, tenthuattoan, publicKey, bSignature);

       } catch (Exception ex) {
           System.out.println(ex.getMessage());
       }
   }
   
   /*phuong thuc sign_nguoigoi danh cho nguoi goi :
       - String thongdiep : thong diep can duoc goi.
       - String tenthuattoan : thuat toan danh cho digital signature
       - PrivateKey privateKey : được dùng để mã hóa Signature.
      Phương thức này trả về mảng byte đó là Digital signature, được gởi đến người nhận
   */
   public static byte[] sign_nguoigoi(String thongdiep,
                                                          String tenthuattoan, PrivateKey
                                                          privateKey){
       byte[] bSignature = null;
       try {
           Signature signature = Signature.getInstance(tenthuattoan);
           signature.initSign(privateKey);
        
           signature.update(thongdiep.getBytes());
           
           bSignature = signature.sign();

            System.out.println("Dang ky thanh cong !");
            return bSignature;
       } catch (Exception ex) {
           System.out.println(ex.getMessage());
       }
       return bSignature;
   }
   
   /*phuong thuc verify_nguoinhan danh cho nguoi nhan :
       - String thongdiep : thong diep nhan duoc tu nguoi goi.
       - String tenthuattoan : thuat toan danh cho digital signature phu hop voi thuat toan ben goi
       - PublicKey publicKey : được dùng để giải mã Signature.
       Nếu thành công phương thức này hiển thị "kiểm tra thành công",
        còn ngược lại "kiểm tra thất bại"
   */
   public static void verify_nguoinhan(String thongdiep, String tenthuattoan, PublicKey publicKey, byte[] sign){
         try {
           Signature signature = Signature.getInstance(tenthuattoan);
           signature.initVerify(publicKey);
           signature.update(thongdiep.getBytes());
           
           boolean b = signature.verify(sign);
           if (b){
               System.out.println("kiem tra sign nhan duoc thanh cong, thong diep chinh xac !");
           }else{
                System.out.println("kiem tra sign nhan duoc that bai, thong diep khong dung !");
           }
       } catch (Exception ex) {
           System.out.println(ex.getMessage());
       }
   }
}
2.class SignedObject :
Nếu thông điệp của bạn gởi đi là 1 chuỗi ký tự thì quá đơn giản, ngược lại thông điệp là nhiều chuỗi ký tự, hay thậm chí là 1 object nào đó của java thì làm sao đây, lúc này bạn phải nhờ đến  class SignedObject.
Class SignedObject nhằm mục đích tạo ra nhiều object khác nhau (text, image,...) từ người gởi mà bảo đảm toàn vẹn đến người nhận. Đối tượng SignedObject được tạo ra bởi 3 tham số đầu vào:
SignedObject so = new SignedObject(Serializableobject, PrivateKey,Signature);
Trong đó:
+ Serializableobject : tất cả các đối tượng thuộc interface Serializable, đều được đăng ký gởi đi.
+ PrivateKey : được dùng để mã hóa Signature, là đối tượng của class PrivateKey.
+ Signature : là đối tượng của class Signature.
Một số phương thức của class SignedObject:
Ví dụ : thông điệp cần gởi bao gồm :  2 chuỗi ký tự và 1 con dãy số bí mật.
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignedObject;
import java.util.Vector;

public class SignObjectApp1 {
   public static void main(String[] args) {
       try {
           //thong diep can goi
           String thongdiep1 = "Happy new year 2014";
           String thongdiep2 = "Happy birthday";
           long sobimat = 1332895473;

           Vector v = new Vector();
           v.add(thongdiep1);
           v.add(thongdiep2);
           v.add(sobimat);

           //cung cap public-key va private-key cho thuat toan Signature
           KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
           KeyPair keyPair = keyPairGenerator.generateKeyPair();
           PrivateKey privateKey = keyPair.getPrivate();
           PublicKey publicKey = keyPair.getPublic();

           //ten thuat toan danh cho Signature
           String tenthuattoan = "SHA1withRSA";

           //nguoi goi
           SignedObject bSignature = sign_bengoi(v, tenthuattoan, privateKey);

           //nguoi nhan
           verify_bennhan(bSignature, publicKey, tenthuattoan);

       } catch (Exception ex) {
           System.out.println(ex.getMessage());
       }
   }
   /*phuong thuc sign_bengoi danh cho nguoi goi :
       - Vector signobject : thong diep can duoc goi.
       - String tenthuattoan : thuat toan danh cho digital signature
       - PrivateKey privateKey : được dùng để mã hóa Signature.
      Phương thức này trả về mảng byte đó là Digital signature, được gởi đến người nhận
   */
   public static SignedObject sign_bengoi(Vector signobject, String tenthuattoan,
                                                                    PrivateKey privateKey) {
       try {
           Signature signature = Signature.getInstance(tenthuattoan);
           SignedObject so = new SignedObject(signobject, privateKey, signature);
           return so;
       } catch (Exception ex) {
           System.out.println(ex.getMessage());
       }
       return null;
   }
   /*phuong thuc verify_bennhan danh cho nguoi nhan :
       - SignedObject so : thong diep nhan duoc tu nguoi goi.
       - String tenthuattoan : thuat toan danh cho digital signature phu hop voi thuat toan ben goi
       - PublicKey publicKey : được dùng để giải mã Signature.
       Nếu thành công phương thức này hiển thị "kiểm tra thành công", còn ngược lại "kiểm tra thất bại"
   */
   public static void verify_bennhan(SignedObject so, PublicKey publicKey,
                                                                                        String tenthuattoan) {
       try {
           Signature signature = Signature.getInstance(tenthuattoan);
           boolean b = so.verify(publicKey, signature);
           if (b) {
               System.out.println("nhan object thanh cong");
           } else {
               System.out.println("nhan object that bai");
           }
       } catch (Exception ex) {
           System.out.println(ex.getMessage());
       }
   }
}

Không có nhận xét nào:

Đăng nhận xét