在android中我总是 IllegalBlockSizeException ,数据在nodejs服务器中加密,看起来像(node.js: encrypting data that needs to be decrypted?):
var crypto = require('crypto');
console.log(crypto.getCiphers(), crypto.getHashes());
var algorithm = 'aes128'; // or any other algorithm supported by OpenSSL
var key = 'password';
var cipher = crypto.createCipher(algorithm, key);
var encrypted = cipher.update(data, 'utf8', 'binary') + cipher.final('binary');
fs.writeFile(file, encrypted, function (err) {
cb(err);
});
android代码:
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
来自文件的调用方法在输入流(is)中:
byte [] b = new byte[2000000];
is.read(b, 0, 2000000);
byte[] decryptedData = decrypt(key,"password".getBytes());
result = new String(decryptedData, "UTF8").split("\n");
android代码的灵感来自:android encryption/decryption with AES我不使用SecureKandom的部分SecretKey ...这肯定是错误的,但我不使用node.js部分中的任何安全随机。问题也可以在文件中编码数据。
我一般在nodejs中生成一个文件,由app下载并存储在SD卡中我不确定我是否应该真正关心这些数据但是如果它加密会很酷,不是吗?: - )
非常感谢您的任何帮助或建议; - )
答案 0 :(得分:3)
IllegalBlockSizeException
表示您的输入不是AES块大小的倍数(16字节)。
您对解密方法的使用看起来完全错误:
byte [] b = new byte[2000000];
is.read(b, 0, 2000000);
byte[] decryptedData = decrypt(key,"password".getBytes()); // <--- ???!
您正在传递密文的八字节常量值。相反,您应该传递从输入流中读取的数据。
我强烈建议您研究读取整个输入流的正确方法,因为此代码段表明您没有正确处理资源。您最终可能会得到比实际数据大得多的字节数组(除非您的文件长度恰好为2000000字节)。
旁注:在创建Cipher
对象时始终指定模式和填充。例如,如果您知道您的JavaScript代码使用CBC模式和PKCS#7填充,请选择:
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
这很重要,因为否则您依赖于平台之间可能不同的默认值。