日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java 图片格式校验_(转载)Java对上传的图片进行格式校验以及安全性校验

發布時間:2024/3/13 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 图片格式校验_(转载)Java对上传的图片进行格式校验以及安全性校验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

前言

判斷上傳的是否是圖片

通過后綴名進行判斷

通過文件頭

通過ImageIO判斷

圖片文件的安全檢查處理

給圖片加水印

前言

在web開發中,肯定會有一些圖片上傳的功能,如果僅僅是通過頁面端進行控制是遠遠不夠的,完全可以直接調用后臺的接口,將一些病毒文件上傳到服務器,如果不進行校驗,后果不堪設想!

判斷上傳的是否是圖片

通過后綴名進行判斷

這層校驗應該說是最基本的校驗了,看下文件的后綴名是否符合要求的格式。

String fileType= "";

int i = fileName.lastIndexOf('.');

if (i > 0) {

fileType= fileName.substring(i+1);

}

//...

if("jpg".equals(fileType) || "png".equals(fileType) ....){

//your code

}

這種非常的不靠譜,完全可以修改文件的后綴名繞過檢驗。

通過文件頭

根據文件的前面幾個字節,即常說的魔術數字進行判斷,不同文件類型的開頭幾個字節

// 獲得文件頭部字符串

public static String bytesToHexString(byte[] src) {

StringBuilder stringBuilder = new StringBuilder();

if (src == null || src.length <= 0) {

return null;

}

for (int i = 0; i < src.length; i++) {

int v = src[i] & 0xFF;

String hv = Integer.toHexString(v);

if (hv.length() < 2) {

stringBuilder.append(0);

}

stringBuilder.append(hv);

}

return stringBuilder.toString();

}

不同文件的頭魔術數字

private static void getAllFileType()

{

FILE_TYPE_MAP.put("jpg", "FFD8FF"); //JPEG

FILE_TYPE_MAP.put("png", "89504E47"); //PNG

FILE_TYPE_MAP.put("gif", "47494638"); //GIF

FILE_TYPE_MAP.put("tif", "49492A00"); //TIFF

FILE_TYPE_MAP.put("bmp", "424D"); //Windows Bitmap

FILE_TYPE_MAP.put("dwg", "41433130"); //CAD

FILE_TYPE_MAP.put("html", "68746D6C3E"); //HTML

FILE_TYPE_MAP.put("rtf", "7B5C727466"); //Rich Text Format

FILE_TYPE_MAP.put("xml", "3C3F786D6C");

FILE_TYPE_MAP.put("zip", "504B0304");

FILE_TYPE_MAP.put("rar", "52617221");

FILE_TYPE_MAP.put("psd", "38425053"); //PhotoShop

FILE_TYPE_MAP.put("eml", "44656C69766572792D646174653A"); //Email [thorough only]

FILE_TYPE_MAP.put("dbx", "CFAD12FEC5FD746F"); //Outlook Express

FILE_TYPE_MAP.put("pst", "2142444E"); //Outlook

FILE_TYPE_MAP.put("office", "D0CF11E0"); //office類型,包括doc、xls和ppt

FILE_TYPE_MAP.put("mdb", "000100005374616E64617264204A"); //MS Access

FILE_TYPE_MAP.put("wpd", "FF575043"); //WordPerfect

FILE_TYPE_MAP.put("eps", "252150532D41646F6265");

FILE_TYPE_MAP.put("ps", "252150532D41646F6265");

FILE_TYPE_MAP.put("pdf", "255044462D312E"); //Adobe Acrobat

FILE_TYPE_MAP.put("qdf", "AC9EBD8F"); //Quicken

FILE_TYPE_MAP.put("pwl", "E3828596"); //Windows Password

FILE_TYPE_MAP.put("wav", "57415645"); //Wave

FILE_TYPE_MAP.put("avi", "41564920");

FILE_TYPE_MAP.put("ram", "2E7261FD"); //Real Audio

FILE_TYPE_MAP.put("rm", "2E524D46"); //Real Media

FILE_TYPE_MAP.put("mpg", "000001BA"); //

FILE_TYPE_MAP.put("mov", "6D6F6F76"); //Quicktime

FILE_TYPE_MAP.put("asf", "3026B2758E66CF11"); //Windows Media

FILE_TYPE_MAP.put("mid", "4D546864"); //MIDI (mid)

}

此時有人把一個可執行的PHP文件的擴展名修改為PNG,然后再在前面補上”89 50″兩個字節,就又繞開了這種驗證方式,這種也是不靠譜的!

通過ImageIO判斷

通過ImageReader來解碼這個file并返回一個BufferedImage對象,如果找不到合適的ImageReader則會返回null,我們可以認為這不是圖片文件。

另外如果能夠正常的獲取到一張圖片的寬高屬性,那肯定這是一張圖片,因為非圖片文件我們是獲取不到它的寬高屬性的。

/**

* 通過讀取文件并獲取其width及height的方式,來判斷判斷當前文件是否圖片,這是一種非常簡單的方式。

* @param imageFile

* @return

*/

