JAVA实现ECC加密 eclipse

ECC加密

一、实验目的
通过使用JPBC库调用ECC椭圆曲线加解密算法,能够编写简单的实验代码进行正确的ECC加密和解密。
二、 实验要求

  1. 熟悉ECC椭圆曲线加解密算法。
  2. 了解如何使用Java简单实现ECC椭圆曲线加密算法。
  3. 掌握ECC椭圆曲线加密算法的简单代码实验。
  4. 熟悉JPBC密码学库。
    三、开发环境
    JDK1.8,Java相关开发环境(本实验以Windows平台为例)
    四、实验内容
    需要导入相关的jpbc包
    【1-1】ECC椭圆曲线加密实验
    1、 给定一个String类型的参数,使用如下的函数进行系统初始化:
public static Pairing initPairing(String parameter) {
    System.out.println("系统正在导入椭圆曲线的相关参数……");
    //读入参数
    Pairing pairing = PairingFactory.getPairing(parameter);
    System.out.println("系统已经导入完毕");
    return pairing;
}
public static Field initG_1(Pairing pairing) {
    System.out.println("系统正在产生椭圆曲线……");
    //读入参数
    Field G1 = pairing.getG1();

    System.out.println("系统已经产生椭圆曲线");
    return G1;
}
public static Element initG(Field G1) {
    System.out.println("系统正在挑选生成元点G……");
    //挑选生成元点G
    Element G = G1.newRandomElement().getImmutable();
    System.out.println("系统已经挑选好生成元点G");
    return G;
}

public static Element initP_t(Field G1) {
    System.out.println("系统正在挑选随机点P_t……");
    //挑选随机点P_t
    Element P_t = G1.newRandomElement().getImmutable();
    System.out.println("系统已经挑选好随机点P_t");
    return P_t;
}

2、 给定String类型的密钥和待加密消息,使用如下的函数进行初始化密钥:

//生成公私钥对
public static void KeyGenerator(Element G,Field G_1) throws Exception {
    //随机选择一个整数n_b,作为私钥
    Random random = new Random();
    BigInteger n_b = new BigInteger(160, 160,random);//大整数作为私钥1
    //构造公钥P_b
    Element P_b = G.duplicate().mul(n_b);
    byte[] b = P_b.toCanonicalRepresentation();
    System.out.println("\n");
    //把公钥和私钥分别存储在publicKey.key和privateKey.key文件里
    String path = new File("").getCanonicalPath();
    out(path + "\\privateKey.key", n_b.toString());
    out(path + "\\publicKey.key",
    Base64.getEncoder().encodeToString(P_b.toCanonicalRepresentation())
    + ",,,,,," +     Base64.getEncoder().encodeToString(G.toCanonicalRepresentation()));
    System.out.println("你的私钥存放在:" + path + "\\privateKey.key");
    System.out.println("你的公钥存放在:" + path + "\\publicKey.key");
}

3、 使用如下的函数实现加密操作:

