Mã hóa dữ liệu khi lưu trữ trong ứng dụng Java + SQL Server


Thông thường dữ liệu các nhân của người dùng khi lưu trữ vào csdl chúng ta nên che đi những dữ liệu nhạy cảm, trong ví dụ sau đây chúng ta cùng làm một demo nhỏ để che đi dữ liệu email và ngày sinh của người dùng (chỉ có ứng dụng của chúng ta mới giải mã được)

Tạo bảng để lưu được thông tin sau:
Order.    Name        Type
1.    Username    Text
2.    Password    Text
3.    Fullname    Text
4.    Address     Text
5.    Email       Text
6.    Birthdate   Date

Yêu cầu

Thiết kế form thêm thông tin người dùng vào bảng trên với các yêu cầu sau:
    1.    Mã hóa Password bằng giải thuật MD5
    2.    Mã hóa email và birthdate bằng giải thật mã hóa 02 chiều

Thiết kế form hiển thị ds người dùng thể hiện các cột: Username, Fullname và Address
Thiết kế form tìm người dùng dựa vào Username, kết quả hiển thị chi tiết người dùng gồm thông tin
       Username
    •    Fullname
    •    Address
    •    Email và Birthdate đã được giải mã

Giao diên thêm và tìm thông tin

image Dữ liệu đã mã hóa

image Dữ liệu được giải mã (nhấn nút find)

image

Bước 1: Tạo CSDL tên data và bảng nguoidung

