Java清除图片中的恶意信息(利用jmagick)
2010-07-08 13:45
399 查看
接上篇,Java判断文件类型,继续图片安全问题。若已正确判断出图片类型,防止了绝大多数恶意图片上传。但是若通过修改文件流的方法,给一张本身合法的图片中强行写入一些恶意代码,或者病毒代码,这样前面的方法仍然能够顺利通过,因为它本身是张正确格式的图片,仅仅读取字节与获取图片类型无法做到清除这种类型图片中隐藏的恶意代码。附用UE打开后的恶意图片部分内容,图片的右半部分显示了恶意脚本:
试想,如这种类型图片上传到服务器,当引用了该图片的网页被访问时,而恰好用户的机子装了杀毒软件,则此时杀毒软件会对该页面报警,如果您的网页中存在大量的这种图片,那惨啦,一打开网页,杀毒软件就开始报病毒。这样用户还再敢访问您的网站。
针对这种情况,说白了就是如何清楚合法格式图片中隐藏的恶意信息问题,在工作中无意中发现jmagick可以对图片进行相应处理,而该工具提供的图片缩放方法能将多余的非图片元素清除,那么我们只需要在正确校验格式后对图片按原大小进行一次缩放来清除恶意信息:
代码如下:
运行以上程序后,再打开看原来的图片,恶意内容已经没有了,大小也比以前小了,杀毒软件也不会报病毒了。
附:jmagick工具的使用方法:
1. 从http://downloads.jmagick.org/6.3.9/下载windows下使用的jmagick-win-6.3.9-Q16.zip 。
解压后有两个文件jmagick.jar,jmagick.dll.
将jmagick.dll拷贝到系统目录system32下.
将jmagick.jar放在你的工程lib包下,或者环境变量能找着的地方。
2. 安装ImageMagick,官方网站:http://www.imagemagick.org/
3. 安装ImageMagick-6.3.9-0-Q16-windows-dll.exe
总结: 利用jmagick可以对图片做非常强大的处理,人是仅仅如果是校验图片格式以及用来清除图片中的恶意代码,有点杀鸡用牛九的感 觉,为了一个简单的图片校验便得我们的系统不仅要依赖第三方的包(jmagick.jar,jmagick.dll),而且要依赖 第三方的软件jmagick(因为不安装该软件,该方法所依赖的其它一些dll文件无法找到)。这样使得系统与第三方工具的耦合性太强,增加一个故障点。当然如果JDK本身能提供这种图片中恶意代码的清除功能最好不过了,但感觉有点不现实,因为清楚图片里的恶意代码有点类似杀毒软件的功能,纠结~~~,那位大侠有好的建议告诉下小弟,不甚感激。
注意:使用中容易出现的问题
1.若报如下异常
原因:往往是安装ImageMagick-6.3.9-0-Q16-windows-dll.exe时没有全选安装项造成
解决办法:在安装ImageMagick-6.3.9-0-Q16-windows-dll.exe时要全选安装项,截图如下
2.若报如下异常
原因:虽然你的jmagick.jar引入了,但是并没有被默认的类加载器加载进来。
解决办法:在类里加上静态块,用系统的类加载器指定下
本程序测试环境: WindowsXP + JDK6.0 +Eclipse3.4.1+ImageMagick-6.3.9-0-Q16-windows
如果要在Linux环境下使用,请使用对应的Linux版本(本人未做测试)。
试想,如这种类型图片上传到服务器,当引用了该图片的网页被访问时,而恰好用户的机子装了杀毒软件,则此时杀毒软件会对该页面报警,如果您的网页中存在大量的这种图片,那惨啦,一打开网页,杀毒软件就开始报病毒。这样用户还再敢访问您的网站。
针对这种情况,说白了就是如何清楚合法格式图片中隐藏的恶意信息问题,在工作中无意中发现jmagick可以对图片进行相应处理,而该工具提供的图片缩放方法能将多余的非图片元素清除,那么我们只需要在正确校验格式后对图片按原大小进行一次缩放来清除恶意信息:
代码如下:
package apistudy; import java.io.IOException; import magick.ImageInfo; import magick.MagickImage; /** * Created on 2010-7-8 * <p>Description: [通过jmagick清除图片中的恶意信息]</p> * @author shixing_11@sina.com * @version 1.0 */ public class ImageTypeTest { static { System.setProperty("jmagick.systemclassloader", "no"); } /** * Created on 2010-7-8 * <p>Discription:[main]</p> * @param args * @author:[shixing_11@sina.com] */ public static void main(String[] args) { String srcFileName = "c:/img/c.jpg"; try { filterImageByScale(srcFileName); } catch (IOException e) { e.printStackTrace(); } } /** * Created on 2010-7-8 * <p>Discription:[filterImageByScale,清除图片中的恶意代码]</p> * @param srcFileName * @throws IOException * @author:[shixing_11@sina.com] */ public final static void filterImageByScale(String srcFileName) throws IOException { MagickImage magic = null; try { ImageInfo imgInfo = new ImageInfo(srcFileName); magic = new MagickImage(imgInfo); int width = (int) magic.getDimension().getWidth(); int height = (int) magic.getDimension().getHeight(); MagickImage newImage = magic.scaleImage(width, height); newImage.profileImage("*", null); //清除无用信息 newImage.setImageAttribute("JPEG-Sampling-factors", null); //清除无用信息 newImage.setImageAttribute("comment", null); //清除无用信息 newImage.writeImage(new ImageInfo()); newImage.writeImage(imgInfo); } catch (Exception e1) { e1.printStackTrace(); } finally { try { magic.destroyImages(); } catch (Exception e2) { e2.printStackTrace(); } } } }
运行以上程序后,再打开看原来的图片,恶意内容已经没有了,大小也比以前小了,杀毒软件也不会报病毒了。
附:jmagick工具的使用方法:
1. 从http://downloads.jmagick.org/6.3.9/下载windows下使用的jmagick-win-6.3.9-Q16.zip 。
解压后有两个文件jmagick.jar,jmagick.dll.
将jmagick.dll拷贝到系统目录system32下.
将jmagick.jar放在你的工程lib包下,或者环境变量能找着的地方。
2. 安装ImageMagick,官方网站:http://www.imagemagick.org/
3. 安装ImageMagick-6.3.9-0-Q16-windows-dll.exe
总结: 利用jmagick可以对图片做非常强大的处理,人是仅仅如果是校验图片格式以及用来清除图片中的恶意代码,有点杀鸡用牛九的感 觉,为了一个简单的图片校验便得我们的系统不仅要依赖第三方的包(jmagick.jar,jmagick.dll),而且要依赖 第三方的软件jmagick(因为不安装该软件,该方法所依赖的其它一些dll文件无法找到)。这样使得系统与第三方工具的耦合性太强,增加一个故障点。当然如果JDK本身能提供这种图片中恶意代码的清除功能最好不过了,但感觉有点不现实,因为清楚图片里的恶意代码有点类似杀毒软件的功能,纠结~~~,那位大侠有好的建议告诉下小弟,不甚感激。
注意:使用中容易出现的问题
1.若报如下异常
Exception in thread "imgtest" java.lang.UnsatisfiedLinkError: magick.Magick.init()V at magick.Magick.init(Native Method) at magick.Magick.<clinit>(Magick.java:40) at com.stress.util.MagickImages.main(MagickImages.java:381)
原因:往往是安装ImageMagick-6.3.9-0-Q16-windows-dll.exe时没有全选安装项造成
解决办法:在安装ImageMagick-6.3.9-0-Q16-windows-dll.exe时要全选安装项,截图如下
2.若报如下异常
java.lang.UnsatisfiedLinkError: no JMagick in java.library.path java.lang.ClassLoader.loadLibrary(ClassLoader.java:1517) java.lang.Runtime.loadLibrary0(Runtime.java:788) java.lang.System.loadLibrary(System.java:834) magick.Magick.(Magick.java:38)
原因:虽然你的jmagick.jar引入了,但是并没有被默认的类加载器加载进来。
解决办法:在类里加上静态块,用系统的类加载器指定下
static { System.setProperty("jmagick.systemclassloader", "no"); }
本程序测试环境: WindowsXP + JDK6.0 +Eclipse3.4.1+ImageMagick-6.3.9-0-Q16-windows
如果要在Linux环境下使用,请使用对应的Linux版本(本人未做测试)。
相关文章推荐
- java平台利用jsoup开发包,抓取优酷视频播放地址与图片地址等信息。
- java完整的利用itext7制作pdf、二维码图片插入pdf,并解析pdf中的二维码信息
- java平台利用jsoup开发包,抓取优酷视频播放地址与图片地址等信息。
- Java中利用URL类下载图片
- Java的Socket连接同时传输图片、文本等多种信息
- 利用Java代码实现图片的下载:
- 利用Java Soft Reference技术实现Android图片管理器
- java爬虫实战(1):抓取信息门户网站中的图片及其他文件并保存至本地
- Java中读取配置文件中的信息,并利用配置文件中的信息创建对象
- java利用微信企业号将位置信息推送到普通微信号并在微信中直接查看地图位置
- java利用POI向Excel(xls)写入图片,并对图片引用超链接
- 利用java实现简单图片的计数器
- Android(java)学习笔记139:在TextView组件中利用Html插入文字或图片
- java通过指定的URL获取图片信息(长宽)
- Java读取图片EXIF信息
- android 手机拍照上传项目的开发-----JAVA利用socket传图片给linux服务器
- java程序集成Tesseract-OCR识别图片信息
- C#和JAVA利用BASE64实现图片编码解码
- java图片动态添加水印(利用Graphics2D)
- java利用异或对图片进行加密