java elgamal_ElGamal算法进行加密和解密的基本原理及实现

1、准备步骤

1)取大素数 p 和 g(g < p,g 最好是 p 的素根)

注解:若 g 是素数 p 的一个素根,则 g mod p, g^2 mod p , …, g^p-1 mod p 是 1 到 p - 1 的排列

2)随机选取一整数 x (2 <= x <= (p - 2),(p,g,x) 是私钥)

3)计算 y = g^x (mod p) ( (p,g,y) 是公钥)

2、加密过程

1)随机选取一整数 k (2 <= k <= (p - 2) 且 k 与 (p - 1) 互素)

2)计算 a = g^k mod p,b = m*y^k mod p(m 为要加密的明文)

3)密文 C = (a, b)

3、解密过程

1)m = b * a^(-x) mod p

注解:b * a^(-x) mod p Ξ m * y^k * g^(-xk) Ξ m * g^(xk) * g^(-xk) Ξ m

加密及解密的实现(Java):

importjava.util.ArrayList;public classMain {static ArrayList suArr = new ArrayList<>();public static voidmain(String[] args) {int max = 8096, p, g, x, y, k, a, b, buffer_data;char[] m = "abc".toCharArray(); //加密字符串"abc"

ArrayList C = new ArrayList<>(); //加密后的密文

intsize1;

suArr.add(2);//随机取一个小于2048的素数g

for (int i = 3; i <= 2048; i++) {if(isSuShu(i)) suArr.add(i);

}

size1=suArr.size();

g=getRanNum(size1);//随机取一个大素数p

for (int i = 2049; i <= max; i++) {if(isSuShu(i)) suArr.add(i);

}

p= getRanNum(suArr.size() -size1, size1);//x的范围是[2,p-2]

x = (int)(Math.random() * (p-3))+2;//k的范围是[2,p-2]且k与p-1互素

k = (int)(Math.random() * (p-3))+2;while (isHuZhi(k, p-1) != 1) {

k= (int)(Math.random() * (p-3))+2;

}//y = g^x mod p

y =myPow(g, x, p);//a = g^k mod p

a =myPow(g, k, p);

C.add(a);//特殊数据test//a = 1434;//g=1117;//k=2403;//p=6101;//x=714;//y=2271;//加密过程,即计算b = m*y^k mod p (m是明文)

for (charc : m) {

C.add((int)c*myPow(y, k, p) %p);

}

buffer_data=myPow(a, x, p);

buffer_data= exGcd(buffer_data, p)[0]; //求(a^x)^(-1) mod p等价于求a^(-x) mod p

if (buffer_data < 0) buffer_data +=p;//将解密后的明文输出

for (int i = 1; i < C.size(); i++) {

System.out.print((char)(C.get(i) * buffer_data %p));

}

}//判断一个数是否为素数

public static boolean isSuShu(intnum) {int max = (int) Math.sqrt(num);for (int i = 2; i <= max; i++) {if (num % i == 0)return false;

}return true;

}//在素数数组中随机取一个数

public static int getRanNum(intsize) {return suArr.get((int) (Math.random() *(size)));

}//在素数数组中的(left, arr.size())之间随机取一个数

public static int getRanNum(int size, intleft) {return suArr.get((int) (Math.random() * (size)) +left);

}//判断两个数是否互质

public static int isHuZhi(int a, intb) {return b == 0 ? a : isHuZhi(b, a %b);

}public static int myPow(int a, int b, intm) {int res = 1;

a%=m;while (b != 0) {if ((b & 1) == 1)

res= (res * a) %m;

a= (a * a) %m;

b>>= 1;

}returnres;

}public static int getSuGen(intp) {booleanisSuGen;for (intg : suArr) {

isSuGen= true;for (int i = 1; i < p; i++) {if (myPow(g, i, p) != i) isSuGen = false;

}if (isSuGen) returng;

}return 2; //如果在素数数组中找不到p的素根,则返回一个默认值

}//扩展欧几里得算法求a模b的逆元

public static int[] exGcd(int a, intb) {if (b == 0) {int[] arr = new int[]{1, 0};returnarr;

}else{int[] arr = exGcd(b, a %b);int x = arr[0];

arr[0] = arr[1];

arr[1] = x - (a / b) * arr[1];returnarr;

}

}

}/** 参考:

* 素根的定义:a是素数p 的一个素根,如果a mod p, a^2 mod p , …, a^p-1 mod p 是1到p-1的排列,称a是P的一个素根

* 加密时x和k的选取:https://blog.csdn.net/qq_34490018/article/details/79758620

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值