文档章节

用JAVA写一个简易图片防篡改

物种起源-达尔文
 物种起源-达尔文
发布于 2017/02/20 11:23
字数 489
阅读 1734
收藏 57

图片防止篡改部分

第一步,获取图片的md5字符串,并转为字节数组

 //将图片使用md5加密
    private static byte[] img2Md5Bytes(File file,String salt) throws Exception{
        FileInputStream inputStream=new FileInputStream(file);
        StringBuilder builder=new StringBuilder();
        byte[] bytes=new byte[1024];
        int bytesRead;
        while ((bytesRead=inputStream.read(bytes))!=-1){
            builder.append(new String(bytes,0,bytesRead));
        }
        inputStream.close();
        builder.append(salt);
        String md5=md5(builder.toString());
        return hexStringToBytes(md5);
    }

    //16进制转字节数组
    private static   byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 6 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    //md5加密字符串
    private static String md5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            return "";
        }
    }

第二步,图片末尾加md5字节数组

 //图片末尾加md5字节数组
    private static void imgAppendMd5Bytes(File file,byte[] md5Bytes) throws Exception{
        RandomAccessFile accessFile=new RandomAccessFile(file,"rw");
        long length=accessFile.length();
        accessFile.seek(length);
        accessFile.write(md5Bytes);
        accessFile.close();
    }

第三步,封装一下

  //防止图片被篡改
    private static void preventTamper(File file,String salt) throws Exception{
        byte[] md5bytes=img2Md5Bytes(file,salt);
        imgAppendMd5Bytes(file,md5bytes);
    }

图片验证部分

第一步,获取图片的末尾存储的md5字节数组

 //获取存储在图片末尾的16个md5字节
    public static byte[] popMd5Bytes(File file) throws Exception{
        RandomAccessFile accessFile=new RandomAccessFile(file,"rw");
        byte[] bytes=new byte[16];
        long length=accessFile.length();
        accessFile.seek(length-16);
        for (int i=0;i<16;i++){
            bytes[i]=accessFile.readByte();
        }
        accessFile.close();
        return bytes;
    }

第二步,去除图片末尾的16个md5字节后,重新计算图片的md5值

 //去除图片末尾的16个md5字节
    private static void imgDelEndMd5Bytes(File file) throws Exception{
        RandomAccessFile accessFile=new RandomAccessFile(file,"rw");
        FileChannel fc = accessFile.getChannel();
        fc.truncate(accessFile.length()-16);
        fc.close();
        accessFile.close();
    }
 byte[] imgMd5=img2Md5Bytes(file,salt);

第三步,封装为方法

 //验证图片是否被篡改
    private static boolean notTamper(File file,String salt) throws Exception{
        byte[] storageMd5=popMd5Bytes(file);//获取存储在图片末尾的16个md5字节
        imgDelEndMd5Bytes(file);//删除末尾md5字节数组
        byte[] imgMd5=img2Md5Bytes(file,salt);
        return Arrays.equals(storageMd5,imgMd5);
    }

简单实现,没有进行调优

© 著作权归作者所有

共有 人打赏支持
物种起源-达尔文

物种起源-达尔文

粉丝 4
博文 30
码字总数 27544
作品 0
深圳
程序员
加载中

评论(4)

题目里的小明
题目里的小明
什么业务场景需要这个东西。。
飞天的小熊
楼主你好,我编写了这个异步例子:
class index(tornado.web.RequestHandler):
@tornado.gen.coroutine
def asyncecho(self):
time.sleep(5)

logger.info("async")
raise gen.Return((200,{}))
@tornado.gen.coroutine
def get(self):
(status, ret) = yield self.asyncecho()
self.finish("async")
if __name__ == '__main__':
gc.set_threshold(100, 5, 2)
gc.enable()
logging_init('broker_server','.')
app = tornado.web.Application([(r"/",index)], compress_response = True)
app.listen(33333)
try:
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
print "receive KeyboardInterrupt signal..."

用curl 127.0.0.1:33333, 为什么还是串行执行啊?不是同时执行啊
请楼主给予解析,谢谢
物种起源-达尔文
物种起源-达尔文

引用来自“公孙二狗”的评论

如果别人知道你的做法和算法呢?为了保证不被删改,还需要对 MD5 做 RSA 签名,秘钥在你手里。
是,其实还有很多调优的地方,这里并没有写,看实际开发中的扩展呗
公孙二狗
公孙二狗
如果别人知道你的做法和算法呢?为了保证不被删改,还需要对 MD5 做 RSA 签名,秘钥在你手里。
SpringBoot 整合 oauth2(五)实现 jwt 及 扩展

什么是jwt,即 json web token。JWT是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。也是一种token,但是和token有一些不同。 jwt优点: 自包含 防篡改 可自定义扩展 JW...

FantJ
05/22
0
0
google protobuf3简易教程

版权声明:本文为博主原创文章,欢迎大家讨论,未经博主允许不得转载. https://blog.csdn.net/u010398771/article/details/82077915 google 的 protobuf 一个及其快速,以及好用的序列化框架,支...

长河
08/26
0
0
10 个最受欢迎的 Java 开发的 CMS 系统

转于:http://www.oschina.net/news/32888/10-most-popular-java-based-cms CMS是Content Management System的缩写,意为"内容管理系统",它具有许多基于模板的优秀设计,可以加快网站开发的...

stamen
2015/08/19
0
0
什么是Java语言?java语言简介

Java是由Sun Microsystems公司于1995年5月推出的Java程序设计语言(以下简称Java语言)和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的W...

阿秀a
2010/10/19
0
0
Scala学习笔记(7)-函数式对象

Java类具有可以带参数的构造器,而Scala类可以直接带参数。Scala的写法更简洁——类参数可以直接在类的主体中使用;没必要定义字段然后写赋值函数把构造器的参数复制到字段里。这可以潜在地节...

山海经
2013/08/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

实战讲解高并发和秒杀抢购系统设计

互联网特别是电商平台,阿里双11秒杀、还有12306春运抢票、以及平时各种节假日抢购活动等,都是典型的高并发场景。 这类场景最大的特征就是活动周期短,瞬间流量大(高并发),大量的人短期涌...

xtof
29分钟前
0
0
代码质量管理平台-sonarqube

在工作中,往往开发的时候会不怎么注重代码质量的人很多,存在着很多的漏洞和隐患等问题,sonarqube可以进行代码质量的审核,而且十分的残酷。。。。。接下来我们说下怎么安装 进入官网下载:...

落叶清风
31分钟前
6
0
在Ubuntu安装和配置Sphinx

Ubuntu系统默认是配置有sphinx的,先检查一下,别多此一举。。。。。 在开始本指南之前,您需要: 一个Ubuntu 16.04服务器。 sudo的一个非root用户,您可以通过以下设置本教程 。 安装在服务...

阿锋zxf
40分钟前
1
0
Qt编写输入法V2018超级终结版

对于qt嵌入式linux开发人员来说,输入法一直是个鸡肋问题,要么不支持实体键盘同步,要么不能汉字输入,要么不支持网页输入等,这几年通过陆续接触大量的各种输入法应用场景客户,得到真实需...

飞扬青云
51分钟前
2
0
TypeScript基础入门之高级类型的多态的 this类型

转发 TypeScript基础入门之高级类型的多态的 this类型 高级类型 多态的this类型 多态的this类型表示的是某个包含类或接口的子类型。 这被称做F-bounded多态性。 它能很容易的表现连贯接口间的...

durban
58分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部