秘钥交换算法(DH算法+非对称加密算法)

在不安全的信道上传递加密文件,当加密文件被截取时,没有秘钥,无法破解密文,但是如何在不安全的信道上安全的传输秘钥呢?如何传输秘钥才能使秘钥被截取是还能保证密文的安全的?

要解决这个问题,则需要要使用密钥交换算法,秘钥交换算法有两种:对称加密算法以及非对称加密算法

对称加密

对称加密算法:DH算法

DH算法交换密钥的步骤:

  1. Alice 首选选择一个素数p=5099,底数g=5(任选),随机数a =123,然后计算A=g^a mod p,    结果是215,然后, Alice 发送 p=509,g=5,A=215给Bob;
  2. Bob 收到后,也选择一个随机数b    =456,然后计算B=g^bmodp,结果是181Bob再同时计算K=A A^b mod p,结果是121;
  3. Bob 把计算的 B=181 发给 Alice    Alice计算 K=B^a modp的余数计算结果与Bob 算出的结果一样,者都是121 。

 使用java实现DH算法的步骤:

  1. 首先需要用户类,在用户类中定义用户姓名以及密钥(私钥+公钥+共享密钥)
  2. 然后定义方法根据DH算法生成一个密钥对(公钥+私钥)
  3. 其次定义方法按照 "对方的公钥" => 生成"共享密钥"
public class Work3 {
	public static void main(String[] args) {
		// Bob和Alice:
        Person bob = new Person("Bob");
        Person alice = new Person("Alice");
        
        // 各自生成KeyPair: 公钥+私钥
        bob.generateKeyPair();
        alice.generateKeyPair();

        // 双方交换各自的PublicKey(公钥):
        // Bob根据Alice的PublicKey生成自己的本地密钥(共享公钥):
        bob.generateSecretKey(alice.publicKey.getEncoded());
          
        // Alice根据Bob的PublicKey生成自己的本地密钥(共享公钥):
        alice.generateSecretKey(bob.publicKey.getEncoded());

        // 检查双方的本地密钥是否相同:
        bob.printKeys();
        alice.printKeys();
	}
}

//用户类
class Person {
	public final String name; // 姓名

	// 密钥
	public PublicKey publicKey; // 公钥
	private PrivateKey privateKey; // 私钥
	private byte[] secretKey; // 本地秘钥(共享密钥)

	// 构造方法
	public Person(String name) {
		this.name = name;
	}

	// 生成本地KeyPair:(公钥+私钥)
	public void generateKeyPair() {
		try {
			//创建DH算法的"秘钥对"生成器
			KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH");
			kpGen.initialize(512);
			
			//生成一个密钥对
			KeyPair kp = kpGen.generateKeyPair();
			this.privateKey = kp.getPrivate();//私钥
			this.publicKey = kp.getPublic();//公钥
			
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	// 按照 "对方的公钥" => 生成"共享密钥"
	public void generateSecretKey(byte[] receivedPubKeyBytes) {
		
		try {
			//从byte[]恢复PublicKey
			X509EncodedKeySpec ketSpec = new X509EncodedKeySpec(receivedPubKeyBytes);
			
			//根据DH算法获取keyFactory
			KeyFactory kf = KeyFactory.getInstance("DH");
			
			//通过keyFactory创建公钥
			PublicKey receivePublicKey = kf.generatePublic(ketSpec);
			
			//创建秘钥协议对象(用于协商秘钥)
			KeyAgreement keyAgreemnet = KeyAgreement.getInstance("DH");
			keyAgreemnet.init(this.privateKey);//初始化自己的PravateKey
			keyAgreemnet.doPhase(receivePublicKey, true);//根据对方的PublicKey
			
			//生成SecretKey本地密钥(共享秘钥)
			this.secretKey = keyAgreemnet.generateSecret();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void printKeys() {
		System.out.printf("Name: %s\n", this.name);
		System.out.printf("Private key: %x\n", new BigInteger(1, this.privateKey.getEncoded()));
		System.out.printf("Public key: %x\n", new BigInteger(1, this.publicKey.getEncoded()));
		System.out.printf("Secret key: %x\n", new BigInteger(1, this.secretKey));
	}
}

对称加密算法是指加密和解密使用的是相同的密钥,其特点是算法公开,计算量小,加密速度快,加密效率高。缺点是双方都使用同样的密钥,安全性较低,包括AES、DES、IDEA。

具体对称加密算法--> 对称加密算法_猿究院~小曹曹曹曹曹曹曹的博客-CSDN博客

非对称加密

非对称加密算法是指加密和解密使用的是不同的密钥(公钥加密,私钥解密),非对称加密的经典算法为RSA算法。

使用非对称加密算法的步骤(小明给小红发送信息):

  1. 生成个人密钥对(公钥+私钥)
  2. 小明使用小红的公钥进行加密(把加密结果发送给小红)
  3. 小红使用自己的私钥进行解密
//RSA
public class Work4 {
	public static void main(String[] args) throws Exception {
		// 明文:
		byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");

		// 创建公钥/私钥对
		Human hong = new Human("小红");
		Human ming = new Human("小明");
		
		// 小明使用小红的公钥进行加密
		// 1.获取小红的公钥
		PublicKey hongPublicKey = hong.getPublicKey();
		System.out.println(String.format("小红的public key(公钥): %x", new BigInteger(1, hongPublicKey.getEncoded())));

		// 2.使用公钥加密
		byte[] encrypted = ming.encrypt(plain, hongPublicKey);
		System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));

		// 小红使用自己的私钥解密:
		// 1.获取小红的私钥,并输出
		PrivateKey hongPrivateKey = hong.getPrivateKey();
		System.out.println(String.format("小红的private key(私钥): %x", new BigInteger(1, hongPrivateKey.getEncoded())));

		// 2.使用私钥解密
		byte[] decrypted = hong.decrypt(encrypted);
		System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
	}
}

//用户类
class Human {
	// 姓名
	String name;

	// 私钥:
	PrivateKey privatekey;

	// 公钥:
	PublicKey publickey;

	// 构造方法
	public Human(String name) throws GeneralSecurityException {
		// 初始化姓名
		this.name = name;

		// 生成公钥/私钥对:
		KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
		kpGen.initialize(1024);
		KeyPair kp = kpGen.generateKeyPair();
		
		this.privatekey = kp.getPrivate();
		this.publickey = kp.getPublic();
		
	}

	// 把私钥导出为字节
	public PrivateKey getPrivateKey() {
		return this.privatekey;
	}

	// 把公钥导出为字节
	public PublicKey getPublicKey() {
		return this.publickey;
	}

	// 用公钥加密
	public byte[] encrypt(byte[] message,PublicKey publickey) throws GeneralSecurityException {
		// 使用公钥进行初始化
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publickey);//使用公钥进行初始化
		return cipher.doFinal(message);
	}

	// 用私钥解密:
	public byte[] decrypt(byte[] input) throws GeneralSecurityException {
		// 使用私钥进行初始化
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, this.privatekey);//使用私钥进行初始化
		return cipher.doFinal(input);
	}
}

非对称加密的缺点:运算速度非常慢,比对称加密慢得多

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值