Bảo mật ứng dụng React Native với Keychains
I. Giới thiệu:
Trong thời buổi công nghệ phát triển như hiện tại, thì việc để lộ hay bị đánh cắp thông tin như mật khẩu, thẻ tín dụng là điều rất dễ xẩy ra. Vậy nên bảo mật dữ liệu là điều cực kỳ quan trọng đối với ứng dụng di động. Hãy cùng nhau tìm hiểu về cách bảo mật thông tin trong ứng dụng React Native của bạn với Biometric
(sinh trắc học) bằng cách sử dụng react-native-keychain
.
II. Cài đặt:
1. Thêm thư viện react-native-keychain
vào ứng dụng React Native:
npm install react-native-keychain
hoặc yarn add react-native-keychain
2. Nếu bạn sử dụng react-native <= 0.59, đừng quên link thư viện vào project:
react-native link react-native-keychain
3. Từ root project chạy dòng lệnh:
cd ios && pod install
Quá trình config thư viện đã hoàn thành rồi. Khá đơn giản phải không ạ :D.
Tham khảo thêm: https://github.com/oblador/react-native-keychain#api
Lưu ý: Khi bạn đang sử dụngreact-native-keychain
, điều quan trọng cần lưu ý là có những phương thức chỉ tương thích trêniOS
hoặcAndroid
. Tuy nhiên, những phương thức mà chúng ta sử dụng trong bài viết này đều có thể sử dụng được trên cảAndroid
vàiOS
.
Tham khảo thêm: react-native-keychain.
III. Sử dụng:
Ví dụ sau sẽ cho thấy cách lưu trữ, truy xuất và sử dụng thông tin để đăng nhập lại vào ứng dụng bằng sinh trắc học.
-
Lưu thông tin đăng nhập:
Chúng ta sử dụng hàmsetGenericPassword()
để lưu trữ thông tin đăng nhập của người dùng (tên người dùng và mật khẩu) vàoKeychain (iOS)
vàShared Preference (Android)
.- Đầu tiên hàm sẽ sử dụng
Keystore
để tạo một cặp khoá (keypair)private/public
. Cặp key này sẽ được lưu trữ trong Keystore. - Dữ liệu truyền vào sẽ được mã hoá bằng thuật toán AES-256-GCM với private key và lưu vào Secure Storage.
import * as Keychain from 'react-native-keychain'; const CONFIG = { accessControl:Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE, accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED, storage: Keychain.STORAGE_TYPE.RSA, } const LoginScreen = props => { const username = 'quanna@vietnamlab.vn'; const password = 'wertyuiop'; await Keychain.setGenericPassword(username, password, CONFIG); }
- Đầu tiên hàm sẽ sử dụng
-
Truy xuất dữ liệu từ Keychain:
Sử dụng hàmgetGenericPassword()
để lấy thông tin đăng nhập người dùng đã lưu trongKeychain
.- Người dùng cần xác thực vân tay/khuôn mặt trước.
- Sau khi xác thực thành công, tiếp tục gọi tới
Keystore
để lấy cặp khoá (keypair)private/public
đã được tạo khi lưu thông tin đăng nhập. - Sử dụng
private key
để giải mã dữ liệu và trả lại cho người dùng. - Theo mặc định, hàm trả về Chuỗi. Vì vậy khi truy xuất các đối tượng, nên sử dụng
JSON.parse
.
import * as Keychain from 'react-native-keychain'; const CONFIG = { accessControl:Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE, accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED, storage: Keychain.STORAGE_TYPE.RSA, } const LoginScreen = (props) => { const checkUserStatus = async () => { try { const credentials = await Keychain.getGenericPassword(CONFIG); } catch (error) { console.log("Keychain couldn't be accessed!", error); } }; };
-
Implement login code:
Trong đoạn code dưới. Đầu tiên hàm functioncheckBiometricSupport()
sẽ được gọi trongUseEffect
để kiểm tra xem thiết bị có được hỗ trợ sinh trắc học hay không. Nếu có ta tiếp tục gọi tới hàmgetUserData()
để truy xuất xuốngKeychain
. Sau đó, hàmlogin ()
sẽ được gọi để đăng nhập bằng thông tin đăng nhập được trả về.import React, { useState, useEffect } from 'react'; import * as Keychain from 'react-native-keychain'; const CONFIG = { accessControl:Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE, accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED, storage: Keychain.STORAGE_TYPE.RSA, } const LoginScreen = (props) => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [bioSupport, setBioSupport] = useState(false); const [preLog, setPreLog] = useState(false); useEffect(() => { checkBiometricSupport(); }, []); useEffect(() => { if (bioSupport) { getUserData(); } }, [bioSupport]); useEffect(() => { if (preLog) { login(); } }, [password, email]); const checkBiometricSupport = async () => { try { const biometricSupport = await Keychain.getSupportedBiometryType(); setBioSupport(biometricSupport); } catch (error) { console.log("Keychain couldn't be accessed!", error); } }; const getUserData = async () => { try { const credentials = await Keychain.getGenericPassword(CONFIG); if (credentials) { setPreLog(true); setEmail(credentials.username); setPassword(credentials.password); } else { setLoading(false); } } catch (error) { console.log("Keychain couldn't be accessed!", error); setLoading(false); } }; const login = async () => { try { const response = await fetch('yoururl' + 'signin', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password, }), }); const responseJson = await response.json(); var message = responseJson.msg; if (responseJson.success === true) { await Keychain.setGenericPassword(email, password, CONFIG); } } catch (error) { console.error(error); } }; };
-
Xoá thông tin đăng nhập:
Khi user thực hiện logout ra khỏi ứng dụng, hàmresetGenericPassword()
được sử dụng để xoá toàn bộ thông tin đăng nhập của người dùng trongKeychain
.import * as Keychain from 'react-native-keychain'; const LoginScreen = (props) => { const removeCredentials = async () => { try { const credentials = await Keychain.resetGenericPassword(); } catch (error) { console.log("Keychain couldn't be accessed!", error); } }; };
IV. Lợi ích khi sử dụng react-native-keychain:
One library to access both iOS Keychain and Android Keystore in React-Native apps.
Có rất nhiều lý do để chúng ta sử dụng react-native-keychain
. Đây là thư viện phổ biến nhất sử dụng để lưu trữ bảo mật thông tun, được React-native khuyên dùng. Ta hãy cùng xem một vài lợi ích mà thư viện này mang tới:
- Thiết lập được quyền truy cập vào
Keychain
, ví dụ thiết bị phải được cài đặt mã khoá thì mới có thể truy cập. Keychain
không thể thểrestored
trên một thiết bị khác.Encrypted keys
được lưu ởhardware level
.- Dễ dàng implement và sử dụng.
- Được cập nhật liên tục và cộng đồng đông đảo.
……..
V. Kết luận:
Dựa trên kinh nghiệm của mình, react-native-keychain
là lựa chọn tốt nhất để lưu trữ dữ liệu quan trọng cho ứng dụng của bạn. Như chúng ta đã thấy ở trên, việc implement và sử dụng hết sức đơn giản nhưng hiệu quả mang lại thì cao nhất.
Mình hy vọng bài viết này sẽ giúp mọi người hiểu hơn về cách sử dụng Keychain
hay cụ thể hơn là đăng nhập bằng sinh trắc học. Cảm ơn mọi người đã đọc bài.