Android端可用的AES加密/解密,已直接封装为文件加密

来源:互联网 发布:刺客信条战斗力知乎 编辑:程序博客网 时间:2024/06/06 20:15

本文转载自http://blog.csdn.net/zjclugger/article/details/34838447,
将可用的内容修改整理后发布。

主要功能类 AESHelper .java

import android.util.Log;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.security.InvalidAlgorithmParameterException;import java.security.InvalidKeyException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.SecureRandom;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.KeyGenerator;import javax.crypto.NoSuchPaddingException;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;public class AESHelper {    private static final String TAG = AESHelper.class.getSimpleName();    public boolean AESCipher(int cipherMode, String sourceFilePath,                             String targetFilePath, String seed) {        boolean result = false;        FileChannel sourceFC = null;        FileChannel targetFC = null;        try {            if (cipherMode != Cipher.ENCRYPT_MODE                    && cipherMode != Cipher.DECRYPT_MODE) {                return false;            }            Cipher mCipher = Cipher.getInstance("AES/CFB/NoPadding");            byte[] rawkey = getRawKey(seed.getBytes("UTF-8"));            File sourceFile = new File(sourceFilePath);            File targetFile = new File(targetFilePath);            sourceFC = new RandomAccessFile(sourceFile, "r").getChannel();            targetFC = new RandomAccessFile(targetFile, "rw").getChannel();            SecretKeySpec secretKey = new SecretKeySpec(rawkey, "AES");            mCipher.init(cipherMode, secretKey, new IvParameterSpec(                    new byte[mCipher.getBlockSize()]));            ByteBuffer byteData = ByteBuffer.allocate(1024);            while (sourceFC.read(byteData) != -1) {                // 通过通道读写交叉进行。                // 将缓冲区准备为数据传出状态                byteData.flip();                byte[] byteList = new byte[byteData.remaining()];                byteData.get(byteList, 0, byteList.length);                //此处,若不使用数组加密解密会失败,因为当byteData达不到1024个时,加密方式不同对空白字节的处理也不相同,从而导致成功与失败。                byte[] bytes = mCipher.doFinal(byteList);                targetFC.write(ByteBuffer.wrap(bytes));                byteData.clear();            }            result = true;        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException                | InvalidAlgorithmParameterException                | IllegalBlockSizeException | BadPaddingException                | NoSuchPaddingException | NoSuchProviderException e) {            Log.d(TAG, e.getMessage());        } finally {            try {                if (sourceFC != null) {                    sourceFC.close();                }                if (targetFC != null) {                    targetFC.close();                }            } catch (IOException e) {                Log.d(TAG, e.getMessage());            }        }        return result;    }    /**     * 使用一个安全的随机数来产生一个密匙,密匙加密使用的     *     * @param seed 密钥种子(字节)     * @return 得到的安全密钥     * @throws NoSuchAlgorithmException     */    private byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException, NoSuchProviderException {        // 获得一个随机数,传入的参数为默认方式。        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");     //网上博客添加"Crypto" 后方能使用        // 设置一个种子,一般是用户设定的密码        sr.setSeed(seed);        // 获得一个key生成器(AES加密模式)        KeyGenerator keyGen = KeyGenerator.getInstance("AES");        // 设置密匙长度128位        keyGen.init(128, sr);        // 获得密匙        SecretKey key = keyGen.generateKey();        // 返回密匙的byte数组供加解密使用        return key.getEncoded();    }}

为避免线程阻塞,在界面里的子线程中调用以下方法

  AESHelper mAESHelper = new AESHelper();        //自定义密钥,字母和数字混合        String mSeed = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";//Cipher.ENCRYPT_MODE表示加密模式,Cipher.DECRYPT_MODE表示解密模式        String  result = mAESHelper.AESCipher(Cipher.ENCRYPT_MODE, SourceFilePath,                        NewFilePath + NewFileName, mSeed) ? "加密已完成" : "加密失败!";

已经完成,亲测可用,无法使用的童鞋请留下评论

0 0