Android判断图片被篡改的方法

<span style="font-size:18px;">需求: app调用照相机拍摄若干张图片,<span style="color:#FF0000;">在图库中不显示这些图片,避免被拷贝篡改</span>。 在以后有wifi的环境下上传到服务器。 要求判断出这些图片被篡改过?</span>

按照安卓的设计, 在拍照后MediaScanner会扫出手机的所有照片并在图库中显示出来。

      

       备注:我考虑过使用图片Exif属性判断图片被篡改过,  后来发现有工具可以修改Exif属性, 所以exif这条路走不通。


三种实现方式:


名称缓存到sqlite校验MD5保存到隐藏目录
实现方式 将图片数据存到数据库一张表的blob字段里拍摄照片后将图片完整路径, 图片的MD5值存储到应用的database里,  在传输图片前比较图片文件的MD5值。在sdcard下建立层次比较深的目录, 最终以".nomedia"格式命名文件夹, 在Android系统里以.作前缀是隐藏文件夹。
优点只有本应用能读写,安全性高。通过比较MD5值,能判断出文件是否被篡改。实现简单,在手机图库里找不到这些图片, 在文件管理器也找不到隐藏目录。 如果目录层级很深, 一般很难被发现。
缺点适合小图片如缩略图计算MD5时要读图片文件, IO操作费时间耗内存。理解android系统的可以写工具软件找到隐藏目录。

第一种: 保存到sqlite的blob类型字段,  在建表时创建一个类型为blob的字段, 将图片数据保存到该字段。(在此不贴代码了,  找度娘)。


第二种: 计算MD5值, 也可以是其它算法的校验值,  就是用文件数据生成一个字符串。

md5示例代码:

  1. import java.security.MessageDigest;  
  2. import java.io.FileInputStream;  
  3. import java.io.InputStream;  
  4.   
  5. public class MD5 {  
  6.     private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',  
  7. 'A', 'B', 'C', 'D', 'E', 'F' };  
  8.   
  9.     public static void main(String[] args)  
  10.     {  
  11.         System.out.println(md5sum("/init.rc"));  
  12.     }  
  13.   
  14.     public static String toHexString(byte[] b) {  
  15.         StringBuilder sb = new StringBuilder(b.length * 2);  
  16.         for (int i = 0; i < b.length; i++) {  
  17.             sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);  
  18.             sb.append(HEX_DIGITS[b[i] & 0x0f]);  
  19.         }  
  20.         return sb.toString();  
  21.     }  
  22.   
  23.     public static String md5sum(String filename) {  
  24.         InputStream fis;  
  25.         byte[] buffer = new byte[1024];  
  26.         int numRead = 0;  
  27.         MessageDigest md5;  
  28.         try{  
  29.             fis = new FileInputStream(filename);  
  30.             md5 = MessageDigest.getInstance("MD5");  
  31.             while((numRead=fis.read(buffer)) > 0) {  
  32.                 md5.update(buffer,0,numRead);  
  33.             }  
  34.             fis.close();  
  35.             return toHexString(md5.digest());     
  36.         } catch (Exception e) {  
  37.             System.out.println("error");  
  38.             return null;  
  39.         }  
  40.     }  


第三种: 保存到手机隐藏目录, 记住目录层级越深越隐蔽。请注意目录名".nomedia", “.”是隐藏目录的前缀, 目录名随便定义。

参考代码:

public String getBaseDir(Context context) {
    String baseDir = null;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        baseDir = Environment.getExternalStorageDirectory() + "/" + FILE_NAME + "/";
    } else {
        baseDir = context.getCacheDir().getAbsolutePath() + "/" + FILE_NAME + "/";
    }
    File basedir = new File(baseDir);
    if (!basedir.exists()) {
        basedir.mkdirs();
    }
    return baseDir;
}

File mediaStorageDir = new File(
        FileManager.getInstance().getBaseDir(this), ".nomedia");
if (!mediaStorageDir.exists()) {
    if (!mediaStorageDir.mkdirs()) {
        Log.d("MyCameraApp", "failed to create directory");
        return null;
    }
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值