如何用java实现ECDH双端通信加解密
时间: 2024-01-23 10:02:38 浏览: 180
ECDH (Elliptic Curve Diffie-Hellman) 是一种基于椭圆曲线的密钥交换算法,用于实现双方通信的加密与解密。下面是一个简单的 Java 实现。
首先,需要引入相关的库:
```java
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.Cipher;
```
然后,定义一个 ECDH 类,包含如下方法:
1. 生成密钥对
```java
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256k1"); // 使用secp256k1曲线
keyPairGenerator.initialize(ecGenParameterSpec);
return keyPairGenerator.generateKeyPair();
}
```
2. 生成共享密钥
```java
public static byte[] generateSharedSecret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("ECIES");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] secret = cipher.doFinal();
return secret;
}
```
3. 加密数据
```java
public static byte[] encrypt(byte[] data, byte[] sharedSecret) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(sharedSecret, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(sharedSecret); // 使用共享密钥作为IV
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encryptedData = cipher.doFinal(data);
return encryptedData;
}
```
4. 解密数据
```java
public static byte[] decrypt(byte[] encryptedData, byte[] sharedSecret) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(sharedSecret, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(sharedSecret); // 使用共享密钥作为IV
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] data = cipher.doFinal(encryptedData);
return data;
}
```
完整代码如下:
```java
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidAlgorithmParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.ECGenParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class ECDH {
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
ECGenParameterSpec ecGenParameterSpec = new ECGenParameterSpec("secp256k1"); // 使用secp256k1曲线
keyPairGenerator.initialize(ecGenParameterSpec);
return keyPairGenerator.generateKeyPair();
}
public static byte[] generateSharedSecret(PrivateKey privateKey, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("ECIES");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] secret = cipher.doFinal();
return secret;
}
public static byte[] encrypt(byte[] data, byte[] sharedSecret) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(sharedSecret, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(sharedSecret); // 使用共享密钥作为IV
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encryptedData = cipher.doFinal(data);
return encryptedData;
}
public static byte[] decrypt(byte[] encryptedData, byte[] sharedSecret) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(sharedSecret, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(sharedSecret); // 使用共享密钥作为IV
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] data = cipher.doFinal(encryptedData);
return data;
}
public static void main(String[] args) throws Exception {
// 生成密钥对
KeyPair keyPairA = generateKeyPair();
KeyPair keyPairB = generateKeyPair();
// A计算共享密钥
byte[] secretA = generateSharedSecret(keyPairA.getPrivate(), keyPairB.getPublic());
// B计算共享密钥
byte[] secretB = generateSharedSecret(keyPairB.getPrivate(), keyPairA.getPublic());
// 加密数据
byte[] data = "Hello, ECDH!".getBytes();
byte[] encryptedData = encrypt(data, secretA);
// 解密数据
byte[] decryptedData = decrypt(encryptedData, secretB);
System.out.println(new String(decryptedData)); // 输出:Hello, ECDH!
}
}
```
注意:此代码仅为示例,实际应用中需要根据具体情况进行调整。另外,ECDH 算法的安全性与曲线的选择有关,需要根据实际需求选择合适的曲线。
阅读全文