算法原理
代码
package com.example.secureserver.encryption;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
public class ElGamal {
static BigInteger p;
static BigInteger q;
static BigInteger g;
public HashMap<String, String> generateKeyPair(int keySize) {
initP(keySize);
SecureRandom secureRandom = new SecureRandom();
BigInteger privateKey = new BigInteger(secureRandom.nextInt(keySize - 1), secureRandom);
BigInteger publicKey = g.modPow(privateKey, p);
HashMap<String, String> keyPair = new HashMap<>();
keyPair.put("privateKey", privateKey.toString());
keyPair.put("publicKey", publicKey.toString());
return keyPair;
}
public HashMap<String, String> encryElGamal(BigInteger m, BigInteger g, BigInteger p, BigInteger publicKey) {
SecureRandom secureRandom = new SecureRandom();
BigInteger k = new BigInteger(secureRandom.nextInt(p.bitLength() - 1), secureRandom);
BigInteger K = publicKey.modPow(k, p);
System.out.println("K:" + K.toString());
BigInteger c1 = g.modPow(k, p);
BigInteger c2 = m.multiply(K).mod(p);
HashMap<String, String> encMessage = new HashMap<>();
encMessage.put("c1", c1.toString());
encMessage.put("c2", c2.toString());
return encMessage;
}
public BigInteger decryElGamal(BigInteger g, BigInteger p, BigInteger privateKey, HashMap<String, String> encMessage) {
BigInteger c1 = new BigInteger(encMessage.get("c1"));
BigInteger c2 = new BigInteger(encMessage.get("c2"));
BigInteger K = c1.modPow(privateKey, p);
BigInteger m = c2.multiply(K.modInverse(p)).mod(p);
System.out.println("K:" + K.toString());
System.out.println("m:" + m);
return m;
}
public void initP(int size) {
SecureRandom secureRandom = new SecureRandom();
while (true) {
q = BigInteger.probablePrime(size, secureRandom);
if (q.bitLength() != size) {
continue;
}
if (q.isProbablePrime(10)) {
p = q.multiply(new BigInteger("2")).add(BigInteger.ONE);
if (p.isProbablePrime(10)) {
break;
}
}
}
do {
g = BigInteger.probablePrime(p.bitLength() - 1, secureRandom);
} while (g.modPow(BigInteger.ONE, p).equals(BigInteger.ONE) || g.modPow(q, p).equals(BigInteger.ONE));
System.out.println(p);
System.out.println(q);
System.out.println(g);
}
public static BigInteger getG() {
return g;
}
public static BigInteger getP() {
return p;
}
public static BigInteger getQ() {
return q;
}
public static void main(String[] args) {
try {
ElGamal elGamal = new ElGamal();
HashMap<String, String> keyPair = elGamal.generateKeyPair(256);
BigInteger privateKey = new BigInteger(keyPair.get("privateKey"));
BigInteger publicKey = new BigInteger(keyPair.get("publicKey"));
BigInteger m = new BigInteger("123456");
HashMap<String,String> encMessage = elGamal.encryElGamal(m,getG(),getP(),publicKey);
BigInteger m2 = elGamal.decryElGamal(getG(),getP(),privateKey,encMessage);
System.out.println(m2);
} catch (Exception e) {
e.printStackTrace();
}
}
}