【问题标题】:Realm Encryption with Android使用 Android 进行领域加密
【发布时间】:2016-06-28 15:05:04
【问题描述】:

Realm 使用 AES-256 进行加密和解密。而且,我正在尝试使用 Android KeyStore 来生成/存储密钥,但根据此页面 - https://developer.android.com/training/articles/keystore.html#SecurityFeatures,Android 仅在 API 23 及更高版本上支持此功能。

谁能给我一个示例或任何其他相关信息,说明我如何使用带加密的领域来支持 API 4.0 及更高版本?

谢谢。

【问题讨论】:

标签: android encryption react-native realm


【解决方案1】:

我们最近遇到了同样的问题,决定简单地将密钥存储在私有共享首选项中,因为如果手机没有 root,你将无法获取它,如果它已 root,那么有一些方法可以甚至从安全的 keyStore 获取数据。

我们在Application子类中使用下一个Realm配置:

RealmConfiguration config = new RealmConfiguration.Builder()
            .deleteRealmIfMigrationNeeded()
            .name(DB_NAME)
            .encryptionKey(mKeyProvider.getRealmKey())
            .build();

而 mKeyProvider 是我们用来获取密钥的辅助类:

public class SharedPrefsKeyProvider implements KeyProvider {

private static final String REALM_KEY = "chats.realm_key";
SharedPreferences mAppSharedPrefs;


public SharedPrefsKeyProvider(SharedPreferences aAppSharedPrefs) {
    mAppSharedPrefs = aAppSharedPrefs;
}

@Override
public byte[] getRealmKey() {
    byte[] key;
    String savedKey = getStringFromPrefs(REALM_KEY);
    if (savedKey.isEmpty()) {
        key = generateKey();
        String keyString = encodeToString(key);
        saveStringToPrefs(keyString);
    } else {
        key = decodeFromString(savedKey);
    }
    return key;
}

@Override
public void removeRealmKey() {
    mAppSharedPrefs.edit().remove(REALM_KEY).apply();
}

@NonNull
private String getStringFromPrefs(String aKey) {
    return mAppSharedPrefs.getString(aKey, "");
}

private void saveStringToPrefs(String aKeyString) {
    mAppSharedPrefs.edit().putString(REALM_KEY, aKeyString).apply();
}

private String encodeToString(byte[] aKey) {
    Timber.d("Encoding Key: %s", Arrays.toString(aKey));
    return Base64.encodeToString(aKey, Base64.DEFAULT);
}

private byte[] decodeFromString(String aSavedKey) {
    byte[] decoded = Base64.decode(aSavedKey, Base64.DEFAULT);
    Timber.d("Decoded Key: %s", Arrays.toString(decoded));
    return decoded;
}

private byte[] generateKey() {
    byte[] key = new byte[64];
    new SecureRandom().nextBytes(key);
    return key;
}
}

KeyProvider 只是一个自定义界面。 KeyProvider 的示例可以是:

package xxx.com;

interface KeyProvider {
    byte[] getRealmKey();

    void removeRealmKey();
}

【讨论】:

  • 请也添加 KeyProvider 类定义,@Gaket
  • 已经有了,请看第二个sn-p,SharedPrefsKeyProvider。
  • 在第二个sn-p中,有public class SharedPrefsKeyProvider implements KeyProvider。但我不知道KeyProvider 是什么,或者我应该从哪里导入该类。我的猜测是,您在您的 android 项目上使用了 cloudant lib,并使用了 cloudant lib 提供的 KeyProvider 类。我说的对吗?
  • 知道了。不,它只是我们创建的一个接口,用于处理密钥,以防我们想在其他 API 级别上使用其他解决方案。你可以想出另一个或简单地使用一个实现。
  • 我建议将密钥保存到密钥库而不是共享首选项中,否则您最好不要费心使用公开可见的密钥来加密您的数据库
【解决方案2】:

AES 256 加密是对称加密,试试非对称的 RSA 加密。如果您尝试加密敏感的用户数据以存储在首选项或 sqlite 中,我建议您尝试 Android 密钥库系统

Android Keystore 系统可让您将加密密钥存储在容器中,以便更难以从设备中提取。一旦密钥在密钥库中,它们就可以用于加密操作,而密钥材料仍然不可导出。

检查我的示例要点以实现此加密和解密here

更好的是它适用于 android 18 及更高版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多