首页 > 其他分享 >实验二 电子公文传输系统安全 - 进展2

实验二 电子公文传输系统安全 - 进展2

时间:2024-05-26 19:10:59浏览次数:10  
标签:公文 String 传输 static new import byte public 系统安全

实验二 电子公文传输系统安全 - 进展2

任务详情

上周任务完成情况(代码链接,所写文档等)

SM3加盐

package cn.edu.nuc.article.util;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;

public class SM3SaltHelper {

    static {
        // 在类加载时添加BouncyCastleProvider
        Security.addProvider(new BouncyCastleProvider());
    }

    public static void main(String[] args) {
        // 原始数据
        byte[] data = "Hello, World!".getBytes();

        // 生成随机的盐值
        byte[] salt = generateSalt();

        // 将原始数据与盐值拼接
        byte[] dataWithSalt = concatBytes(data, salt);

        // 计算SM3哈希值
        byte[] hash = calculateHash(dataWithSalt);

        // 将盐值和哈希值转换为十六进制字符串
        String saltHex = bytesToHex(salt);
        String hashHex = bytesToHex(hash);

        System.out.println("Salt: " + saltHex);
        System.out.println("Hash: " + hashHex);
    }

    public static String encrypt(String paramStr, byte[] salt) {
        // 原始数据
        byte[] data = paramStr.getBytes();

        // 将原始数据与盐值拼接
        byte[] dataWithSalt = concatBytes(data, salt);

        // 计算SM3哈希值
        byte[] hash = calculateHash(dataWithSalt);

        // 将哈希值转换为十六进制字符串
        return bytesToHex(hash);
    }

    public static String entryptSM3Password(String plainPassword) {
        byte[] bytesSalt = generateSalt();
        String sm3Password = encrypt(plainPassword, bytesSalt);
        return bytesToHex(bytesSalt) + sm3Password;
    }

    public static byte[] generateSalt() {
        byte[] salt = new byte[16];  // 使用16字节的盐值
        new SecureRandom().nextBytes(salt);
        return salt;
    }

    private static byte[] concatBytes(byte[] a, byte[] b) {
        byte[] result = Arrays.copyOf(a, a.length + b.length);
        System.arraycopy(b, 0, result, a.length, b.length);
        return result;
    }

    private static byte[] calculateHash(byte[] input) {
        SM3Digest digest = new SM3Digest();
        digest.update(input, 0, input.length);
        byte[] result = new byte[digest.getDigestSize()];
        digest.doFinal(result, 0);
        return result;
    }

    public static String bytesToHex(byte[] bytes) {
        return Hex.toHexString(bytes);
    }

    public static byte[] HexTobytes(String hexStr) {
        return Hex.decode(hexStr);
    }
}

用户数据库定期更新

@Component
public static class PasswordUpdateTask {

    private final Logger logger = LoggerFactory.getLogger(PasswordUpdateTask.class);

    @Autowired
    private UserService userService;

    @Value("${user.default.password}") // 此处需注意不同用户应当根据其用户名等信息生成密码,并进行保存
    private String defaultPassword;

    @Scheduled(fixedRate = 10000) // 每10秒执行一次,单位为毫秒,可修改,实际工作中应当6个月为一个周期
    public void updatePasswords() {
        List<User> users = userService.findAllUsers();
        for (User user : users) {
            byte[] salt = SM3SaltHelper.generateSalt();
            String encryptedPassword = SM3SaltHelper.encrypt(defaultPassword, salt);
            user.setPassword(encryptedPassword);
            user.setSalt(SM3SaltHelper.bytesToHex(salt));
            boolean isUpdated = userService.updateUser1(user);
            if (isUpdated) {
                logger.info("用户 {} 密码成功更新。新密码: {}", user.getLoginname(), encryptedPassword);
            } else {
                logger.error("更新用户 {} 失败.", user.getLoginname());
            }
        }
    }
}

SM4

采用SM4对存储的公文进行加密处理,密钥随机生成,乱序存储在数据库中。其中SM4采用CBC模式,IV随机生成,跟随密文一起存储。解密的时候读取密文并分离密文和IV,然后解密。

