密钥长度 | 默认 | 实现方 |
---|---|---|
512~1024(64倍数) | 1024 | JDK |
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;
/**
* 基于 DH 算法的非对称加密工具类
*
* @Author LeifChen
* @Date 2018-11-30
*/
public class DhUtils {
static final String DH = "DH";
static final String DES = "DES";
static final String STR = "Hello LeifChen";
public static void jdkDH() {
try {
// 1.发送方构建公钥私钥
KeyPair senderKeyPair = generateSenderPublicKey();
// 2.发送方发布公钥
byte[] senderPublicKeyBytes = senderKeyPair.getPublic().getEncoded();
// 3.接收方构建公钥私钥->接收方通过发送方公钥构建公钥私钥
KeyPair receiverKeyPair = generateReceiverPublicKey(senderPublicKeyBytes);
// 4.接收方发布公钥
byte[] receiverPublicKeyBytes = receiverKeyPair.getPublic().getEncoded();
// 5.接收方构建对称加密秘钥->依据发送方公钥和接收方公钥私钥构建
SecretKey receiverDESKey = generateSecretKey(receiverKeyPair, senderPublicKeyBytes);
// 6.发送方构建对称加密秘钥->依据接收方公钥和发送方公钥私钥构建
SecretKey senderDESKey = generateSecretKey(senderKeyPair, receiverPublicKeyBytes);
if (Objects.equals(receiverDESKey, senderDESKey)) {
System.out.println("双方密钥相同");
}
// 7.发送方加密
Cipher cipher = Cipher.getInstance(DES);
cipher.init(Cipher.ENCRYPT_MODE, senderDESKey);
byte[] result = cipher.doFinal(STR.getBytes());
System.out.println("JDK DH Encrypt: " + Base64.encodeBase64String(result));
// 8.接收方解密
cipher.init(Cipher.DECRYPT_MODE, receiverDESKey);
result = cipher.doFinal(result);
System.out.println("JDK DH Decrypt: " + new String(result));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 发送方构建密钥
*
* @return 构建完的公钥私钥
* @throws NoSuchAlgorithmException
*/
private static KeyPair generateSenderPublicKey() throws NoSuchAlgorithmException {
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance(DH);
senderKeyPairGenerator.initialize(512);
return senderKeyPairGenerator.generateKeyPair();
}
/**
* 依据发送方公钥构建接收方公钥私钥
*
* @param senderPublicKey 发送方公钥
* @return 接收方公钥私钥
* @throws Exception
*/
private static KeyPair generateReceiverPublicKey(byte[] senderPublicKey) throws Exception {
KeyFactory receiverKeyFactory = KeyFactory.getInstance(DH);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKey);
PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams();
KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance(DH);
receiverKeyPairGenerator.initialize(dhParameterSpec);
return receiverKeyPairGenerator.generateKeyPair();
}
/**
* 使用自己的公钥私钥与对方的公钥构建 对称密钥
*
* @param keyPair 自己的公钥私钥
* @param publicKeyBytes 对方的公钥
* @return 本地对称加密密钥
* @throws Exception
*/
private static SecretKey generateSecretKey(KeyPair keyPair, byte[] publicKeyBytes) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(DH);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyBytes);
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
KeyAgreement keyAgreement = KeyAgreement.getInstance(DH);
keyAgreement.init(keyPair.getPrivate());
keyAgreement.doPhase(publicKey, true);
return keyAgreement.generateSecret(DES);
}
}
java.security.NoSuchAlgorithmException: Unsupported secret key algorithm: DES
错误-Djdk.crypto.KeyAgreement.legacyKDF=true
密钥长度 | 默认 | 工作方式 | 填充方式 | 实现方 |
---|---|---|---|---|
512~65536(64整数倍) | 1024 | ECB | NoPadding PKCS1Padding OAEPWITHMD5AndMGF1Pading OAEPWITHSHA1AndMGF1Pading OAEPWITHSHA256AndMGF1Pading OAEPWITHSHA384AndMGF1Pading OAEPWITHSHA512AndMGF1Pading |
JDK |
512~65536(64整数倍) | 2048 | NONE | NoPadding PKCS1Padding OAEPWITHMD5AndMGF1Pading OAEPWITHSHA1AndMGF1Pading OAEPWITHSHA224AndMGF1Pading OAEPWITHSHA256AndMGF1Pading OAEPWITHSHA384AndMGF1Pading OAEPWITHSHA512AndMGF1Pading ISO9796-1Padding |
BC |
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* 基于 RSA 算法的非对称加密工具类
*
* @Author LeifChen
* @Date 2018-11-30
*/
public class RsaUtils {
static final String RSA = "RSA";
static final String STR = "Hello LeifChen";
public static void jdkRSA() {
try {
// 构建密钥对
KeyPair keyPair = generateSenderPublicKey();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
// 1.私钥加密、公钥解密——加密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(STR.getBytes());
System.out.println("私钥加密、公钥解密——加密:" + Base64.encodeBase64String(result));
// 2.私钥加密、公钥解密——解密
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance(RSA);
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
result = cipher.doFinal(result);
System.out.println("私钥加密、公钥解密——解密:" + new String(result));
// 3.公钥加密、私钥解密——加密
x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance(RSA);
publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = cipher.doFinal(STR.getBytes());
System.out.println("公钥加密、私钥解密——加密:" + Base64.encodeBase64String(result));
// 4.公钥加密、私钥解密——解密
pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance(RSA);
privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(result);
System.out.println("公钥加密、私钥解密——解密:" + new String(result));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 构建密钥对
*
* @return 构建完的公钥私钥
* @throws NoSuchAlgorithmException
*/
private static KeyPair generateSenderPublicKey() throws NoSuchAlgorithmException {
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance(RSA);
senderKeyPairGenerator.initialize(512);
return senderKeyPairGenerator.generateKeyPair();
}
}
密钥长度 | 默认 | 工作方式 | 填充方式 | 实现方 |
---|---|---|---|---|
160~16384(8整数倍) | 1024 | ECB、NONE | NoPadding PKCS1Padding OAEPWITHMD5AndMGF1Pading OAEPWITHSHA1AndMGF1Pading OAEPWITHSHA224AndMGF1Pading OAEPWITHSHA256AndMGF1Pading OAEPWITHSHA384AndMGF1Pading OAEPWITHSHA512AndMGF1Pading ISO9796-1Padding |
BC |
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* 基于 ElGamal 算法的非对称加密工具类
*
* @Author LeifChen
* @Date 2018-11-30
*/
public class ElGamalUtils {
static final String ELGAMAL = "ElGamal";
static final String STR = "Hello LeifChen";
public static void bcElGamal() {
Security.addProvider(new BouncyCastleProvider());
try {
AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator.getInstance(ELGAMAL);
System.out.println(algorithmParameterGenerator.getProvider());
algorithmParameterGenerator.init(256);
AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();
DHParameterSpec dhParameterSpec = algorithmParameters.getParameterSpec(DHParameterSpec.class);
// 构建密钥对
KeyPair keyPair = generateSenderPublicKey(dhParameterSpec);
PublicKey elGamalPublicKey = keyPair.getPublic();
PrivateKey elGamalPrivateKey = keyPair.getPrivate();
// 公钥加密、私钥解密——加密
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance(ELGAMAL);
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(STR.getBytes());
System.out.println("公钥加密、私钥解密——加密:" + Base64.encodeBase64String(result));
// 公钥加密、私钥解密——解密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance(ELGAMAL);
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(result);
System.out.println("公钥加密、私钥解密——解密:" + new String(result));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 构建密钥对
*
* @return 构建完的公钥私钥
* @throws NoSuchAlgorithmException
*/
private static KeyPair generateSenderPublicKey(DHParameterSpec dhParameterSpec) throws Exception {
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance(ELGAMAL);
senderKeyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
return senderKeyPairGenerator.generateKeyPair();
}
}