//加密算法
public static String encrypt(Element P_b, String data, int k, Element P_t, Element G){
    try {
        byte[] datasource=data.getBytes("utf8");
        String CArray = "A";
        //计算P_1
        Element P_1 = G.duplicate().getImmutable().mul(k);
        System.out.println("加密过程中计算出的P_1:"+ P_1);
        //计算P_2
        Element P_2 = P_b.duplicate().getImmutable().mul(k);
        System.out.println("加密过程中计算出的P_2:"+ P_2);
        //计算P_end
        Element P_end = P_t.add(P_2);
        System.out.println("加密过程中计算出的P_end:"+ P_end);
        //计算密文C
        String[] p_txy = P_t.toString().split(",");
        BigInteger p_tx = new BigInteger(p_txy[0]);
        BigInteger p_ty = new BigInteger(p_txy[1]);
        for(int i=0;i<datasource.length;i++)
        {
            BigInteger M = new BigInteger(datasource[i]+"");
            BigInteger C_mid = M.multiply(p_tx).add(p_ty);
            CArray = CArray +","+C_mid.toString();
        }
        CArray = CArray + ",,"+
        Base64.getEncoder().encodeToString(P_1.toCanonicalRepresentation())+",,"+ 
        Base64.getEncoder().encodeToString(P_end.toCanonicalRepresentation());
        return Base64.getEncoder().encodeToString(CArray.getBytes());
    }
    catch(Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

4、 给定String类型的密钥和待解密的密文,使用如下的函数进行解密:

public static String decrypt(BigInteger Privatekey, String data, Field G_1,Element G) {
try {
        String ciphertext= new String(Base64.getDecoder().decode(data),"utf8");
        //分解密文
        String[] CS=ciphertext.split(",,");
        String m = "";
        //取出P_t+kP_b
        Element P_end = G_1.newElementFromBytes(Base64.getDecoder().decode(CS[2]));
        //取出P_1
        Element P_1 = G_1.newElementFromBytes(Base64.getDecoder().decode(CS[1]));
        //计算P_t
        Element P_t = P_end.getImmutable().sub(P_1.getImmutable().mul(Privatekey));
        System.out.println("解密过程中计算出的P_t:"+ P_t);
        //计算明文M
        String[] p_txy = P_t.toString().split(",");
        BigInteger p_tx = new BigInteger(p_txy[0]);
        BigInteger p_ty = new BigInteger(p_txy[1]);
        //取出密文c
        String[] Plaintext = CS[0].split(",");
        for(int i=1;i<Plaintext.length;i++){
            BigInteger C = new BigInteger(Plaintext[i]);
            BigInteger M_mid = C.subtract(p_ty).divide(p_tx);
            m = m+new String(M_mid.toByteArray(),"GBK");;
        }
        return m;
    }
    catch(Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

全部代码

import it.unisa.dia.gas.jpbc.*;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class ECC {
    public static Pairing initPairing(String parameter) {
        System.out.println("系统正在导入椭圆曲线的相关参数……");
        //读入参数
        Pairing pairing = PairingFactory.getPairing(parameter);
        System.out.println("系统已经导入完毕");
        return pairing;
    }
    public static Field initG_1(Pairing pairing) {
        System.out.println("系统正在产生椭圆曲线……");
        //读入参数
        Field G1 = pairing.getG1();
        System.out.println("系统已经产生椭圆曲线");
        return G1;
    }
    public static Element initG(Field G1) {
        System.out.println("系统正在挑选生成元点G……");
        //挑选生成元点G
        Element G = G1.newRandomElement().getImmutable();
        System.out.println("系统已经挑选好生成元点G");
        return G;
    }

    public static Element initP_t(Field G1) {
        System.out.println("系统正在挑选随机点P_t……");
        //挑选随机点P_t
        Element P_t = G1.newRandomElement().getImmutable();
        System.out.println("系统已经挑选好随机点P_t");
        return P_t;
    }

    //生成公私钥对
    public static void KeyGenerator(Element G,Field G_1) throws Exception {
        //随机选择一个整数n_b,作为私钥
        Random random = new Random();
        BigInteger n_b = new BigInteger(160, 160,random);//大整数作为私钥1
        //构造公钥P_b
        Element P_b = G.duplicate().mul(n_b);
        byte[] b = P_b.toCanonicalRepresentation();
        System.out.println("\n");
        //把公钥和私钥分别存储在publicKey.key和privateKey.key文件里
        String path = new File("").getCanonicalPath();
        out(path + "\\privateKey.key", n_b.toString());
        out(path + "\\publicKey.key", 
        Base64.getEncoder().encodeToString(P_b.toCanonicalRepresentation()) + ",,,,,," + 
        Base64.getEncoder().encodeToString(G.toCanonicalRepresentation()));
        System.out.println("你的私钥存放在:" + path + "\\privateKey.key");
        System.out.println("你的公钥存放在:" + path + "\\publicKey.key");
    }

    //加密算法
    public static String encrypt(Element P_b, String data, BigInteger k, Element P_t, Element G){
      try {
            byte[] datasource=data.getBytes("utf8");
            String CArray = "A";
            //计算P_1
            Element P_1 = G.duplicate().getImmutable().mul(k);
            System.out.println("加密过程中计算出的P_1:"+ P_1);
            //计算P_2
            Element P_2 = P_b.duplicate().getImmutable().mul(k);
            System.out.println("加密过程中计算出的P_2:"+ P_2);
            //计算P_end
            Element P_end = P_t.add(P_2);
            System.out.println("加密过程中计算出的P_end:"+ P_end);
            //计算密文C
            String[] p_txy = P_t.toString().split(",");
            BigInteger p_tx = new BigInteger(p_txy[0]);
            BigInteger p_ty = new BigInteger(p_txy[1]);
            for(int i=0;i<datasource.length;i++)
            {
                BigInteger M = new BigInteger(datasource[i]+"");
                BigInteger C_mid = M.multiply(p_tx).add(p_ty);
                CArray = CArray +","+C_mid.toString();
            }
            CArray = CArray + ",,"+
            Base64.getEncoder().encodeToString(P_1.toCanonicalRepresentation())+",,"+ 
            Base64.getEncoder().encodeToString(P_end.toCanonicalRepresentation());
            return Base64.getEncoder().encodeToString(CArray.getBytes());
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    public static String decrypt(BigInteger Privatekey, String data, Field G_1,Element G) {
      try {
            String ciphertext= new String(Base64.getDecoder().decode(data),"utf8");
            //分解密文
            String[] CS=ciphertext.split(",,");
            String m = "";
            //取出P_t+kP_b
            Element P_end = G_1.newElementFromBytes(Base64.getDecoder().decode(CS[2]));
            //取出P_1
            Element P_1 = G_1.newElementFromBytes(Base64.getDecoder().decode(CS[1]));
            //计算P_t
            Element P_t = P_end.getImmutable().sub(P_1.getImmutable().mul(Privatekey));
            System.out.println("解密过程中计算出的P_t:"+ P_t);
            //计算明文M
            String[] p_txy = P_t.toString().split(",");
            BigInteger p_tx = new BigInteger(p_txy[0]);
            BigInteger p_ty = new BigInteger(p_txy[1]);
            //取出密文c
            String[] Plaintext = CS[0].split(",");
            for(int i=1;i<Plaintext.length;i++){
                BigInteger C = new BigInteger(Plaintext[i]);
                BigInteger M_mid = C.subtract(p_ty).divide(p_tx);
                m = m+new String(M_mid.toByteArray(),"GBK");;
            }
            return m;
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    //封装输出流
    public static void out(String path, String val) {
       try {
            val = Base64.getEncoder().encodeToString(val.getBytes("utf8"));
            FileWriter fw = new FileWriter(path);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter outs = new PrintWriter(bw);
            outs.println(val);
            outs.flush();
            outs.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    //从文件中读公钥
    public static Element readPk(String path, Field G_1){
        Element sk = null;
        try {
            File f=new File(path);
            FileReader fr=new FileReader(f);
            BufferedReader br=new BufferedReader(fr);
            String line=null;
            StringBuffer sb=new StringBuffer();
            while((line=br.readLine())!=null) {
                byte[] b = Base64.getDecoder().decode(line);
                String[] key = new String(b).split(",,,,,,");
                byte [] a = Base64.getDecoder().decode(key[0]);
                System.out.println("\n");
                if(key.length == 2){
                    sk = G_1.newElementFromBytes(a);
                } else{
                    throw new Exception("文件错误");
                }
            }

            br.close();
            return sk;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        return sk;
    }

//从文件中读取私钥
public static BigInteger readSk(String path, Field G_1){
        BigInteger sk = null;
        try {
            File f=new File(path);
            FileReader fr=new FileReader(f);
            BufferedReader br=new BufferedReader(fr);
            String line=null;

            StringBuffer sb=new StringBuffer();
            while((line=br.readLine())!=null) {
                byte[] b = Base64.getDecoder().decode(line);
                String[] key = new String(b).split(",,,,,,");
                if (key.length == 1) {
                    sk = new BigInteger(key[0]);
                }else{
                    throw new Exception("文件错误");
                }
            }
            br.close();
            return sk;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        return sk;
    }

public static void main(String[] args) {
     try {
            BigInteger k = new BigInteger(10, new Random());
            //执行系统初始化
            Pairing pairing = initPairing("C:\\Users\\89763\\Desktop\\a.properties");
            Field G_1 = initG_1(pairing);
            Element G = initG(G_1);
            Element P_t = initP_t(G_1);
            //构造公私钥
            KeyGenerator(G,G_1);
            Scanner sc = new Scanner(System.in);
            String str = "";
            sc.useDelimiter("\n");
            System.out.print("\n"+"请输入公钥地址按回车结束:");
            if (sc.hasNext()) {
                str = sc.next();
            }
            //获取公钥
            Element publicKey = readPk(str.substring(0, str.length()-1), G_1);
            System.out.print("\n"+"请输入需要加密的文字按回车结束:");
            if (sc.hasNext()) {
                str = sc.next();
            }
            //加密明文
            String c = encrypt(publicKey, str, k, P_t, G);
            System.out.println("\n"+"加密结果:" + c+"\n");
            System.out.print("请输入私钥地址按回车可对密文数据进行解密:");
            if (sc.hasNext()) {
                str = sc.next();
            }
            //获得私钥
            BigInteger privateKey = readSk(str.substring(0, str.length()-1 ), G_1);
            //解密密文
            String m = decrypt(privateKey, c, G_1, G);
            System.out.println("\n"+"解密明文:" + m+"\n");
            sc.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

注:相关jpbc导入方法
在这里插入图片描述
在这里插入图片描述
相关JPBC文件已上传,自行解压,
其中

Pairing pairing = initPairing("C:\\Users\\89763\\Desktop\\a.properties");

中为你保存a.properties的文件位置

猜你喜欢

转载自blog.csdn.net/qq_45056216/article/details/106589970