简体   繁体   English

如何在Android中解密由Node.js加密的数据

[英]How to decrypt a data in Android which was crypted in nodejs

In android i get always IllegalBlockSizeException , the data are encrypted in nodejs server and looks like ( node.js: encrypting data that needs to be decrypted? ): 在android中,我总是得到IllegalBlockSizeException ,数据在nodejs服务器中加密,并且看起来像( node.js:正在加密需要解密的数据? ):

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 code: 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;
    }

call method from file is in input stream (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 code is inspired by : android encryption/decryption with AES where i dont use part of SecretKey with SecureRandom... which is for sure wrong, but i dont use any secure random in node.js part. android代码的灵感来自于: 用AES进行android加密/解密,其中我不使用带有SecureRandom的SecretKey的一部分...这是肯定的,但是我不在node.js部分使用任何安全的随机数。 The problem can be also with coding data in file. 问题也可能在于编码文件中的数据。

I generaly generate a file in nodejs which is downloaded by app and stored in sdcard i'm not sure if i should be realy care about these data but will be cool have it crypted, isn't it?:-) 我通常在nodejs中生成一个文件,该文件由应用程序下载并存储在sdcard中,我不确定我是否真的应该关心这些数据,但是将其加密会很酷,不是吗?

Thank you so much for any help or advice;-) 非常感谢您的帮助或建议;-)

An IllegalBlockSizeException means that your input is not a multiple of the AES block size (16 bytes). IllegalBlockSizeException意味着您的输入不是AES块大小(16字节)的倍数。

Your use of the decryption method looks completely wrong: 您对解密方法的使用看起来完全错误:

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

You are passing an eight byte constant value for your ciphertext. 您正在为密文传递八个字节的常量值。 Instead, you should be passing the data you read from your input stream. 相反,您应该传递从输入流中读取的数据。

I would strongly recommend you research the correct way to read an entire input stream, because this code snippet suggests you are not handling resources correctly. 我强烈建议您研究读取整个输入流的正确方法,因为此代码段表明您未正确处理资源。 You are also likely to end up with a byte array much larger than your actual data (unless your file is exactly 2000000 bytes long). 您还可能最终得到一个比实际数据大得多的字节数组(除非文件正好是2000000字节长)。


Side note: always specify the mode and padding when creating a Cipher object. 旁注:创建Cipher对象时始终指定模式和填充。 For instance, if you know your JavaScript code uses CBC-mode and PKCS#7 padding, select: 例如,如果您知道您的JavaScript代码使用CBC模式和PKCS#7填充,请选择:

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

This is important, because otherwise you are relying on default values that may differ between platforms. 这很重要,因为否则您将依赖于平台之间可能有所不同的默认值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM