我正试图在应用程序中保密(String),无论如何,除此之外!所以我想出了这个想法,使用keyStore来存储密钥,只用它来加密和解密我的秘密。以下是我保存(加密)我的秘密的方法:
public static boolean setKeyStoreString(String strToStore, Context context) {
if (strToStore == null) return false;
if (strToStore.length() == 0) return false;
Log.e(TAG, strToStore);
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
int nBefore = keyStore.size();
// Create the keys if necessary
if (!keyStore.containsAlias("phrase")) {
KeyGenerator generator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder("phrase", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setKeySize(256)
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setUserAuthenticationValidityDurationSeconds(-1)
.setRandomizedEncryptionRequired(false)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setUserAuthenticationRequired(false)
.build();
generator.init(spec);
generator.generateKey();
}
int nAfter = keyStore.size();
Log.v(TAG, "Before = " + nBefore + " After = " + nAfter);
String filesDirectory = context.getFilesDir().getAbsolutePath();
String encryptedDataFilePath = filesDirectory + File.separator + "my_phrase";
// Log.v(TAG, "strPhrase = " + strToStore);
// Log.v(TAG, "dataDirectory = " + dataDirectory);
// Log.v(TAG, "filesDirectory = " + filesDirectory);
// Log.v(TAG, "encryptedDataFilePath = " + encryptedDataFilePath);
SecretKey secret = (SecretKey) keyStore.getKey("phrase", null);
Cipher inCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
inCipher.init(Cipher.ENCRYPT_MODE, secret);
CipherOutputStream cipherOutputStream = new CipherOutputStream(
new FileOutputStream(encryptedDataFilePath), inCipher);
byte[] bytesToStore = strToStore.getBytes("UTF-8");
cipherOutputStream.write(bytesToStore);
try {
cipherOutputStream.close();
} catch (Exception ex) {
ex.printStackTrace();
}
return true;
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
return false;
}
以下是我尝试检索它的方法:
public static String getKeyStoreString(final Context context) {
KeyStore keyStore;
String recoveredSecret = "";
String filesDirectory = context.getFilesDir().getAbsolutePath();
String encryptedDataFilePath = filesDirectory + File.separator + "my_phrase";
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey)
keyStore.getKey("phrase", null);
if (secretKey == null) throw new RuntimeException("secretKey is null");
Cipher outCipher;
outCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
outCipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(
new byte[outCipher.getBlockSize()]));
CipherInputStream cipherInputStream = new CipherInputStream(
new FileInputStream(encryptedDataFilePath), outCipher);
byte[] roundTrippedBytes = new byte[1000]; //TODO: dynamically resize as we get more data
int index = 0;
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
roundTrippedBytes[index] = (byte) nextByte;
index++;
}
recoveredSecret = new String(roundTrippedBytes, 0, index, "UTF-8");
Log.e(TAG, "round tripped string = " + recoveredSecret);
} catch (Exception e) {
e.printStackTrace();
}
Log.e(TAG, "recovered: " + recoveredSecret);
return recoveredSecret;
}
问题是 - 结果在开始时有点受损,
即:一些用于提取的酷文本>>>>> �k��X�&�ALqM,A�文本 提取
答案 0 :(得分:1)
我遇到了同样的问题,我使用Base64.encode(your byte[], Base64.DEFAULT);
进行编码,Base64.decode(your byte[], Base64.DEFAULT)
进行解码
尝试放byte[] encode = Base64.encode(bytesToStore, Base64.DEFAULT)
在byte[] bytesToStore = strToStore.getBytes("UTF-8");
之后
在public static boolean setKeyStoreString()中并检入" encode"日志