Java实现ELGAMAL非对称加密算法
2022-05-07 本文已影响0人
小波同学
ELGAMAL算法
和RSA不同的是它只提供公钥加密,它依靠BouncyCastle实现。
![](https://img.haomeiwen.com/i13587608/d9d61abc48c2a1d1.png)
![](https://img.haomeiwen.com/i13587608/394e1d3aced895cd.png)
java实现如下:
- 引入BouncyCastle
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
- Elgamal java实现工具类
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* @author: huangyibo
* @Date: 2022/5/6 18:03
* @Description:
*/
public class SecurityElgamal {
/**
* 非对称加密算法——ELGamal算法
* 对于:“Illegal key size or default parameters”异常,是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。
* Java 7 无政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html,
* 下载后得到UnlimitedJCEPolicyJDK7.zip,解压替换%JAVA_HOME%/jre/lib/security的两个文件即可
*/
//公钥
private static final String PUBLIC_KEY = "elgamalPublicKey";
//私钥
private static final String PRIVATE_KEY = "elgamalPrivateKey";
/** 初始化密钥对
* @return Map 密钥对Map
* @throws Exception
*/
public static Map<String, Object> initKey() {
try {
Security.addProvider(new BouncyCastleProvider());//加入对Bouncy Castle的支持
//1.初始化发送方密钥
AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance("ELGamal");
algorithmParameterGenerator.init(256);//初始化参数生成器
AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();//生成算法参数
DHParameterSpec dhParameterSpec = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);//构建参数材料
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ELGamal");//实例化密钥对生成器
//初始化密钥对生成器
keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//公钥和私钥
PublicKey elGamalPublicKey = keyPair.getPublic();
PrivateKey elGamalPrivateKey = keyPair.getPrivate();
//将密钥对存储在Map中
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put(PUBLIC_KEY, elGamalPublicKey);
keyMap.put(PRIVATE_KEY, elGamalPrivateKey);
return keyMap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/** 加密【公钥加密,私钥解密】
* @param data 待加密数据
* @param key 公钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key) {
try {
PublicKey pubKey = (PublicKey) KeyFactory.getInstance("ELGamal")
.generatePublic(new X509EncodedKeySpec(key));
Cipher cipher = Cipher.getInstance("ELGamal","BC");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** 解密【公钥加密,私钥解密】
* @param data 待解密数据
* @param key 私钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) {
try {
PrivateKey priKey = (PrivateKey) KeyFactory.getInstance("ELGamal")
.generatePrivate(new PKCS8EncodedKeySpec(key));
//实例化
Cipher cipher = Cipher.getInstance("ELGamal","BC");
//使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, priKey);
//执行操作
byte[] result = cipher.doFinal(data);
return result;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
/** 取得私钥
* @param keyMap 密钥Map
* @return byte[] 私钥
* @throws Exception
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/** 取得公钥
* @param keyMap 密钥Map
* @return byte[] 公钥
* @throws Exception
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
}
- Elgamal加解密工具测试类
/**
* @author: huangyibo
* @Date: 2022/5/6 18:04
* @Description:
*/
public class ElgamalTest {
public static void main(String[] args) {
//公钥
byte[] publicKey;
//私钥
byte[] privateKey;
//初始化密钥
//生成甲方密钥对
Map<String, Object> keyMap = SecurityElgamal.initKey();
publicKey = SecurityElgamal.getPublicKey(keyMap);
privateKey = SecurityElgamal.getPrivateKey(keyMap);
System.out.println("Elgamal公钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(publicKey));
System.out.println("Elgamal私钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(privateKey));
System.out.println();
System.out.println("===甲方向乙方发送加密数据===");
String msgA2B = "求知若饥,虚心若愚。";
System.out.println("原文:\n" + msgA2B);
System.out.println("---甲方使用公钥对数据进行加密---");
//使用公钥对数据加密
byte[] encodeMsgA2B = SecurityElgamal.encrypt(msgA2B.getBytes(), publicKey);
System.out.println("Elgamal加密:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(encodeMsgA2B));
System.out.println("---乙方使用私钥对数据库进行解密---");
//使用私钥对数据进行解密
byte[] msgB2A = SecurityElgamal.decrypt(encodeMsgA2B, privateKey);
String output1 = new String(msgB2A);
System.out.println("Elgamal解密:\n" + output1);
}
}