package cn.edu.nuc.article.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.util.Arrays;
import java.util.Random;

public class SM4Tools {
    private static final String name = "SM4";                               // 算法名字
    private static final String transformation = "SM4/CBC/PKCS5Padding";    // 加密模式以及短块填充方式

    // private static final String Default_iv="0123456789abcdef";            // 加密使用的初始向量

    /**
     * 加载指定文件,对其进行加密,并将加密结果写入指定输出文件中
     * @param inputFile 要加密的输入文件路径
     * @param outputFile 加密后的输出文件路径
     * @param key 加密所需的密钥
     * @throws Exception 如果文件读取、加密或写入时出现错误,则抛出异常
     */
    public static void encodeFile(String inputFile, String outputFile, String key) throws Exception {
        byte[] inputBytes = Files.readAllBytes(Paths.get(inputFile));
        byte[] encodeByte = encode(inputBytes, key.getBytes(StandardCharsets.UTF_8));
        Files.write(Paths.get(outputFile), encodeByte);
        System.out.println("File encoded successfully.");
    }

    /**
     * 使用指定的加密算法和密钥对给定的字节数组进行加密
     * @param inputByte 要加密的字节数组
     * @param key 加密所需的密钥
     * @return 加密后的字节数组
     * @throws Exception 如果加密时发生错误,则抛出异常
     */
    public static byte[] encode(byte[] inputByte, byte[] key) throws Exception {
        Cipher c = Cipher.getInstance(transformation);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, name);

        // 生成随机IV
        byte[] iv = new byte[16];
        SecureRandom random = new SecureRandom();
        random.nextBytes(iv);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        c.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);

        // 加密数据
        byte[] encryptedData = c.doFinal(inputByte);

        // 将IV和密文一起返回
        byte[] combined = new byte[iv.length + encryptedData.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encryptedData, 0, combined, iv.length, encryptedData.length);

        return combined;
    }

    public static void decodeFile(String inputFilePath, String outputFilePath, String key) throws Exception {
        byte[] inputBytes = Files.readAllBytes(Paths.get(inputFilePath));
        byte[] decodeBytes = decode(inputBytes, key.getBytes(StandardCharsets.UTF_8));
        Files.write(Paths.get(outputFilePath), decodeBytes);
        System.out.println("File decode successfully.");
    }

    public static byte[] decode(byte[] inputBytes, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance(transformation);
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, name);

        // 从输入数据中提取IV和密文
        byte[] iv = Arrays.copyOfRange(inputBytes, 0, 16);
        byte[] encryptedData = Arrays.copyOfRange(inputBytes, 16, inputBytes.length);
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        return cipher.doFinal(encryptedData);
    }

    public static String generateRandomString(int length) {
        Random random = new Random();
        StringBuffer string = new StringBuffer();

        for (int i = 0; i < length; i++) {
            int randomChar = random.nextInt(91);
            if (randomChar >= 48 && randomChar <= 57 ||
                    randomChar >= 65 && randomChar <= 90 ||
                    randomChar >= 97 && randomChar <= 122) {
                string.append((char) randomChar);
            } else {
                i--;
            }
        }

        return string.toString();
    }

    public static void main(String[] args) throws Exception {
        Security.addProvider(new BouncyCastleProvider());
        String inputFile = "D:\\data\\test01.docx";
        String enFile = "D:\\data\\test01Encode.docx";
        String deFile = "D:\\

data\\test01Decode.docx";
        String key = generateRandomString(16);
        System.out.println(key);
        encodeFile(inputFile, enFile, key);
        decodeFile(enFile, deFile, key);
    }
}

上传后的公文加密存储

本周计划

  • 等待验收
  • 继续对密钥算法进行完善

标签:公文,String,传输,static,new,import,byte,public,系统安全
From: https://www.cnblogs.com/zsy1748774883/p/18214154

