ITKeyword,专注技术干货聚合推荐

注册 | 登录

UniversalImageLoader加密磁盘缓存

loveliwenyan2012 2016-07-26

相关推荐:浅谈Android中的异步加载之ListView中图片的缓存及优化三

隔了很久没写博客,现在必须快速脉动回来。今天我还是接着上一个多线程中的异步加载系列中的最后一个使用异步加载实现ListView中的图片缓存及其

UniversalImageLoader加密磁盘缓存

感谢CSDN博主Mr_甘 的博客android imageloader加密解密图片(地址:http://blog.csdn.net/gan303/article/details/50266569

当使用网络图片缓存到本地时,基于安全考虑需要加密缓存到本地的数据,加上使用UIL已经很久了,并且很好用,所以决定扩展UIL支持加密本地缓存。开始干活了!!!

  在ImageLoaderConfiguration中找到imageDecoder和diskCache,imageDecoder用于提供读取数据生成Bitmap的接口,diskCache提供磁盘缓存的接口;就在这两个方面下功夫了。加密技术我选择javax下面CipherInputStream,提高效率,如果不满足你的需求可以自定义InputStream,重写read函数在(read函数里面进行加解密操作)就可以。这些前提就是你已经成功配置UniversalImageLoader库(包含需要的权限之类的)

  1(加密):继承UnlimitedDiskCache并重写save函数,save函数的功能就是将需要缓存到本地的数据保存在本地,当然我们只加密网络缓存图片,加密操作就是将原来的InputStream转化成加密的CipherInputStream。

相关推荐:Universal-Image-Loader,android-Volley,Picasso、Fresco和Glide图片缓存库的联系与区别

Universal-Image-Loader,android-Volley,Picasso、Fresco和Glide五大Android开源组件加载网络图片比较在Android中的加载网络图片是一件十分令

package com.common.cipher;

import android.util.Log;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.FileNameGenerator;
import com.nostra13.universalimageloader.utils.IoUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.crypto.CipherInputStream;

/** * 作者:徐仕海 on 2016/7/25 0025 14:47 * <p> 加密图片磁盘缓存 * 邮箱:1056483075@qq.com */

public class CipherUnlimitedDiskCache extends UnlimitedDiskCache {


    public CipherUnlimitedDiskCache(File cacheDir) {
        super(cacheDir);
    }

    public CipherUnlimitedDiskCache(File cacheDir, File reserveCacheDir) {
        super(cacheDir, reserveCacheDir);
    }

    public CipherUnlimitedDiskCache(File cacheDir, File reserveCacheDir, FileNameGenerator fileNameGenerator) {
        super(cacheDir, reserveCacheDir, fileNameGenerator);
    }

    @Override
    public boolean save(String imageUri, InputStream imageStream, IoUtils.CopyListener listener) throws IOException {
        Log.e("TAG", "保存到本地");
        InputStream inputStream;
        /** * 本地文件的缓存就不加密了 */
        if (imageUri.startsWith("http")) {
            try {
                inputStream = new CipherInputStream(imageStream, CipherImage.getInstance().getEncryptCipher());
            } catch (Exception e) {
                imageStream.close();
                e.printStackTrace();
                return false;
            }
        } else {
            inputStream = imageStream;
        }
        return super.save(imageUri, inputStream, listener);
    }
}

 2(解密):加密了图片接下来就是解密加密过后的数据,继承BaseImageDecoder,并重写getImageStream函数,当然我们也只解密网络图片,解密操作就是将InputStream转化成解密的CipherInputStream。
 

package com.common.cipher;

import com.nostra13.universalimageloader.core.decode.BaseImageDecoder;
import com.nostra13.universalimageloader.core.decode.ImageDecodingInfo;

import java.io.IOException;
import java.io.InputStream;

import javax.crypto.CipherInputStream;

/** * 作者:徐仕海 on 2016/7/25 0025 11:20 * <p> 解密图片解码器 * 邮箱:1056483075@qq.com */

public class CipherImageDecoder extends BaseImageDecoder {
    public CipherImageDecoder(boolean loggingEnabled) {
        super(loggingEnabled);
    }

    @Override
    protected InputStream getImageStream(ImageDecodingInfo decodingInfo) throws IOException {
        InputStream imageStream = super.getImageStream(decodingInfo);
        /** * 只解密网络下载的图片,其他的途径的图片不用加密所以就不用解密,加解密手段用的是Java的加解密输入流 */
        if (decodingInfo.getOriginalImageUri().startsWith("http")) {
            CipherInputStream in = null;
            try {
                in = new CipherInputStream(imageStream, CipherImage.getInstance().getDecryptCipher());
            } catch (Exception e) {
                e.printStackTrace();
                imageStream.close();
            }
            return in;
        }
        return imageStream;
    }

}

3(加解密Cipher对象):为了方便使用且方便修改密钥和加解密算法新建一个CipherImage类,他主要用来配置密钥和算法,生成加解密的Cipher对象供创建CipherInputStream类使用

package com.common.cipher;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

/** * 作者:徐仕海 on 2016/7/26 0026 10:18 * <p>主要提供加密密钥,加解密算法,加密Cipher对象,解密Cipher对象 * 邮箱:1056483075@qq.com */
public class CipherImage {
    private static CipherImage ourInstance = new Builder().build();

    public static CipherImage getInstance() {
        return ourInstance;
    }

    private CipherImage() {}

    /** * 加解密图片的密钥 */
    private String key;

    /** * 加解密算法 */
    private String algorithm;

    /** * 获取解密Cipher * * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException */
    public Cipher getDecryptCipher() throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        byte[] str = key.getBytes();
        Key key = new SecretKeySpec(str, 0, str.length, algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher;
    }

    /** * 获取加密Cipher * * @return * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws InvalidKeyException */
    public Cipher getEncryptCipher() throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        byte[] str = key.getBytes();
        Key key = new SecretKeySpec(str, 0, str.length, algorithm);
        Cipher cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        return cipher;
    }


    /** * 构造器 */
    public static class Builder {
        private String key, algorithm;

        public Builder() {
            key = "123456";//默认密钥
            algorithm = "RC4";//默认加解密算法
        }

        public Builder cipherKey(String key) {
            this.key = key;
            return this;
        }

        public Builder cipherAlgorithm(String algorithm) {
            this.algorithm = algorithm;
            return this;
        }

        public CipherImage build() {
            if (ourInstance == null) {
                ourInstance = new CipherImage();
            }
            ourInstance.algorithm = algorithm;
            ourInstance.key = key;
            return ourInstance;
        }
    }
}

 功能实现完毕,接下来该试试如何使用了。首先必须启用缓存到磁盘,在设置图片解码器和磁盘缓存,这样每张网络图片缓存在磁盘上的数据都是加密的都是安全的。
 

