Android判断图片被篡改的方法

    xiaoxiao2026-09-16  2

    <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示例代码:

    import java.security.MessageDigest;  import java.io.FileInputStream;  import java.io.InputStream;    public class MD5 {      private static final char HEX_DIGITS[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',  'A', 'B', 'C', 'D', 'E', 'F' };        public static void main(String[] args)      {          System.out.println(md5sum("/init.rc"));      }        public static String toHexString(byte[] b) {          StringBuilder sb = new StringBuilder(b.length * 2);          for (int i = 0; i < b.length; i++) {              sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);              sb.append(HEX_DIGITS[b[i] & 0x0f]);          }          return sb.toString();      }        public static String md5sum(String filename) {          InputStream fis;          byte[] buffer = new byte[1024];          int numRead = 0;          MessageDigest md5;          try{              fis = new FileInputStream(filename);              md5 = MessageDigest.getInstance("MD5");              while((numRead=fis.read(buffer)) > 0) {                  md5.update(buffer,0,numRead);              }              fis.close();              return toHexString(md5.digest());             } catch (Exception e) {              System.out.println("error");              return null;          }      }  } 

    第三种: 保存到手机隐藏目录, 记住目录层级越深越隐蔽。请注意目录名".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; } }

    转载请注明原文地址: https://ju.6miu.com/read-1312083.html
    最新回复(0)