文档章节

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

物种起源-达尔文
 物种起源-达尔文
发布于 2017/02/20 11:23
字数 489
阅读 1705
收藏 56
点赞 4
评论 4

图片防止篡改部分

第一步,获取图片的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);
    }

简单实现,没有进行调优

© 著作权归作者所有

共有 人打赏支持
物种起源-达尔文
粉丝 3
博文 16
码字总数 7457
作品 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

Java 的 Ruby 解释器 - JRuby

JRuby是面向Ruby、基于Java虚拟机(JVM)的一种解释程序,它结合了Ruby语言的简易性和功能强大的JVM的执行机制,包括与Java库 全面集成。Rails彻底加快及简化了Web应用的开发,不过它让人觉得不...

匿名 ⋅ 2008/09/07 ⋅ 2

Java就业变难了?你需要对自己有点信心

伴随着IT的火热,越来越多的人进入了IT领域,这在进一步推动着IT发展的同时也极大增加了就业压力。伴随着激烈的岗位竞争,越来越多的人开始感叹工作难找,越火的行业越是如此,Java自是首当其...

糖宝_d864 ⋅ 06/08 ⋅ 0

JRuby 9.1.17.0 发布,改进对 Java 9/10 的兼容性

JRuby 9.1.17.0 已发布,JRuby 是面向 Ruby、基于 Java 虚拟机(JVM)的一种解释程序,它结合了 Ruby 语言的简易性和功能强大的 JVM 的执行机制,包括与 Java 库全面集成。Rails 彻底加快及简化...

王练 ⋅ 04/24 ⋅ 0

14、Java并发性和多线程-Java ThreadLocal

以下内容转自http://ifeve.com/java-theadlocal/: Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作。因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有...

easonjim ⋅ 2017/06/16 ⋅ 0

利用“进程注入”实现无文件复活 WebShell

  * 本文作者:rebeyond,本文属FreeBuf原创奖励计划,未经许可禁止转载   引子   上周末,一个好兄弟找我说一个很重要的目标shell丢了,这个shell之前是通过一个S2代码执行的漏洞拿到...

FreeBuf ⋅ 05/30 ⋅ 0

JAVA使用字节流将本地图片传到前端

JAVA使用字节流将本地图片传到前端 01.基本介绍 在我们日常的开发中,会遇到对验证码的使用问题(验证码的作用这里不多多说,避免程序被恶意攻击等),如何是的前端和后端保持一致是一个问题...

meiqi0538 ⋅ 04/09 ⋅ 0

sharding-jdbc源码分析—准备工作

原文作者:阿飞Javaer 原文链接:https://www.jianshu.com/p/7831817c1da8 接下来对sharding-jdbc源码的分析基于tag为源码,根据sharding-jdbc Features深入学习sharding-jdbc的几个主要特性...

飞哥-Javaer ⋅ 05/03 ⋅ 0

java程序员基础进阶篇,万丈高楼平地起

一.final,finally,finalize 三者区别 Final是一个修饰符: 当final修饰一个变量的时候,变量变成一个常量,它不能被二次赋值 当final修饰的变量为静态变量(即由static修饰)时,必须在声明这...

启示录是真的 ⋅ 05/26 ⋅ 0

升级到JDK9的一个BUG,你了解吗

概述 前几天在一个群里看到一个朋友发了一个demo,说是JDK的bug,昨天在JVM的一个群里又有朋友发了,觉得挺有意思,分享给大家,希望大家升级JDK的版本的时候注意下是否存在这样的代码,如果...

你假笨 ⋅ 06/06 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据工程师需要精通算法吗,要达到一个什么程度呢?

机器学习是人工智能的一个重要分支,而机器学习下最重要的就是算法,本文讲述归纳了入门级的几个机器学习算法,加大数据学习群:716581014一起加入AI技术大本营。 1、监督学习算法 这个算法由...

董黎明 ⋅ 26分钟前 ⋅ 0

Kylin 对维度表的的要求

1.要具有数据一致性,主键值必须是唯一的;Kylin 会进行检查,如果有两行的主键值相同则会报错。 2.维度表越小越好,因为 Kylin 会将维度表加载到内存中供查询;过大的表不适合作为维度表,默...

无精疯 ⋅ 29分钟前 ⋅ 0

58到家数据库30条军规解读

军规适用场景:并发量大、数据量大的互联网业务 军规:介绍内容 解读:讲解原因,解读比军规更重要 一、基础规范 (1)必须使用InnoDB存储引擎 解读:支持事务、行级锁、并发性能更好、CPU及...

kim_o ⋅ 32分钟前 ⋅ 0

代码注释中顺序更改 文件读写换行

`package ssh; import com.xxx.common.log.LogFactory; import com.xxx.common.log.LoggerUtil; import org.apache.commons.lang3.StringUtils; import java.io.*; public class DirErgodic ......

林伟琨 ⋅ 40分钟前 ⋅ 0

linux实用操作命令

参考 http://blog.csdn.net/qwe6112071/article/details/50806734 ls [选项] [目录名 | 列出相关目录下的所有目录和文件 -a 列出包括.a开头的隐藏文件的所有文件-A 同-a,但不列出"."和"...

简心 ⋅ 56分钟前 ⋅ 0

preg_match处理中文符号 url编码方法

之前想过直接用符号来替换,但失败了,或者用其他方式,但有有些复杂,这个是一个新的思路,亲测可用 <?php$str='637朗逸·超速新风王(300)(白光)'; $str=iconv("UTF-8","GBK",$s...

大灰狼wow ⋅ 今天 ⋅ 0

DevOps 资讯 | PostgreSQL 的时代到来了吗 ?

PostgreSQL是对象-关系型数据库,BSD 许可证。拼读为"post-gress-Q-L"。 作者: Tony Baer 原文: Has the time finally come for PostgreSQL?(有删节) 近30年来 PostgreSQL 无疑是您从未听...

RiboseYim ⋅ 今天 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 今天 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 今天 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部