DisplayImageOptions displayImageOptions = new DisplayImageOptions.Builder().cacheOnDisk(true).cacheInMemory(true).build();
        ImageLoaderConfiguration configuration = null;
        configuration = new ImageLoaderConfiguration.Builder(this)
                .imageDecoder(new CipherImageDecoder(true))
                .diskCache(new CipherUnlimitedDiskCache(getExternalCacheDir()))
                .defaultDisplayImageOptions(displayImageOptions)
                .build();
 ImageLoader.getInstance().init(configuration);
 final ImageView imageView = (ImageView) findViewById(R.id.imageView);
 ImageLoader.getInstance().displayImage("http://desk.fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/0D/0D/ChMkJ1eV_E2IMTEQABERSEVD0poAAT0hAID5McAERFg559.jpg", imageView);

 当然如果你不喜欢默认的密钥123456或者默认的加解密算法RC4,可以更新密钥和算法,只要在图片保存之前都会有效
 

new CipherImage.Builder()
                .cipherAlgorithm("RC4")
                .cipherKey("dhghd")
                .build();

本文示例工程的地址http://files.cnblogs.com/files/xushihai/CipherUIL.rar

相关推荐:教你写Android ImageLoader框架之图片缓存 (完结篇)

在教你写Android ImageLoader框架系列博文中,我们从基本架构到具体实现已经更新了大部分的内容。今天,我们来讲最后一个关键点,即图片的缓存。为了

UniversalImageLoader加密磁盘缓存感谢CSDN博主Mr_甘 的博客android imageloader加密解密图片(地址:http://blog.csdn.net/gan303/article/details/50266569)当使用网络图片缓存到本地时...

相关阅读排行


用户评论

游客

相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。