public static boolean isImage(File imageFile) {

if (!imageFile.exists()) {

return false;

}

Image img = null;

try {

img = ImageIO.read(imageFile);

if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {

return false;

}

return true;

} catch (Exception e) {

return false;

} finally {

img = null;

}

}

這種方式較安全!

圖片文件的安全檢查處理

通過上面的方法,確認上傳的文件是圖片了,但是如果在可以正常打開的圖片里面加入非法代碼或者病毒,那就非常危險了。那么怎么可以預防這種情況,既能夠正常打開,又能獲取圖片的寬高等屬性,可以對圖片進行重寫,新生成的圖片不會有這種惡意代碼了。

給圖片加水印

/**

* 給圖片添加水印、可設置水印圖片旋轉角度

* @param iconPath 水印圖片路徑

* @param srcImgPath 源圖片路徑

* @param targerPath 目標圖片路徑

* @param degree 水印圖片旋轉角度

* @param width 寬度(與左相比)

* @param height 高度(與頂相比)

* @param clarity 透明度(小于1的數)越接近0越透明

*/

public static void waterMarkImageByIcon(String iconPath, String srcImgPath,

String targerPath, Integer degree, Integer width, Integer height,

float clarity) {

OutputStream os = null;

try {

Image srcImg = ImageIO.read(new File(srcImgPath));

System.out.println("width:" + srcImg.getWidth(null));

System.out.println("height:" + srcImg.getHeight(null));

BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),

srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

// 得到畫筆對象

Graphics2D g = buffImg.createGraphics();

// 設置對線段的鋸齒狀邊緣處理

g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,

RenderingHints.VALUE_INTERPOLATION_BILINEAR);

g.drawImage(

srcImg.getScaledInstance(srcImg.getWidth(null),

srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,

null);

if (null != degree) {

// 設置水印旋轉

g.rotate(Math.toRadians(degree),

(double) buffImg.getWidth() / 2,

(double) buffImg.getHeight() / 2);

}

// 水印圖象的路徑 水印一般為gif或者png的,這樣可設置透明度

ImageIcon imgIcon = new ImageIcon(iconPath);

// 得到Image對象。

Image img = imgIcon.getImage();

float alpha = clarity; // 透明度

g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,

alpha));

// 表示水印圖片的位置

g.drawImage(img, width, height, null);

g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));

g.dispose();

os = new FileOutputStream(targerPath);

// 生成圖片

ImageIO.write(buffImg, "JPG", os);

System.out.println("添加水印圖片完成!");

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (null != os)

os.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

/**

* 給圖片添加水印、可設置水印圖片旋轉角度

* @param logoText 水印文字

* @param srcImgPath 源圖片路徑

* @param targerPath 目標圖片路徑

* @param degree 水印圖片旋轉角度

* @param width 寬度(與左相比)

* @param height 高度(與頂相比)

* @param clarity 透明度(小于1的數)越接近0越透明

*/

public static void waterMarkByText(String logoText, String srcImgPath,

String targerPath, Integer degree, Integer width, Integer height,

Float clarity) {

// 主圖片的路徑

InputStream is = null;

OutputStream os = null;

try {

Image srcImg = ImageIO.read(new File(srcImgPath));

BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),

srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

// 得到畫筆對象

// Graphics g= buffImg.getGraphics();

Graphics2D g = buffImg.createGraphics();

// 設置對線段的鋸齒狀邊緣處理

g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,

RenderingHints.VALUE_INTERPOLATION_BILINEAR);

g.drawImage(

srcImg.getScaledInstance(srcImg.getWidth(null),

srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,

null);

if (null != degree) {

// 設置水印旋轉

g.rotate(Math.toRadians(degree),

(double) buffImg.getWidth() / 2,

(double) buffImg.getHeight() / 2);

}

// 設置顏色

g.setColor(Color.red);

// 設置 Font

g.setFont(new Font("宋體", Font.BOLD, 30));

float alpha = clarity;

g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,

alpha));

// 第一參數->設置的內容,后面兩個參數->文字在圖片上的坐標位置(x,y) .

g.drawString(logoText, width, height);

g.dispose();

os = new FileOutputStream(targerPath);

// 生成圖片

ImageIO.write(buffImg, "JPG", os);

System.out.println("添加水印文字完成!");

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

if (null != is)

is.close();

} catch (Exception e) {

e.printStackTrace();

}

try {

if (null != os)

os.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) throws IOException {

waterMarkImageByIcon("d:/shuiyin.png", imagePath, "d:/result.png", 10, 100, 100, 0F);

waterMarkByText("logo", imagePath, "d:/result1.png", 3, 100, 100, 0F);

}

上面加水印,你可以將透明度調為0,乍一看跟原圖一樣,其實不是上面的那張原圖了。

效果展示

原圖:

image.png

加水印圖片(水印透明度0.5):

image.png

加水印文字(水印透明度0.5):

image.png

————————————————

版權聲明:本文為CSDN博主「太陽守護者Sunner」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/qq_26788593/article/details/85062168

總結

以上是生活随笔為你收集整理的java 图片格式校验_(转载)Java对上传的图片进行格式校验以及安全性校验的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。