Adolf K Wiseman 2023-06-16 09:32 采纳率: 70%
浏览 75
已结题

java实现消息认证码签名与验证

java实现消息认证码签名与验证:想改进一下实验代码,要签名的对象为参数dataSetFolder路径中的每个文件的内容(每个文件都为英文电子邮件)、参数positionMap和一个随循环次数自增的参数fileCounter。每次循环都生成一个MAC签名,并验证签名内容的正确性,如正确则系统输出Accept,并把MAC签名写成一个txt格式的文件保存在本地且txt文件命名为自增的数字序号。

部分代码如图:

img

程序代码如下:

import client.utils.*;
import it.unisa.dia.gas.jpbc.Element;
import orestes.bloomfilter.CountingBloomFilter;
import orestes.bloomfilter.FilterBuilder;
import pojo.PrivateKey;
import pojo.PublicKey;
import server.Search;
import server.utils.HomoEncryption_Server;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;


public class Phrase_multi {
    public static void main(String[] args) {

        KeyGenUtils.genKey();
        Object[] key = KeyGenUtils.getKeyFromFile("key.data");

        PublicKey publicKey = (PublicKey) key[0];
        PrivateKey privateKey = (PrivateKey) key[1];


        CountingBloomFilter<Object> cbf = new FilterBuilder(1000000, 0.01)
                .buildCountingBloomFilter();
        ConcurrentHashMap<Integer, HashMap<String, ArrayList<Element>>> filesMaps = new ConcurrentHashMap<>();

        File dataSetFolder = new File("C:\\mypaperdataset\\enron\\version2\\10000");

        ExecutorService executorService = Executors.newCachedThreadPool();

        long s = System.currentTimeMillis();
        AtomicInteger fileCounter = new AtomicInteger(1);

        for (File file : dataSetFolder.listFiles()) {
//            if (count==7000) break;
//            count++;
            Integer node = NodeGen_Client.getNode();

            executorService.execute(()->{
                System.out.println("正在处理文件:" + file.getName() +"分配的节点:"+node);
                List<String> extracted = ExtractKeyword.extract_easy(file);//一个文件提取关键词耗费5ms
                IndexBuilding.buildCBF_Batch(extracted, node, cbf);
                HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
                filesMaps.put(node, positionMap);
            });
        }


        executorService.shutdown();


        try {
            while (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                System.out.println("线程池没有关闭");
//                System.out.println("isTerminated:" + executorService.isTerminated());
                ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
                System.out.println("剩余线程数: "+executor.getActiveCount());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long e = System.currentTimeMillis();

        System.out.println("线程池已经关闭");
        System.out.println("isTerminated:" + executorService.isTerminated());
        System.out.println("用时:"+(e-s)+"毫秒");

        // 搜索
        HomoEncryption_Client homo_client = new HomoEncryption_Client(privateKey, publicKey);
        Element elementX = homo_client.getElementX();
        Element elementY = homo_client.getElementY();


        while (true) {
            ArrayList<String> keywords = new ArrayList<>();
            while (true) {
                System.out.println("请输入:");
                Scanner input = new Scanner(System.in);
                String next = input.next();
                if (next.equals("0")) {
                    System.out.println("开始查询");
                    break;
                }
                keywords.add(MyHashUtils.md5(next));
            }


            HomoEncryption_Server homo_server = new HomoEncryption_Server(publicKey);



            long kk = System.nanoTime();
            List<Integer> search_result1 = Search.searchKeywords(keywords, cbf);
            long ll = System.nanoTime();
            System.out.println("普通查询完成,用时:"+(ll-kk)+"ns 查询到了"+search_result1.size()+"个文件");

            long pp = System.nanoTime();
            List<Integer> search_result2 = Search.searchKeywords_Phrase(keywords, cbf, filesMaps, homo_server, elementX, elementY);
            long jj = System.nanoTime();
            System.out.println("词组查询完成,用时:"+(jj-pp)+"ms 查询到了"+search_result2.size()+"个文件");




        }

    }
}


  • 写回答

3条回答 默认 最新

  • 「已注销」 2023-06-16 10:41
    关注

    以下是修改后的代码,根据你的要求添加了MAC签名的功能:

    import client.utils.*;
    import it.unisa.dia.gas.jpbc.Element;
    import orestes.bloomfilter.CountingBloomFilter;
    import orestes.bloomfilter.FilterBuilder;
    import pojo.PrivateKey;
    import pojo.PublicKey;
    import server.Search;
    import server.utils.HomoEncryption_Server;
    
    import javax.crypto.KeyGenerator;
    import javax.crypto.Mac;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.nio.file.Files;
    import java.nio.file.Path;
    import java.nio.file.StandardOpenOption;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Scanner;
    import java.util.concurrent.*;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class Phrase_multi {
        private static final String MAC_ALGORITHM = "HmacSHA256";
    
        public static void main(String[] args) {
            KeyGenUtils.genKey();
            Object[] key = KeyGenUtils.getKeyFromFile("key.data");
    
            PublicKey publicKey = (PublicKey) key[0];
            PrivateKey privateKey = (PrivateKey) key[1];
    
            CountingBloomFilter<Object> cbf = new FilterBuilder(1000000, 0.01)
                    .buildCountingBloomFilter();
            ConcurrentHashMap<Integer, HashMap<String, ArrayList<Element>>> filesMaps = new ConcurrentHashMap<>();
    
            File dataSetFolder = new File("C:\\mypaperdataset\\enron\\version2\\10000");
    
            ExecutorService executorService = Executors.newCachedThreadPool();
    
            long s = System.currentTimeMillis();
            AtomicInteger fileCounter = new AtomicInteger(1);
    
            for (File file : dataSetFolder.listFiles()) {
                Integer node = NodeGen_Client.getNode();
    
                executorService.execute(() -> {
                    System.out.println("正在处理文件:" + file.getName() + " 分配的节点:" + node);
                    List<String> extracted = ExtractKeyword.extract_easy(file);
                    IndexBuilding.buildCBF_Batch(extracted, node, cbf);
                    HashMap<String, ArrayList<Element>> positionMap = IndexBuilding.buildHashTable_exp(extracted, privateKey);
                    filesMaps.put(node, positionMap);
    
                    // Generate and verify MAC signature
                    String macSignature = generateMacSignature(file.getAbsolutePath(), positionMap, fileCounter.getAndIncrement());
                    if (verifyMacSignature(file.getAbsolutePath(), macSignature, positionMap, fileCounter.get() - 1)) {
                        System.out.println("Accept");
                        saveMacSignatureToFile(fileCounter.get() - 1, macSignature);
                    }
                });
            }
    
            executorService.shutdown();
    
            try {
                while (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    System.out.println("线程池没有关闭");
                    ThreadPoolExecutor executor = (ThreadPoolExecutor) executorService;
                    System.out.println("剩余线程数: " + executor.getActiveCount());
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            long e = System.currentTimeMillis();
    
            System.out.println("线程池已经关闭");
            System.out.println("isTerminated: " + executorService.isTerminated());
            System.out.println("用时: " + (e - s) + "毫秒");
    
            // 搜索
            HomoEncryption_Client homo_client = new HomoEncryption_Client(privateKey, publicKey);
            Element elementX = homo_client.getElementX();
            Element elementY = homo_client.getElementY();
    
            while (true) {
                ArrayList<String> keywords = new ArrayList<>();
                while (true) {
                    System.out.println("请输入:");
                    Scanner input = new Scanner(System.in);
                    String next = input.next();
                    if (next.equals("0")) {
                        System.out.println("开始查询");
                        break;
                    }
                    keywords.add(MyHashUtils.md5(next));
                }
    
                HomoEncryption_Server homo_server = new HomoEncryption_Server(publicKey);
    
                long kk = System.nanoTime();
                List<Integer> search_result1 = Search.searchKeywords(keywords, cbf);
                long ll = System.nanoTime();
                System.out.println("普通查询完成,用时:" + (ll - kk) + "ns 查询到了" + search_result1.size() + "个文件");
    
                long pp = System.nanoTime();
                List<Integer> search_result2 = Search.searchKeywords_Phrase(keywords, cbf, filesMaps, homo_server, elementX, elementY);
                long jj = System.nanoTime();
                System.out.println("词组查询完成,用时:" + (jj - pp) + "ms 查询到了" + search_result2.size() + "个文件");
            }
        }
    
        private static String generateMacSignature(String filePath, HashMap<String, ArrayList<Element>> positionMap, int fileCounter) {
            try {
                String data = readFileAsString(filePath);
                StringBuilder sb = new StringBuilder();
                sb.append(data);
    
                for (String keyword : positionMap.keySet()) {
                    sb.append(keyword);
                    for (Element element : positionMap.get(keyword)) {
                        sb.append(element);
                    }
                }
    
                String dataToSign = sb.toString();
    
                Mac mac = Mac.getInstance(MAC_ALGORITHM);
                SecretKey secretKey = generateMacSecretKey(fileCounter);
                mac.init(secretKey);
                byte[] signatureBytes = mac.doFinal(dataToSign.getBytes());
    
                return bytesToHexString(signatureBytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        private static boolean verifyMacSignature(String filePath, String macSignature, HashMap<String, ArrayList<Element>> positionMap, int fileCounter) {
            try {
                String data = readFileAsString(filePath);
                StringBuilder sb = new StringBuilder();
                sb.append(data);
    
                for (String keyword : positionMap.keySet()) {
                    sb.append(keyword);
                    for (Element element : positionMap.get(keyword)) {
                        sb.append(element);
                    }
                }
    
                String dataToVerify = sb.toString();
    
                Mac mac = Mac.getInstance(MAC_ALGORITHM);
                SecretKey secretKey = generateMacSecretKey(fileCounter);
                mac.init(secretKey);
                byte[] signatureBytes = mac.doFinal(dataToVerify.getBytes());
                String generatedSignature = bytesToHexString(signatureBytes);
    
                return macSignature.equals(generatedSignature);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return false;
        }
    
        private static SecretKey generateMacSecretKey(int fileCounter) {
            try {
                KeyGenerator keyGen = KeyGenerator.getInstance(MAC_ALGORITHM);
                keyGen.init(256); // Adjust key size as needed
                SecretKey secretKey = keyGen.generateKey();
                byte[] encodedKey = secretKey.getEncoded();
                Path keyFilePath = Path.of("mac_keys", fileCounter + ".txt");
                Files.createDirectories(keyFilePath.getParent());
                Files.write(keyFilePath, encodedKey, StandardOpenOption.CREATE);
    
                return secretKey;
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        private static String readFileAsString(String filePath) {
            try {
                return new String(Files.readAllBytes(Path.of(filePath)));
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        private static void saveMacSignatureToFile(int fileCounter, String macSignature) {
            try {
                String fileName = fileCounter + ".txt";
                FileWriter writer = new FileWriter(fileName);
                writer.write(macSignature);
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        private static String bytesToHexString(byte[] bytes) {
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        }
    }
    

    这个修改后的代码添加了以下功能:

    在循环处理每个文件时生成MAC签名,并验证签名的正确性。
    如果签名验证通过,将MAC签名保存到本地以自增的数字序号作为文件名的txt文件中。
    请确保在运行代码之前创建名为mac_keys的文件夹,用于保存生成的MAC密钥。

    注意:该代码只提供了基本的MAC签名功能,但并未包含数据完整性和安全性的全面保护。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月24日
  • 已采纳回答 6月16日
  • 创建了问题 6月16日

悬赏问题

  • ¥30 使用matlab将观测点聚合成多条目标轨迹
  • ¥15 Workbench中材料库无法更新,如何解决?
  • ¥20 如何推断此服务器配置
  • ¥15 关于github的项目怎么在pycharm上面运行
  • ¥15 内存地址视频流转RTMP
  • ¥100 有偿,谁有移远的EC200S固件和最新的Qflsh工具。
  • ¥15 有没有整苹果智能分拣线上图像数据
  • ¥20 有没有人会这个东西的
  • ¥15 cfx考虑调整“enforce system memory limit”参数的设置
  • ¥30 航迹分离,航迹增强,误差分析