如何使用 Android KeyStore 生成、保存和加载对称密钥
How to generate,save and load a symmetric key using the Android KeyStore
我目前正在从事一个我们想要加密但不能使用服务器(我们不允许)的项目。我现在正在用这行代码制作我的钥匙:
key = KeyGenerator.getInstance("AES").generateKey();
所有的加解密都与之完美配合。问题是,每次您终止该应用程序并再次 运行 它时,都没有任何效果,因为会创建一个新密钥。所有以前加密的数据都不能再用这个新密钥解密。
我需要制作每次打开我的应用程序时获取相同密钥的函数。这就是为什么我要使用密钥库(我不允许将密钥存储在设备上,我只能使用 Android 密钥库或 RAM)。
知道具体怎么做吗?我在网上找到的唯一链接是配对密钥。
终于成功了!使用这个 link 我制作了一个不起作用的基本代码,但在其他堆栈溢出 post 的帮助下我成功了。
以下是可能需要它的其他人的解决方案:
这应该像您的 MainActivity java class.
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 class 中,因为它被您放在 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();
}
}
给你!然后你可以使用密钥做任何你想做的事情。
我目前正在从事一个我们想要加密但不能使用服务器(我们不允许)的项目。我现在正在用这行代码制作我的钥匙:
key = KeyGenerator.getInstance("AES").generateKey();
所有的加解密都与之完美配合。问题是,每次您终止该应用程序并再次 运行 它时,都没有任何效果,因为会创建一个新密钥。所有以前加密的数据都不能再用这个新密钥解密。
我需要制作每次打开我的应用程序时获取相同密钥的函数。这就是为什么我要使用密钥库(我不允许将密钥存储在设备上,我只能使用 Android 密钥库或 RAM)。
知道具体怎么做吗?我在网上找到的唯一链接是配对密钥。
终于成功了!使用这个 link 我制作了一个不起作用的基本代码,但在其他堆栈溢出 post 的帮助下我成功了。
以下是可能需要它的其他人的解决方案:
这应该像您的 MainActivity java class.
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 class 中,因为它被您放在 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();
}
}
给你!然后你可以使用密钥做任何你想做的事情。