当前位置:   article > 正文

C4认证模拟考试题_csdn认证模拟考试

csdn认证模拟考试

任务概述
制作一个服务器端工具链。
任务说明
一、文件地址
https://csdn-task.oss-cn-hangzhou.aliyuncs.com/demo/studyNginx.zip

二、完成内容

  1. 使用Java程序将远程文件(zip压缩包)存储到本地指定的目录;
  2. 使用Java程序解压本地的zip文件;
  3. 使用AES加密算法单独加密每个文件,并覆盖原文件内容;

三、编码要求
每个文件的AES加密的key(32位)与偏移量都不同。

根据任务要求,远程下载压缩包,解压该压缩包。编写工具类Util,代码如下

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipFile {
    /**
     * 远程下载文件并读取返回p
     * @param filePath 文件网络地址 如http://www.baidu.com/1.txt
     * @return String
     */
    public static void DownAndReadFile(String filePath,String dirPath){
        String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir;
        //使用默认项目路径
        if(dirPath==null||dirPath.length()==0){
            dir=""+date;
        }else {
            //指定路径下载
            dir=dirPath;
        }
        File savePath = new File(dir);//创建新文件
        if (!savePath.exists()) {
            savePath.mkdir();
        }
        String[] urlname = filePath.split("/");
        int len = urlname.length-1;
        String uname = urlname[len];//获取文件名
        try {
            File file = new File(savePath+"//"+uname);//创建新文件
            if(file!=null && !file.exists()){
                file.createNewFile();
            }
            OutputStream oputstream = new FileOutputStream(file);
            URL url = new URL(filePath);
            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
            uc.setDoInput(true);//设置是否要从 URL 连接读取数据,默认为true
            uc.connect();
            InputStream iputstream = uc.getInputStream();
            System.out.println("file size is:"+uc.getContentLength());//打印文件长度
            byte[] buffer = new byte[4*1024];
            int byteRead = -1;
            while((byteRead=(iputstream.read(buffer)))!= -1){
                oputstream.write(buffer, 0, byteRead);
            }
            oputstream.flush();
            iputstream.close();
            oputstream.close();
        } catch (Exception e) {
            System.out.println("读取失败!");
            e.printStackTrace();
        }
    }

    /**
     * 解压缩包
     * @param zipFile 源压缩文件
     * @param destFile 压缩目录
     */
    public static void unzip(File zipFile,File destFile) throws IOException {
        if(zipFile == null)return;
        if (destFile.isFile())return;
        //destFile目录不存在,创建该目录
        if(!destFile.exists()){
            destFile.mkdirs();
        }
        ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
        ZipEntry zipEntry;
        while ((zipEntry=zipInputStream.getNextEntry())!=null){
            String name = zipEntry.getName();
            File file = new File(destFile,name);
            if(zipEntry.isDirectory()){
                file.mkdirs();
                continue;
            }
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len=zipInputStream.read(bytes))!=-1){
                fileOutputStream.write(bytes,0,len);
            }
            zipInputStream.closeEntry();
            fileOutputStream.close();
        }
        zipInputStream.close();

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

现在来使用AES加密算法单独加密每个文件,并覆盖原文件内容;创建AESCBCDemo类,代码如下

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Random;

public class AESCBCDemo {
    private static final int KEY_LENGTH_16 = 16;
    private static final int KEY_LENGTH_32 = 32;
    private static final String AES = "AES";
    private static final String AES_CBC_NO_PADDING = "AES/CBC/NoPadding";

