-IV是相同的,因为目前它是静态变量,用于测试目的。
-密码设置为AES/CBC/PKCS5Padding
-键设置为AES
SharedPreferences sharedPreferences = context.getSharedPreferences(GENERATED_KEY, Context.MODE_PRIVATE);
String keyStr = sharedPreferences.getString(GENERATED_KEY, null);
if (keyStr == null) {
final int outputKeyLength = 128;
SecureRandom secureRandom = new SecureRandom();
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(outputKeyLength, secureRandom);
SecretKey key = keyGenerator.generateKey();
byte[] bytes = key.getEncoded();
keyStr = Base64.encodeToString(bytes, Base64.DEFAULT);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(GENERATED_KEY, keyStr);
editor.commit();
return key.toString();
} else {
return keyStr;
}
connection = (HttpURLConnection) url.openConnection();
connection.connect();
SecretKey secretKey = getSecretKey(context);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
spec = generateIv(cipher.getBlockSize());
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, spec);
input = connection.getInputStream();
cis = new CipherInputStream(input, cipher);
String FILEPATH = context.getFilesDir().getParentFile().getPath();
File file = new File(FILEPATH, "/download/" + id + "/");
if (!file.exists()) {
file.mkdirs();
}
xmlFile = new File(FILEPATH + "/download/" + id + "/", "xmldata.xml");
output = new FileOutputStream(xmlFile);
cos = new CipherOutputStream(output, cipher);
byte data[] = new byte[4096];
int count;
while ((count = cis.read(data)) != -1) {
if (isCancelled()) throw new TaskCanceledException();
cos.write(data, 0, count);
progress = -1;
publishProgress();
}
if (isCancelled()) throw new TaskCanceledException();
public String decryptXml() {
String data = null;
File file = new File(context.getFilesDir().getParentFile().getPath() + "/download/" + id + "/xmldata.xml");
int size = (int) file.length();
byte[] bytes = new byte[size];
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(getSecretKey(context).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, DownloadBookAsyncTask.spec);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytes, 0, bytes.length);
bis.close();
byte[] decrypted = cipher.doFinal(bytes);
}
public SecretKey getSecretKey(Context context){
SharedPreferences sharedPreferences = context.getSharedPreferences(DashboardFragment.GENERATED_KEY, Context.MODE_PRIVATE);
String stringKey = sharedPreferences.getString(DashboardFragment.GENERATED_KEY, null);
byte[] encodedKey = Base64.decode(stringKey, Base64.DEFAULT);
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}
编辑
添加IV发生器方法
public AlgorithmParameterSpec generateIv(int size) throws NoSuchAlgorithmException {
AlgorithmParameterSpec ivspec;
byte[] iv = new byte[size];
new SecureRandom().nextBytes(iv);
ivspec = new IvParameterSpec(iv);
return ivspec;
}
好的,我找到问题了。我的代码不能工作的原因是我在加密中使用了CipherInputStream,我不应该这样做。我还重做了整个解密方法,现在看起来是这样的:
byte[] wholeFileByte = null;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, key, DownloadBookAsyncTask.ivspec);
File file = new File(context.getFilesDir().getParentFile().getPath() + "/download/" + id + "/xmldata.xml");
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
CipherInputStream cis = new CipherInputStream(fis, cipher);
byte data[] = new byte[4096];
int count;
while ((count = cis.read(data)) != -1) {
bos.write(data, 0, count);
}
if(cis != null)
cis.close();
if(bos != null)
bos.close();
if(fis != null)
fis.close();
wholeFileByte = bos.toByteArray();
String kk = new String(wholeFileByte, "UTF-8");
我认为我犯的另一个错误是,我在解密时使用了doFinal,即使密码已经完成了解密,这也是我的一些错误的来源。
感谢@Garibn,因为你让我走上了正确的道路,当我的代表允许我的时候,你会投你的赞成票:)
我被困在一个问题与AES解密在我的Android应用程序。我已经搜索了很多,但无法得到解决方案。 这是步骤,我正在做的。 用我的密钥加密信用卡号并发送到Web服务器 此外,来自服务器的加密信息与我们以加密格式发送的信息不同。在iPhone应用程序中也做了同样的事情,iPhone能够成功地解密信息。 我使用以下代码进行加密和解密。 请建议。 编辑:我还有一件事,那就是工作
我尝试解密从Web服务接收的加密数据。 使用AES 128进行加密。 我使用以下代码对数据进行解密: 在 密码doFinal() 我得到了以下例外: javax.crypto.badpaddingexception垫块损坏 我浏览了我的帖子,但没有找到解决办法。我被困在这里了。
我编写了一个简单的Java AES加密和解密,如下所示(用于学习): 编辑: 我想我搞错了。黑客可能不会使用我的程序来解密。所以对于AES来说,如果一个人解密失败,他会知道解密失败,但不会像我想的那样,从解密中得到错误的字节?这太可怕了...
我正在编写android应用程序,使AES加密/解密的文件。我希望能够检测是否指定了不正确的密码,因此不匹配的密钥是为解密派生的。我使用aes/cbc/pkcs7padding和256位密钥。如果我执行cipher.doFinal(),我可以尝试/捕捉BadPaddingException,它会告诉我有些地方出错了,可能是key不正确。但是如果我使用CipherInputStream读取加密文件,
附注:这是我们在IOS中设置加密的方式: key和IV的推导方法: