An toàn hơn khi làm việc với dữ liệuMột phần của Android Jetpack.
Thư viện bảo mật cung cấp việc triển khai các phương pháp hay nhất về bảo mật liên quan đến việc đọc và ghi dữ liệu tĩnh, cũng như việc tạo và xác minh khoá.
Thư viện sử dụng mẫu trình tạo để cung cấp chế độ cài đặt mặc định an toàn cho các mức bảo mật sau:
- Mức bảo mật mạnh cân bằng giữa phương thức mã hoá hiệu quả và hiệu suất cao. Cấp độ bảo mật này phù hợp với các ứng dụng dành cho người dùng thông thường, chẳng hạn như các ứng dụng ngân hàng và trò chuyện, cũng như các ứng dụng doanh nghiệp để thực hiện quy trình kiểm tra việc thu hồi chứng chỉ.
- Mức bảo mật tối đa. Cấp độ bảo mật này phù hợp với các ứng dụng yêu cầu kho khoá dựa trên phần cứng và sự hiện diện của người dùng để cung cấp quyền truy cập khoá.
Hướng dẫn này chỉ cho bạn cách làm việc với các cấu hình bảo mật được đề xuất của Thư viện bảo mật, cũng như cách đọc và ghi dữ liệu đã mã hoá được lưu trữ trong các tệp và các tuỳ chọn chung một cách dễ dàng và an toàn.
Quản lý khoá
Thư viện bảo mật sử dụng hệ thống gồm 2 phần để quản lý khoá:
-
Một tập hợp khoá chứa một hoặc nhiều khoá để mã hoá một tệp hoặc dữ liệu về các tuỳ chọn chung. Tập hợp khoá sẽ được lưu trữ trong
SharedPreferences
. -
Khoá chính (
master
) mã hoá tất cả các bộ khoá. Khoá này được lưu trữ bằng hệ thống kho khoá của Android.
Các lớp có trong thư viện
Thư viện bảo mật chứa các lớp sau đây để cung cấp thêm dữ liệu tĩnh an toàn:
EncryptedFile
-
Cung cấp các biện pháp triển khai tuỳ chỉnh của
FileInputStream
vàFileOutputStream
, giúp cho các ứng dụng của bạn được an toàn hơn trong việc truyền trực tuyến các thao tác đọc và ghi.Để cung cấp các thao tác đọc và ghi an toàn từ luồng truyền tệp (file streams), Thư viện bảo mật sử dụng phương thức gốc Mã hoá truyền trực tuyến đã xác thực với dữ liệu liên kết (AEAD). Tìm hiểu thêm về phương thức gốc này trong tài liệu về thư viện Tink trên GitHub.
EncryptedSharedPreferences
-
Gói lớp
SharedPreferences
và tự động mã hoá các khoá và giá trị bằng phương thức hai lược đồ:- Khoá được mã hoá bằng một thuật toán mã hoá xác định để khoá có thể được mã hoá và tra cứu đúng cách.
- Giá trị được mã hoá bằng AES-256 GCM và là giá trị không xác định.
Các phần sau đây cho biết cách sử dụng các lớp này để thực hiện các thao tác phổ biến với tệp và tuỳ chọn chung.
Đưa thư viện vào dự án của bạn
Để sử dụng Thư viện bảo mật, hãy thêm phần phụ thuộc sau vào tệp build.gradle
của mô-đun ứng dụng:
Groovy
dependencies { implementation "androidx.security:security-crypto:1.0.0" // For Identity Credential APIs implementation "androidx.security:security-identity-credential:1.0.0-alpha03" // For App Authentication APIs implementation "androidx.security:security-app-authenticator:1.0.0-alpha02" // For App Authentication API testing androidTestImplementation "androidx.security:security-app-authenticator:1.0.0-alpha01" }
Kotlin
dependencies { implementation("androidx.security:security-crypto:1.0.0") // For Identity Credential APIs implementation("androidx.security:security-identity-credential:1.0.0-alpha03") // For App Authentication APIs implementation("androidx.security:security-app-authenticator:1.0.0-alpha02") // For App Authentication API testing androidTestImplementation("androidx.security:security-app-authenticator:1.0.0-alpha01") }
Đọc tệp
Đoạn mã sau đây minh hoạ cách sử dụng EncryptedFile
để đọc nội dung của tệp theo cách an toàn hơn:
Kotlin
// Although you can define your own key generation parameter specification, it's // recommended that you use the value specified here. val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC val mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec) val fileToRead = "my_sensitive_data.txt" val encryptedFile = EncryptedFile.Builder( File(DIRECTORY, fileToRead), applicationContext, mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val inputStream = encryptedFile.openFileInput() val byteArrayOutputStream = ByteArrayOutputStream() var nextByte: Int = inputStream.read() while (nextByte != -1) { byteArrayOutputStream.write(nextByte) nextByte = inputStream.read() } val plaintext: ByteArray = byteArrayOutputStream.toByteArray()
Java
Context context = getApplicationContext(); // Although you can define your own key generation parameter specification, it's // recommended that you use the value specified here. KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC; String mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec); String fileToRead = "my_sensitive_data.txt"; EncryptedFile encryptedFile = new EncryptedFile.Builder( new File(DIRECTORY, fileToRead), context, mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build(); InputStream inputStream = encryptedFile.openFileInput(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); int nextByte = inputStream.read(); while (nextByte != -1) { byteArrayOutputStream.write(nextByte); nextByte = inputStream.read(); } byte[] plaintext = byteArrayOutputStream.toByteArray();
Ghi tệp
Đoạn mã sau đây minh hoạ cách sử dụng EncryptedFile
để ghi nội dung của tệp theo cách an toàn hơn:
Kotlin
// Although you can define your own key generation parameter specification, it's // recommended that you use the value specified here. val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC val mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec) // Create a file with this name, or replace an entire existing file // that has the same name. Note that you cannot append to an existing file, // and the file name cannot contain path separators. val fileToWrite = "my_sensitive_data.txt" val encryptedFile = EncryptedFile.Builder( File(DIRECTORY, fileToWrite), applicationContext, mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val fileContent = "MY SUPER-SECRET INFORMATION" .toByteArray(StandardCharsets.UTF_8) encryptedFile.openFileOutput().apply { write(fileContent) flush() close() }
Java
Context context = getApplicationContext(); // Although you can define your own key generation parameter specification, it's // recommended that you use the value specified here. KeyGenParameterSpec keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC; String mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec); // Create a file with this name, or replace an entire existing file // that has the same name. Note that you cannot append to an existing file, // and the file name cannot contain path separators. String fileToWrite = "my_sensitive_data.txt"; EncryptedFile encryptedFile = new EncryptedFile.Builder( new File(DIRECTORY, fileToWrite), context, mainKeyAlias, EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build(); byte[] fileContent = "MY SUPER-SECRET INFORMATION" .getBytes(StandardCharsets.UTF_8); OutputStream outputStream = encryptedFile.openFileOutput(); outputStream.write(fileContent); outputStream.flush(); outputStream.close();
Với trường hợp sử dụng yêu cầu tăng cường mức bảo mật, hãy hoàn thành các bước sau:
- Tạo đối tượng
KeyGenParameterSpec.Builder
, chuyểntrue
vàosetUserAuthenticationRequired()
và một giá trị lớn hơn 0 vàosetUserAuthenticationValidityDurationSeconds()
. Nhắc người dùng nhập thông tin xác thực bằng
createConfirmDeviceCredentialIntent()
. Tìm hiểu thêm về cách yêu cầu việc xác thực người dùng để sử dụng khoá.Ghi đè
onActivityResult()
để nhận lệnh gọi lại thông tin xác thực đã xác nhận.
Để biết thêm thông tin, hãy xem phần Yêu cầu xác thực người dùng để sử dụng khoá.
Chỉnh sửa tuỳ chọn chung
Đoạn mã sau đây minh hoạ cách sử dụng EncryptedSharedPreferences
để chỉnh sửa tập hợp các tuỳ chọn chung của người dùng theo cách an toàn hơn:
Kotlin
val sharedPrefsFile: String = FILE_NAME val sharedPreferences: SharedPreferences = EncryptedSharedPreferences.create( sharedPrefsFile, mainKeyAlias, applicationContext, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) with (sharedPreferences.edit()) { // Edit the user's shared preferences... apply() }
Java
String sharedPrefsFile = FILE_NAME; SharedPreferences sharedPreferences = EncryptedSharedPreferences.create( sharedPrefsFile, mainKeyAlias, getApplicationContext(), EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ); SharedPreferences.Editor sharedPrefsEditor = sharedPreferences.edit(); // Edit the user's shared preferences... sharedPrefsEditor.apply();