    /**
     * 生成密钥(盐)
     * @param n 密钥长度
     * @return
     */
    public String getCKey(int n) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < n; i++) {
            String str = random.nextInt(2) % 2 == 0 ? "num" : "char";
            if ("char".equalsIgnoreCase(str)) { // 产生字母
                int nextInt = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (nextInt + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(str)) { // 产生数字
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }


    /**
     * 读取文件内容
     * @param fileName 文件路径
     * @return 文件全部内容
     */
    public String readContext(String fileName) throws Exception {
        String context="";
        if(fileName==null||fileName.length()==0){
            throw new Exception("文件路径不能为空!");
        }
        File file = new File(fileName);
        if (file.isDirectory()){
            throw new Exception("该文件是目录!");
        }
        BufferedReader reader = new BufferedReader(new FileReader(file));
        int length;
        char[] chars = new char[1024];
        while ((length=reader.read(chars))!=-1){
            context+=new String(chars,0,length);
        }
        reader.close();
        return context;
    }

    /**
     * 将内容写入到指定文件中
     * @param fileName 文件路径名
     * @param context 写入内容
     */
    public void write(String fileName,String context) throws Exception {
        File file = new File(fileName);
        if(!file.exists()){
            file.mkdirs();
        }
        if(file.isDirectory()) throw new Exception("该文件是目录!");
        BufferedWriter writer = new BufferedWriter(new FileWriter(file));
        writer.write(context);
        writer.close();

    }


    /**
     * AES ECB模式加密
     *
     * @param key     加密的秘钥
     * @param content 待加密内容
     * @param iv      偏移矢量
     * @return 加密后的内容
     * @throws Exception 异常信息
     */
    public String encryptByCBC(String key, String content, String iv) throws Exception {
        checkKey(key);
        checkIV(iv);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
        //AES/ECB/PKCS5Padding 格式为 "算法/模式/补码方式"
        Cipher cipher = Cipher.getInstance(AES_CBC_NO_PADDING);
        //加密内容长度必须要为blockSize的整数倍
        int blockSize = cipher.getBlockSize();
        int contentLength = content.getBytes().length;
        if (contentLength % blockSize != 0) {
            contentLength = contentLength + (blockSize - (contentLength % blockSize));
        }
        byte[] newBytes = new byte[contentLength];
        System.arraycopy(content.getBytes(), 0, newBytes, 0, content.getBytes().length);
        //偏移矢量
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        //设置加密模式,加密的key,偏移矢量
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        //加密
        byte[] bytes = cipher.doFinal(newBytes);
        //base64编码进行二次加密
        return new BASE64Encoder().encode(bytes);
    }

    /**
     * 检查key是否合法
     *
     * @param key {@link String}秘钥信息
     * @throws Exception 异常信息
     */
    private void checkKey(String key) throws Exception {
        if (key == null || key.length() != KEY_LENGTH_16 && key.length() != KEY_LENGTH_32) {
            throw new Exception("加密秘钥不正确");
        }
    }

    /**
     * 检查偏移矢量是否合法
     *
     * @param iv {@link String} 偏移矢量
     * @throws Exception 异常信息
     */
    private void checkIV(String iv) throws Exception {
        if (iv == null || iv.length() != KEY_LENGTH_16) {
            throw new Exception("偏移矢量不正确,必须为16位");
        }
    }

    /**
     * AES ECB模式解密
     *
     * @param key     加密的秘钥
     * @param encrypt 加密后的内容
     * @param iv      偏移矢量
     * @return 解密后的内容
     * @throws Exception 异常信息
     */
    public String decryptByCBC(String key, String encrypt, String iv) throws Exception {
        checkKey(key);
        checkIV(iv);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);
        //AES/ECB/PKCS5Padding 格式为 "算法/模式/补码方式"
        Cipher cipher = Cipher.getInstance(AES_CBC_NO_PADDING);
        //偏移矢量
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
        //设置为解密模式,解密的key,偏移矢量
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        //base64解密
        byte[] decodeBuffer = new BASE64Decoder().decodeBuffer(encrypt);
        //aes解密
        byte[] bytes = cipher.doFinal(decodeBuffer);
        return new String(bytes);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162

测试代码如下

import www.csdn.util.AESCBCDemo;
import www.csdn.util.ZipFile;

import java.io.File;

public class Main {
    public static void main(String[] args) throws Exception {
        /**
         * 1.使用`Java`程序将远程文件(zip压缩包)存储到本地指定的目录
         */
        String url="https://csdn-task.oss-cn-hangzhou.aliyuncs.com/demo/studyNginx.zip";
        ZipFile.DownAndReadFile(url,"downFile"); //dirPath 指定下载目录

        /**
         * 2.使用Java程序解压本地的zip文件
         */
        ZipFile.unzip(new File("downFile\\studyNginx.zip"),new File("./unzip"));

        //3.接下来加密4个文件
        AESCBCDemo aescbcDemo = new AESCBCDemo();
        //加密key长度需要为16位或32位
        String key = aescbcDemo.getCKey(32);
        //偏移矢量,必须为16位
        String iv = aescbcDemo.getCKey(16);

        //待加密内容
        String content = aescbcDemo.readContext("unzip\\001.txt");
        //加密
        String s = aescbcDemo.decryptByCBC(key, content, iv);
        //将加密后的内容写入原文件
        aescbcDemo.write("unzip\\001.txt",s);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/600828
推荐阅读
相关标签
  

闽ICP备14008679号