テキストフィールドを安全に保存しようとしています。そのために、私はコンテンツを暗号化し解読しようとしています。これはコードです:Androidでテキストを暗号化するときに復号化で空の文字列が返される
public class SecureStorage {
public String getPassword() {
if(!isRooted()) {
String password = pref.getPassword("");
System.out.println("pass getPass: " + password);
return password.isEmpty() ? password : new String(decrypt(Base64.decode(password, Base64.DEFAULT)));
} else
return "";
}
public void setPassword(String passwordStr) {
if(!isRooted()) {
byte[] password = encrypt(passwordStr.getBytes());
pref.setPassword(password == null ? "" : Base64.encodeToString(password, Base64.DEFAULT));
}
}
private SecretKey generateKey() {
// Generate a 256-bit key
final int outputKeyLength = 256;
try {
SecureRandom secureRandom = new SecureRandom();
// Do *not* seed secureRandom! Automatically seeded from system entropy.
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(outputKeyLength, secureRandom);
return keyGenerator.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private byte[] getRawKey(byte[] key) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
secureRandom.setSeed(key);
keyGenerator.init(128, secureRandom); // 192 and 256 bits may not be available
SecretKey secretKey = keyGenerator.generateKey();
byte[] rawKey = secretKey.getEncoded();
return rawKey;
}
/** The method that encrypts the string.
@param toEncrypt The string to be encrypted.
@return The encrypted string in bytes. */
//****************************************
private byte[] encrypt(byte[] toEncrypt) {
byte[] encryptedByte = new String().getBytes();
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(getRawKey(Utils.generateUID().getBytes()), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
encryptedByte = cipher.doFinal(toEncrypt);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return encryptedByte;
}
//**************************************
/** The method that decrypts the string.
@param encryptedByte The string to be encrypted.
@return The decrypted string in bytes. */
//****************************************
private byte[] decrypt(byte[] encryptedByte) {
byte[] decryptedByte = new String().getBytes();
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(getRawKey(Utils.generateUID().getBytes()), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
decryptedByte = cipher.doFinal(encryptedByte);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return decryptedByte;
}
}
私はテキストを暗号化できます。 私はSharedPreferencesを使用して暗号化されたテキストを保存し、sharedprefsを取得してテキストを復号化してTextViewに渡します。しかし、getPassword()
では、SharedPreference値を取得していて、SharedPrefsに値があれば復号化しようとしています。私はSharedPrefsを文字列(password
)にして、それを解読しようとしていますが、私はできません!私は空の文字列を取得しています!
'pref.getPassword(" ");'は何ですか? – Jimmy
可能なすべての例外をキャッチしているため、空の文字列が表示されています。どの例外がスローされたかを調べるためにログを調べましたか?私はそれがBadPaddingExceptionだと思う –
それを得た!, Im世代ランダムキーとそれを保存していない!だから、今私は新しい鍵を呼び戻すとき。今では、テキストと一緒にキーを保存しています! –