如何使用Android KeyStore生成,保存和加载对称密钥

时间:2018-03-23 16:44:54

标签: java android encryption key keystore

我目前正在开展一个我们想要加密的项目,但不能使用服务器(我们不允许)。我现在用这行代码制作我的密钥:

key = KeyGenerator.getInstance("AES").generateKey();

所有加密和解密都与它完美配合。问题是,你甚至可以杀死应用程序并再次运行它,因为创建了一个新密钥,所以没有任何作用。使用此新密钥无法再解密所有先前加密的数据。

我需要让每次打开我的应用时获得相同密钥的功能。这就是我想要使用密钥库的原因(我不允许将密钥存储在设备上,我只能使用Android密钥库或RAM)。

知道怎么做到这一点吗?我在网上找到的唯一链接是配对密钥。

1 个答案:

答案 0 :(得分:1)

最后设法让它发挥作用!使用此链接我创建了一个无效的基本代码,但在其他堆栈溢出帖子的帮助下,我完成了它。

以下是可能需要它的其他任何人的解决方案:

这应该类似于您的MainActivity java类。

public KeyStore ks;

@Override protected void onCreate (Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        try{
            // Get Keystore
            ks = KeyStore.getInstance(KeyStore.getDefaultType());

            SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
            boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
            if (isFirstRun)
            {
                SharedPreferences.Editor editor = wmbPreference.edit();
                editor.putBoolean("FIRSTRUN", false);
                editor.commit();

                ks.load(null, password);
                GenerateKey();
            } else {
                LoadKey();
            }
        }
        catch(Exception ex){
            ex.printStackTrace();
        }

        myClassNeedingTheKey.secretKey = key;
    }

它声明在应用程序的第一次运行时,它会创建密钥库以及随之而来的密钥(我们还会保存所有内容)。如果不是第一次运行应用程序,则加载密钥。然后在结束onCreate之前,我们将密钥传递给任何需要它的人。

以下是生成,保存和加载的实际代码。这也是一个典型的MainActivity类,因为它被放在onCreate中的代码使用。

public SecretKey key;

public char[] password = "1234567890".toCharArray();

void GenerateKey(){
    try {
        // Get and Convert the Key
        key = KeyGenerator.getInstance("AES").generateKey();

        SaveKey();
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
}

void SaveKey(){
    try{
        // Save my secret key
        KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(key);
        ks.setEntry("SecretKeyAlias", secretKeyEntry,null);

        // Save the keystore
        FileOutputStream fos = new FileOutputStream(this.getFilesDir().getAbsolutePath() + "/OEKeyStore");
        ks.store(fos, password);
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
}

void LoadKey(){
    try{
        // Load Keystore
        FileInputStream fis = new FileInputStream(this.getFilesDir().getAbsolutePath() + "/OEKeyStore");
        ks.load(fis, password);

        // Load the secret key
        KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry)ks.getEntry("SecretKeyAlias",null);
        key = secretKeyEntry.getSecretKey();
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
}
你去吧!然后,您可以使用密钥来执行任何操作。