相关文章

  • 电子公文传输系统安全-进展2
    -上周任务完成情况完成对于登陆过程中的加盐操作: SM3加盐算法存储密码的实现类 加盐思路:1.通过UUID拿到盐值2.拼接:盐值+明文密码3.对2中数据进行SM3哈希4.拼接:盐值+”^“+3中的哈希值 明文密码走完上述流程后后存入数据库 登录验证:1.根据用户名在数据库里得到......
  • 电子公文传输系统-进展二
    上周任务完成情况改进密码存储方案,解决用户密码存储未加密问题重新商讨密钥存储方案,解决用户公私钥对存在未加密问题修改css文件,美化前端页面完善后端数据库功能实现修改SM3哈希算法和加盐技术来存储密码sm3_hash_with_salt函数defsm3_hash_with_salt(password,salt):......
  • 《计算机网络微课堂》2-2 物理层下面的传输媒体
    请大家注意,传输媒体不属于计算机网络体系结构的任何一层,如果非要将它添加到体系结构中,‍‍那只能将其放在物理层之下。传输媒体可分为两类:一类是导引型传输媒体,‍‍另一类是非导引型传输媒体。在导引型传输媒体中,电磁波被导引沿着固体媒体传播,‍‍常见的导引型传输媒体有同轴电......
  • 《计算机网络微课堂》2-3 传输方式
    本节课我们介绍几种传输方式:串行传输和并行传输同步传输和异步传输单工,半双工‍‍以及全双工通信​​串行我们首先来看串行传输和并行传输,串行传输是指‍‍数据是一个比特依次发送的,因此在发送端和接收端之间‍‍只需要一条数据传输线路即可。‍并行传输是指‍‍一次发送......
  • 实验二 电子公文传输系统安全-进展2
    实验二电子公文传输系统安全-进展2上周任务完成情况(代码链接,所写文档等)本周计划上周任务完成情况使用国密算法SM2,在注册账号时为用户生成公私钥对try{//设置SM2曲线参数ECGenParameterSpececGenSpec=newECGenParameterSpec("sm2p256v1");KeyPair......
  • 实验二 电子传输系统安全-进展2
    实验二电子传输系统安全-进展2上周任务学习gmssl相关知识学习加密相关知识,选择合适的国密算法部署安装gmssl中的算法库将相关算法库接口利用maven导入系统进行调用调试运行更改加密算法后的系统·学习密码项目标准进行系统优化上周任务完成情况学号姓名任务完成......
  • IceRPC之多路复用传输>快乐的RPC
    作者引言很高兴啊,我们来到了IceRPC之多路复用传输>快乐的RPC,基础引导,打好基础,才能让自已不在迷茫,快乐的畅游世界。icerpc和多路复用传输了解icerpc协议和多路复用传输icerpc协议当创建到服务器地址icerpc://hello.zeroc.com的客户端连接时,指示IceRPC建立使用ic......
  • 实验二 电子传输系统安全-进展2
    任务详情上周任务完成情况(代码链接,所写文档等)本周计划上周任务完成情况采用sm4对存储的公文进行加密处理,密钥随机生成,乱序存储在数据库中。其中sm4采用cbc模式,iv固定,跟随密文一起存储。解密的时候读取密文并分离密文和iv,然后解密。SM3加盐存储代码packagecn.edu.nuc.a......
  • 探索SPI单线传输模式:时钟线与数据传输的简化之道
    探索SPI单线传输模式:时钟线与数据传输的简化之道在当今的嵌入式系统和微控制器通信中,串行外设接口(SPI)因其高速、全双工和同步的特点而广受欢迎。然而,随着设备尺寸和复杂性的不断减少,对SPI通信的简化需求也日益增加。在这种背景下,SPI的单线传输模式成为了一个备受关注的解决方案。......
  • 实验二 电子公文传输系统安全-进展2
    实验二电子公文传输系统安全-进展2任务详情上周任务完成情况(代码链接,所写文档等)本周计划上周任务完成情况SM3加盐packagecn.edu.nuc.article.util;importorg.bouncycastle.crypto.digests.SM3Digest;importorg.bouncycastle.jce.provider.BouncyCastleProvider;......