铁马冰河2000

导航

Java加解密-Elgamal非对称加密算法

Elgamal算法

  和RSA不同的是它只提供公钥加密,它依靠BouncyCastle实现。

  java实现如下:

============================================================================Elgamal加解密工具类:

import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
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 javax.crypto.spec.DHParameterSpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

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加解密工具测试类:

    @Test
    public void test_Elgamal() {
        //公钥
        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);
    }

 

posted on 2022-01-23 22:44  铁马冰河2000  阅读(443)  评论(1编辑  收藏  举报