【问题标题】:Decrypt AES256 encrypted bytes解密 AES256 加密字节
【发布时间】:2015-01-30 05:58:48
【问题描述】:

我以前从未使用过加密。其实我对加密一无所知。我有一个使用参数的 openssl 工具加密的文件:

openssl aes-256-cbc -nosalt -in fileIn -out fileOUT -p -k KEY

我需要将它解密到内存中,但我不知道如何。谁能给我加密相关的代码?

【问题讨论】:

标签: android encryption aes


【解决方案1】:

这是我编写的用于解密使用上述参数编码的字符串的类(如果我没记错的话):

public class CipherUtils {
    public static byte[] getKey(String password, byte[] salt) {
        try {
            byte[] passwordSalt = EncodingUtils.getAsciiBytes(password);
            passwordSalt = concatenateByteArrays(passwordSalt, salt);

            byte[] hash1 = getHashForHash(null, passwordSalt);
            byte[] hash2 = getHashForHash(hash1, passwordSalt);
            byte[] key = concatenateByteArrays(hash1, hash2);

            return key;
        } catch (Exception e) {
            return null;
        }

    }

    public static byte[] getIV(String password, byte[] salt) {
        try {
            byte[] passwordSalt = EncodingUtils.getAsciiBytes(password);
            passwordSalt = concatenateByteArrays(passwordSalt, salt);
            byte[] hash1 = getHashForHash(null, passwordSalt);
            byte[] hash2 = getHashForHash(hash1, passwordSalt);
            byte[] hash3 = getHashForHash(hash2, passwordSalt);
            return hash3;
        } catch (Exception e) {
            return null;
        }

    }

    private static byte[] getHashForHash(byte[] hash, byte[] passwordSalt) {
        try {
            byte[] hashMaterial = concatenateByteArrays(hash, passwordSalt);
            MessageDigest md = MessageDigest.getInstance("MD5");
            return md.digest(hashMaterial);
        } catch (Exception e) {
            return null;
        }
    }

    private static byte[] concatenateByteArrays(byte[] a, byte[] b) {
        if (a == null)
            return b;
        if (b == null)
            return a;
        byte[] result = new byte[a.length + b.length];
        System.arraycopy(a, 0, result, 0, a.length);
        System.arraycopy(b, 0, result, a.length, b.length);
        return result;
    }
}

在这种情况下,Salt 是一个空字节数组。它使用 apache-commons-compress.jar。

以下是用法示例:

byte[] key = CipherUtils.getKey(password, null);
byte[] IV = CipherUtils.getIV(password, null);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),
        new IvParameterSpec(IV));
cis = new CipherInputStream(is, cipher);

其中is 是加密数据的InputStream

【讨论】:

    【解决方案2】:

    这可能对你有帮助

    public void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
            // Here you read the cleartext.
            FileInputStream fis = new FileInputStream("data/cleartext");
            // This stream write the encrypted text. This stream will be wrapped by
            // another stream.
            FileOutputStream fos = new FileOutputStream("data/encrypted");
    
            // Length is 16 byte
            SecretKeySpec sks = new SecretKeySpec("yourkey".getBytes(), "AES");
            // Create cipher
            Cipher cipher = Cipher.getInstance("AES/CBC");
            cipher.init(Cipher.ENCRYPT_MODE, sks);
            // Wrap the output stream
            CipherOutputStream cos = new CipherOutputStream(fos, cipher);
            // Write bytes
            int b;
            byte[] d = new byte[8];
            while ((b = fis.read(d)) != -1) {
                cos.write(d, 0, b);
            }
            // Flush and close streams.
            cos.flush();
            cos.close();
            fis.close();
        }
    

    解密

    public  void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
            FileInputStream fis = new FileInputStream("data/encrypted");
    
            FileOutputStream fos = new FileOutputStream("data/decrypted");
            SecretKeySpec sks = new SecretKeySpec("yourkey".getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC");
            cipher.init(Cipher.DECRYPT_MODE, sks);
            CipherInputStream cis = new CipherInputStream(fis, cipher);
            int b;
            byte[] d = new byte[8];
            while((b = cis.read(d)) != -1) {
                fos.write(d, 0, b);
            }
            fos.flush();
            fos.close();
            cis.close();
        }
    

    【讨论】:

    • 问题是我只知道密码。我需要以某种方式获得密钥和 IV。
    • 只要给我加密的文件和密码。
    • 可悲的是,我得到 javax.crypto.BadPaddingException: pad block 使用类似代码损坏。 bpaste.net/show/B0jf8204RkRxvn3hsqB0 当我在 OpenSSL 中使用 -nosalt 参数时,我尝试撕掉与盐相关的所有内容,但随后出现错误,我的盐为空或零宽度。
    • 你能给我一个临时加密文件和密码用于测试吗?
    • dropbox.com/s/ci556if2974o8gg/test.txt "abc" 但是我提供了我使用的 OpenSSL 参数,因此您可以使用任何文件和密码。我能够解密没有“-nosalt”参数编码的文件。
    猜你喜欢
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多