使用AES解密错误

时间:2016-02-22 09:43:53

标签: android

/**
 * 初始化 AES Cipher
 * @param sKey
 * @param cipherMode
 * @return
 */
public static Cipher initAESCipher (String sKey, int cipherMode) throws Exception {
    //创建Key gen
    KeyGenerator keyGenerator = null;
    Cipher cipher = null;
        keyGenerator = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance( "SHA1PRNG" ,"Crypto");
        sr.setSeed(sKey.getBytes("UTF-8"));
        keyGenerator.init(128,sr);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] codeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec(codeFormat, "AES");
        cipher = Cipher.getInstance("AES");
        //初始化
        cipher.init(cipherMode, key);
    return cipher;
}

/**
 * 对文件进行AES加密
 * @param sourceFile
 * @param fileType
 * @param sKey
 * @return
 */
public static File encryptFile(File sourceFile,String fileType, String sKey) throws Exception {
    //新建临时加密文件
    File encrypfile = null;
    InputStream inputStream = null;
    OutputStream outputStream = null;

        inputStream = new FileInputStream(sourceFile);
        encrypfile = new File(fileType);
        outputStream = new FileOutputStream(encrypfile);
        Cipher cipher = initAESCipher(sKey,Cipher.ENCRYPT_MODE);
        //以加密流写入文件
        CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
        byte[] cache = new byte[1024];
        int nRead = 0;
        while ((nRead = cipherInputStream.read(cache)) != -1) {
            outputStream.write(cache, 0, nRead);
            outputStream.flush();
        }
        cipherInputStream.close();
            inputStream.close();
            outputStream.close();
            sourceFile.delete();

    return encrypfile;
}

我想使用AES加密=和解密文件。这是我的代码。

/**
 * AES方式解密文件
 * @param sourceFile
 * @return
 */
public static File decryptFile(File sourceFile,String fileType,String sKey) throws Exception {
    File decryptFile = null;
    InputStream inputStream = null;
    OutputStream outputStream = null;
        decryptFile = new File(fileType);
        Cipher cipher = initAESCipher(sKey,Cipher.DECRYPT_MODE);
        inputStream = new FileInputStream(sourceFile);
        outputStream = new FileOutputStream(decryptFile);
        CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
        byte [] buffer = new byte [1024];
        int r;
        while ((r = inputStream.read(buffer)) >= 0) {
            cipherOutputStream.write(buffer, 0, r);
        }
        cipherOutputStream.close();
            inputStream.close();
            outputStream.close();
            sourceFile.delete();
    return decryptFile;
}

我用它来加密和解密文件,但是我得到了以下日志:

02-22 17:36:38.451 11972-11995/com.augur.android.agcom W/System.err: java.io.IOException: pad block corrupted

任何人都可以帮助我吗?我已经困惑了两个星期。

1 个答案:

答案 0 :(得分:0)

在实例化Cipher.getInstance("AES")时,您没有提供填充。最好同时提供填充选项和模式,因为基本文档指出:"特定于提供者的模式和填充方案的默认值"这可能会有所不同。

初始化字符串应包括填充和模式。

由于没有提供iv,可能正在使用ECB模式,这不安全,但初始化字符串将是:" AES / ECB / PKCS5Padding"。 (PKCS#5填充是过时的,但与PKCS#7基本相同)。

但是不要使用ECB模式,它不安全,而是使用带有随机IV和MAC的CBC加密字符串进行身份验证。