我正在使用this library来保存加密到SharedPreferences的用户名和密码(非常确定没有应用可以访问我的SharedPreferences,但无论如何这都是必需的。)
我做了这段代码,因为我还需要使用自己的IV和密钥:
public class EncryptionHandler {
private final static String PREFS_FILE_NAME = "SAVED_CREDENTIALS";
private final static String MSG_FORMAT = "%s;%s";
public static void saveCredentials(Context context, String username, String password) {
try {
String formattedMsg = String.format(MSG_FORMAT, username, password);
String encryptedMsg = new String(AESCrypt.encrypt(getKeySpec(), getIV(), stringToBytes(formattedMsg)));
//save encryptedMsg to SharedPreferences
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] stringToBytes(String msg) {
return msg.getBytes(Charset.forName("UTF-8"));
}
public static LoginCredentials getSavedCredentials(Context context) {
try {
String encryptedMsg = getSharedPreferences(context).getString(PREFS_FILE_NAME, "");
String messageAfterDecrypt = new String(AESCrypt.decrypt(getKeySpec(), getIV(), stringToBytes(encryptedMsg)));
String[] split = messageAfterDecrypt.split(";");
//irrelevant code
return credentials;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] ivBytes = {0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0x52, 0x00, 0x00, 0x00, 0x00};
private static SecretKeySpec secretKeySpec = new SecretKeySpec(ivBytes, "AES");
private static SecretKeySpec getKeySpec() throws Exception {
return secretKeySpec;
}
private static byte[] getIV() {
return ivBytes;
}
}
Related questions建议使用Base64,但我确实需要使用AESCrypt(它已经在iOS应用程序上工作,所以我必须做同样的事情)。
我得到的例外是:
javax.crypto.IllegalBlockSizeException: error:1e06b07b:Cipher functions:EVP_DecryptFinal_ex:WRONG_FINAL_BLOCK_LENGTH
at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
at com.android.org.conscrypt.OpenSSLCipher$EVP_CIPHER.doFinalInternal(OpenSSLCipher.java:568)
at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:350)
at javax.crypto.Cipher.doFinal(Cipher.java:1502)
at com.scottyab.aescrypt.AESCrypt.decrypt(AESCrypt.java:158)
at com.mypackage.encryption.EncryptionHandler.getSavedCredentials(EncryptionHandler.java:48)
当我尝试读取和解密时,此行中发生异常:
String messageAfterDecrypt = new String(AESCrypt.decrypt(getKeySpec(), getIV(), stringToBytes(encryptedMsg)));
修改:
我明白做new String(someBytes)
没有意义,所以我也尝试将字节转换为Base64
:
public static void saveCredentials(Context context, String username, String password) {
try {
String formattedMsg = String.format(MSG_FORMAT, username, password);
byte[] bytes = stringToBytes(formattedMsg);
byte[] encryptedBytes = AESCrypt.encrypt(getKeySpec(), getIV(), bytes);
String encryptedMsg = Base64.encodeToString(encryptedBytes, Base64.NO_WRAP);
//save to sharedpreferences
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] stringToBytes(String msg) {
byte[] bytes = msg.getBytes(Charset.forName("UTF-8"));
return bytes;
}
public static LoginCredentials getSavedCredentials(Context context) {
try {
String base64Msg = getSharedPreferences(context).getString(PREFS_FILE_NAME, "");
byte[] bytes = Base64.decode(base64Msg, Base64.NO_WRAP);
byte[] decryptedBytes = AESCrypt.decrypt(getKeySpec(), getIV(), bytes);
String messageAfterDecrypt = ????;
//...
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
我没有收到错误,但我不知道如何获得最终的解密消息(行String messageAfterDecrypt = ????;
)