java实现DH非对称加密工具包

请珍惜作者劳动成果:

  • 欢迎评论
  • 你的评价是我的进步
  • 如有Ctrl+c 请注明出处

刚学习完一点加密知识就迫不及待和大家分享了,这些都是JDK自带实现,不用下载什么jar包。代码复制就可以使用! 希望大家也多多分享自己的成果!让我们在项目中可以到网上copy代码,增加开发效率。。。。

package 加密;

import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

/**
 * 该算法属于一种交换算法, 发送方生成自己的密钥对,再将公钥传递到接收方,
 * 接收方再根据发送方的公钥生成自己的密钥对,接着将自己生成的密钥对公钥传递到发送方。 这时候发送方根据对方的公钥和自己的私钥生成新的本地密钥
 * 而接收方也根据对方之前发生的公钥和自己的私钥生成新的本地密钥 双方生成的本地密钥是相同。弥补了对称加密密钥传递不安全的问题。
 * 
 * @author Administrator 君琦
 *
 */
public class DHutil {

    public static void main(String[] args) {
        // 发送方生成自己的密钥对并保存
        Map<String, byte[]> map = getKey();
        // 接收方根据发送方的公钥生成自己的密钥对并保存
        Map<String, byte[]> map1 = getKey(map.get("publicKey"));
        // 根据发送方的公钥和接收方私钥生成 接收方的本地密钥
        byte[] bytes = getSecretKey(map.get("publicKey"),
                map1.get("privateKey"), "AES");
        System.out.println("接收方的本地密钥    " + parseByte2HexStr(bytes));
        // 根据接收方公钥和发送方私钥生成发送方本地密钥
        bytes = getSecretKey(map1.get("publicKey"), map.get("privateKey"),
                "AES");
        System.out.println("发送方的本地密钥    " + parseByte2HexStr(bytes));

    }

    /**
     * 发送方生成自己的密钥对
     * 
     * @return 返回密钥对 失败则null
     */
    public static Map<String, byte[]> getKey() {
        Map<String, byte[]> map = null;
        try {
            // 实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator
                    .getInstance("DH");
            // 初始化密钥生成器 密钥长度默认1024 长度只能为512~1024 并且必须时64的倍数
            keyPairGenerator.initialize(1024);
            // 生成密钥对
            KeyPair keypair = keyPairGenerator.generateKeyPair();
            // 获得公钥
            PublicKey publicKey = keypair.getPublic();
            // 获得私钥
            PrivateKey privateKey = keypair.getPrivate();

            map = new HashMap<String, byte[]>();
            // 存储密钥
            map.put("publicKey", publicKey.getEncoded());
            map.put("privateKey", privateKey.getEncoded());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 得到发送方的公钥,生成接收方自己的密钥对
     * 
     * @param key
     *            发送方传递的公钥
     * @return 返回自己的密钥对 失败则null
     */
    public static Map<String, byte[]> getKey(byte[] key) {
        Map<String, byte[]> map = null;
        try {
            // 实例化密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
            // 将对方公钥从数组转换为PublicKey
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(key);
            // 产生对方公钥publicKey
            DHPublicKey dhpublicKey = (DHPublicKey) keyFactory
                    .generatePublic(keySpec);
            // 剖析对方key 获取其参数
            DHParameterSpec dhParameterSpec = dhpublicKey.getParams();
            // 实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator
                    .getInstance("DH");
            // 使用对方公钥参数初始化生成器
            keyPairGenerator.initialize(dhParameterSpec);
            // 生成密钥对
            KeyPair keypair = keyPairGenerator.generateKeyPair();
            // 获得公钥
            PublicKey publicKey = keypair.getPublic();
            // 获得私钥
            PrivateKey privateKey = keypair.getPrivate();

            map = new HashMap<String, byte[]>();
            // 存储密钥
            map.put("publicKey", publicKey.getEncoded());
            map.put("privateKey", privateKey.getEncoded());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 将对方公钥 结合自己的私钥 生成一个双方都相同的密钥 , 方便进行对称加密操作。
     * 
     * @param publicKey
     *            对方传递的公钥
     * @param privateKey
     *            自己的私钥
     * @param algorithm
     *            生成哪个对称加密算法的密钥
     * @return 返回对称算法的共同密钥 失败则null
     */
    public static byte[] getSecretKey(byte[] publicKey, byte[] privateKey,
            String algorithm) {
        byte[] result = null;
        try {
            // 实例化密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance("DH");
            // 将publicKey转换为Key对象
            PublicKey publicKey2 = keyFactory
                    .generatePublic(new X509EncodedKeySpec(publicKey));
            // 将privateKey转换为Key对象
            PrivateKey privateKey2 = keyFactory
                    .generatePrivate(new PKCS8EncodedKeySpec(privateKey));

            // 根据以上私钥和公钥生成本地密钥SecretKey

            // 先实例化KeyAgreement
            KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
            // 用自己的私钥初始化keyAgreement
            keyAgreement.init(privateKey2);
            // 结合对方公钥进行运算
            keyAgreement.doPhase(publicKey2, true);
            // 开始生成本地密钥SecretKey 密钥算法为对称算法
            SecretKey secretKey = keyAgreement.generateSecret(algorithm);
            result = secretKey.getEncoded();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }

    /**
     * 将二进制转换成16进制
     * 
     * @param buf
     * @return
     */
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * 将16进制转换为二进制
     * 
     * @param hexStr
     * @return
     */
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
                    16);
            result[i] = (byte) (high * 16 + low);
        }
        return result;
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值