版权声明:转载请注明出处 https://blog.csdn.net/laozhaishaozuo/article/details/81975763
- ElGamal算法
ElGamal算法
ElGamal算法,是一种较为常见的加密算法,它是基于1985年提出的公钥密码体制和椭圆曲线加密体系。百度百科
就像之前说的,ElGamal算法也是基于数学难题,不过ElGamal是基于离散对数。它跟RSA算法一样,既能应用于数据加密也能应用于数字签名。
在Jdk8中本身并没有提供ElGamal算法的支持,我们可以使用Bouncy Castle 加密组件。
ElGamalCoder
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ElGamalParameterSpec;
/**
* ElGamal 编码组件<br>
* jdk 不支持 Bouncy Castle支持
*
* @author shaozuo
* @date 2018/08/01
*/
public final class ElGamalCoder {
public static final String ALGORITHM_NAME = "ElGamal";
private ElGamalCoder() {
}
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final int KEY_SIZE = 256;
private static final String PUBLIC_KEY = "public_key";
private static final String PRIVATE_KEY = "private_key";
/**
* 初始化公钥
*
* @return Map 密钥map
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception {
AlgorithmParameterGenerator parameterGenerator = AlgorithmParameterGenerator
.getInstance(ALGORITHM_NAME);
parameterGenerator.init(KEY_SIZE);
AlgorithmParameters parameters = parameterGenerator.generateParameters();
ElGamalParameterSpec spec = parameters.getParameterSpec(ElGamalParameterSpec.class);
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_NAME);
keyPairGenerator.initialize(spec, new SecureRandom());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
public static byte[] getPublicKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
/**
* 使用公钥加密数据
*
* @param data
* 待加密数据
* @param encodedPublicKey
* 公钥
* @return
* @throws GeneralSecurityException
*/
public static byte[] encyptByPublicKey(byte[] data, byte[] encodedPublicKey)
throws GeneralSecurityException {
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(encodedPublicKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME);
PublicKey publicKey = factory.generatePublic(encodedKeySpec);
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
System.out.println(data.length);
return cipher.doFinal(data);
}
/**
* 使用私钥解密数据
*
* @param data
* 待解密数据
* @param encodedPublicKey
* 私钥
* @return
* @throws GeneralSecurityException
*/
public static byte[] decyptByPrivateKey(byte[] data, byte[] encodedPrivateKey)
throws GeneralSecurityException {
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME);
PrivateKey privateKey = factory.generatePrivate(encodedKeySpec);
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
}
ElGamalCoderTest
import static org.junit.Assert.assertEquals;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.junit.Before;
import org.junit.Test;
public class ElGamalCoderTest {
// 公钥
private byte[] publicKey;
// 私钥
private byte[] privateKey;
String rawStrForPub = "ElGamal加密";
@Before
public final void initKey() throws Exception {
Map<String, Object> keyMap = ElGamalCoder.initKey();
publicKey = ElGamalCoder.getPublicKey(keyMap);
privateKey = ElGamalCoder.getPrivateKey(keyMap);
System.out.println("公钥: " + Base64.encodeBase64String(publicKey));
System.out.println("私钥: " + Base64.encodeBase64String(privateKey));
}
@Test
public void test() throws Exception {
System.out.println("待加密数据:" + rawStrForPub);
System.out.println("原文:" + rawStrForPub);
byte[] encodeData = ElGamalCoder.encyptByPublicKey(rawStrForPub.getBytes(), publicKey);
System.out.println("加密数据: " + Base64.encodeBase64String(encodeData));
byte[] decodeData = ElGamalCoder.decyptByPrivateKey(encodeData, privateKey);
String output = new String(decodeData);
System.out.println("解密数据:" + output);
assertEquals(rawStrForPub, output);
}
}
参考资料
关于本章内容,参考了一下书籍和文章
- Java加密与解密的艺术 链接
- ElGamal算法百度百科
- Jdk支持的算法官方文档
- Bouncy Castle