1 SET ANSI_NULLS ON 2 GO 3 4 SET QUOTED_IDENTIFIER ON 5 GO 6 7 SET ANSI_PADDING ON 8 GO 9 10 CREATE TABLE [dbo].[users]( 11 [username] [varchar](50) NULL, 12 [password] [varchar](100) NULL, 13 [fullname] [varchar](100) NULL, 14 [address] [varchar](250) NULL, 15 [email] [varbinary](max) NULL, 16 [birthdate] [varbinary](max) NULL 17 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 18 19 GO 20 21 SET ANSI_PADDING OFF 22 GO

Bước 2: Tạo cập khóa cho ứng dụng và lưu trữ lại để sử dụng (file)

1 class KeyGen { 2 public static void main(String[] args) { 3 try { 4 if (!new File("src/lib/pri.key").exists()) { 5 KeyPairGenerator key = KeyPairGenerator.getInstance("RSA"); 6 key.initialize(512); 7 KeyPair keys = key.genKeyPair(); 8 // Tạo cặp khóa 9 PrivateKey privateKey = keys.getPrivate(); 10 PublicKey publicKey = keys.getPublic(); 11 // Lưu thông tin khóa để tái sử dụng, khóa công khai để giải mã 12 X509EncodedKeySpec x509EncodedKeySpec = 13 new X509EncodedKeySpec(publicKey.getEncoded()); 14 FileOutputStream fos = new FileOutputStream("src/lib/pub.key"); 15 fos.write(x509EncodedKeySpec.getEncoded()); 16 fos.close(); 17 // khóa mật để mã hóa 18 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = 19 new PKCS8EncodedKeySpec(privateKey.getEncoded()); 20 fos = new FileOutputStream("src/lib/pri.key"); 21 fos.write(pkcs8EncodedKeySpec.getEncoded()); 22 fos.close(); 23 } else { 24 System.out.println("Khoa da co"); 25 } 26 } catch (IOException ex) { 27 Logger.getLogger(KeyGen.class.getName()).log(Level.SEVERE, null, ex); 28 } catch (NoSuchAlgorithmException ex) { 29 Logger.getLogger(KeyGen.class.getName()).log(Level.SEVERE, null, ex); 30 } 31 } 32 }

Tới đây chúng ta đã có được cặp khóa để có thể mã hóa và giải mã những dữ liệu cần thiết.

Bước 3: Xây dựng lớp Encode để phục hồi khóa từ tập tin và tạo phương thức mã hóa, giải mã.

1 public class Encode { 2 private PrivateKey priKey; 3 private PublicKey pubKey; 4 public Encode() { 5 getKeys(); 6 } 7 private void getKeys() { 8 try { 9 File pubKeyFile = new File("src/lib/pub.key"); 10 File privKeyFile = new File("src/lib/pri.key");; 11 // đọc dữ liệu từ file và khởi tọa lại khóa công khai 12 DataInputStream dis = new DataInputStream(new FileInputStream(pubKeyFile)); 13 byte[] pubKeyBytes = new byte[(int) pubKeyFile.length()]; 14 dis.readFully(pubKeyBytes); 15 dis.close(); 16 17 // đọc dữ liệu từ file và khởi tọa lại khóa mật 18 dis = new DataInputStream(new FileInputStream(privKeyFile)); 19 byte[] privKeyBytes = new byte[(int) privKeyFile.length()]; 20 dis.read(privKeyBytes); 21 dis.close(); 22 // 23 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 24 // Tạo khóa công khai 25 X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyBytes); 26 pubKey = (RSAPublicKey) keyFactory.generatePublic(pubSpec); 27 // tạo khóa mật 28 PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(privKeyBytes); 29 priKey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec); 30 } catch (Exception ex) { 31 System.out.println("ERR: " + ex.toString()); 32 } 33 } 34 // hàm mã hóa 35 public byte[] TwowayEncrypt(byte[] data) { 36 try { 37 Cipher c = Cipher.getInstance("RSA"); 38 c.init(Cipher.ENCRYPT_MODE, priKey); 39 byte[] rs = c.doFinal(data); 40 return rs; 41 } catch (Exception ex) { 42 System.out.println("Err: " + ex.toString()); 43 } 44 return null; 45 } 46 // hàm giải mã 47 public byte[] TwowayDecrypt(byte[] data) { 48 try { 49 Cipher c = Cipher.getInstance("RSA"); 50 c.init(Cipher.DECRYPT_MODE, pubKey); 51 byte[] rs = c.doFinal(data); 52 return rs; 53 } catch (Exception ex) { 54 System.out.println("Err: " + ex.toString()); 55 } 56 return null; 57 } 58 // dùng cho mã hóa mật khẩu 59 public byte[] OnewayEncrypt(byte[] data){ 60 try { 61 MessageDigest dig = MessageDigest.getInstance("MD5"); 62 return dig.digest(data); 63 } catch (Exception ex) { 64 System.out.println("ERR: "+ ex.toString()); 65 } 66 return null; 67 } 68 }

Bước 4: Tích hợp lên giao diện

Xử lý sự kiện Click nút Add new

1 private void btnAddActionPerformed(java.awt.event.ActionEvent evt) { 2 try { 3 Connection conn = DriverManager.getConnection("jdbc:sqlserver://ntdan;databasename=data;", "sa", "sa"); 4 PreparedStatement comm = conn.prepareStatement("Insert into users values(?,?,?,?,?,?)"); 5 comm.setString(1, txtUser.getText()); 6 7 byte[] ba1 = Charset.forName("UTF-8").encode(CharBuffer.wrap(txtPass.getPassword())).array(); 8 9 comm.setString(2, new String(encode.OnewayEncrypt(ba1), "UTF-8")); 10 comm.setString(3, txtFull.getText()); 11 comm.setString(4, txtAdd.getText()); 12 13 comm.setBytes(5,encode.TwowayEncrypt(txtEmail.getText().getBytes("UTF-8"))); 14 comm.setBytes(6, encode.TwowayEncrypt(txtBirth.getText().getBytes("UTF-8"))); 15 16 comm.executeUpdate(); 17 } catch (Exception ex) { 18 System.out.println("ERR: " + ex.toString()); 19 } 20 }

Xử lý sự kiện Click nút Find

1 private void btnFindActionPerformed(java.awt.event.ActionEvent evt) { 2 try { 3 Connection conn = DriverManager.getConnection("jdbc:sqlserver://ntdan;databasename=data;", "sa", "sa"); 4 PreparedStatement comm = conn.prepareStatement("Select * from Users where username=?"); 5 comm.setString(1, txtUser.getText()); 6 ResultSet rs = comm.executeQuery(); 7 String found=""; 8 if(rs.next()) 9 { 10 found = "User: "; 11 found += rs.getString(1); 12 found += "\nFullname: "+rs.getString(3); 13 found += "\nAddress: "+rs.getString(4); 14 found += "\nEmail: "+ new String(encode.TwowayDecrypt(rs.getBytes(5)),"UTF-8"); 15 found += "\nBirthDate: "+ new String(encode.TwowayDecrypt(rs.getBytes(6)),"UTF-8"); 16 } 17 18 JOptionPane.showMessageDialog(this, found); 19 } catch (Exception ex) { 20 System.out.println("Err: "+ ex.toString()); 21 } 22 }

OK, như vậy là cơ bản chúng ta đã một phần nào đó che đi dữ liệu email và ngày sinh khi lưu vào SQL Server.

 

Đây là một ví dụ nhỏ hi vọng sẽ giúp chúng ta có cái nhìn rất cơ bản về việc bảo vệ dữ liệu riêng tư cho ứng dụng.

Advertisements

Phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Đăng xuất / Thay đổi )

Connecting to %s