【问题标题】:How to decrypt a data in Android which was crypted in nodejs如何解密在nodejs中加密的Android数据
【发布时间】:2013-12-06 17:14:53
【问题描述】:

在 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);
        });

安卓代码:

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 我不使用 SecureRandom 的 SecretKey 的一部分...这肯定是错误的,但我没有在 node.js 部分使用任何安全随机数。问题也可能与文件中的编码数据有关。

我通常在 nodejs 中生成一个文件,该文件由应用程序下载并存储在 sdcard 中,我不确定我是否应该真正关心这些数据,但如果将其加密会很酷,不是吗?: -)

非常感谢您的任何帮助或建议;-)

【问题讨论】:

  • 您是否有理由不能为此使用TLS 这样的标准?
  • 因为我想将文件存储在 sdcard 上的 android 设备中,用户可以轻松读取它

标签: android node.js cryptography encryption


【解决方案1】:

IllegalBlockSizeException 表示您的输入不是 AES 块大小(16 字节)的倍数。

您使用的解密方法看起来完全错误:

byte [] b = new byte[2000000];
is.read(b, 0, 2000000);
byte[] decryptedData = decrypt(key,"password".getBytes()); // <--- ???!

您正在为密文传递一个八字节的常量值。相反,您应该传递从输入流中读取的数据。

我强烈建议您研究读取整个输入流的正确方法,因为此代码 sn-p 表明您没有正确处理资源。您也可能最终得到一个比实际数据大得多的字节数组(除非您的文件正好是 2000000 字节长)。


旁注:创建Cipher 对象时始终指定模式和填充。例如,如果您知道您的 JavaScript 代码使用 CBC 模式和 PKCS#7 填充,请选择:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

这很重要,否则您依赖的默认值可能会因平台而异。

【讨论】:

  • 感谢您的快速回答;-) 您完全正确的是错误的解密调用。我已修复,也改进了文件中的加载数据,现在我得到了新的异常“没有设置 IV”无论如何,非常感谢你
  • @m1uan 您的 JavaScript 可能使用的是 ECB 模式而不是 CBC 模式。 ECB 模式不需要 IV 值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-19
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
  • 2014-11-21
相关资源
最近更新 更多