非对称加密算法是一种基于密钥的保密方法,需要公开密钥和私有密钥,在文件加密、尤其是网银中应用广泛。
DH密钥交换算法
- Diffie-Helman
- 对称加密带来的困扰
- 构建本地密钥
-
对称
DH算法的步骤
-
初始化发送方密钥
-
KeyPairGenerator [ 生成KeyPair的类 ]
(可以指定算法名称或者来指定加密的提供方)
- KeyPair [ 获取常用的密钥载体/密钥对.] [ 通常有两个信息,一个公钥(PublicKey)一个私钥(PrivateKey) ]
- PublicKey
-
-
初始化接收方密钥
- KeyFactory [ 密钥工厂/生成密钥 ]
· generatePublic() 生成公钥
· generatePrivate() 生成私钥 - X509EncodedKeySpec [ 根据ASN.1标准进行密钥编码 ]
- DHPublicKey [ PublicKey某种具体的形式 ]
- DHParameterSpec [ 随同DH算法来使用的参数集合 ]
- KeyPairGenerator [ 生成KeyPair ]
- PrivateKey
- KeyFactory [ 密钥工厂/生成密钥 ]
-
密钥构建
- KeyAgreement [ 提供密钥一致性的协议的功能 ]
- SecreatKey [ 生成一个分组的秘密密钥,提供了类型安全的操作 ]
- KeyFactory
- X509EncodedKeySpec
- Publickey
-
加密/解密
-
Cipher [ JCE框架核心内容 ]
-
撸代码咯~~~~~~~~~~~
private void jdkDH() {
try {
// 1.初始化发送方密钥
KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH");
sendKeyPairGenerator.initialize(512);//设置长度
KeyPair sendKeyPair = sendKeyPairGenerator.generateKeyPair();// 生成密钥对
byte[] sendPublicKeyEncoded = sendKeyPair.getPublic().getEncoded();// 获取Byte数组形式 发送方的公钥 ---> 发送给接收方(网络、文件、U盘拷贝[需要序列化])
// 2.初始化接收方的密钥
KeyFactory receiveKeyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(sendPublicKeyEncoded);
PublicKey receivePublicKey = receiveKeyFactory.generatePublic(x509EncodedKeySpec); // 接收方公钥
DHParameterSpec dhParameterSpec = ((DHPublicKey) receivePublicKey).getParams();
KeyPairGenerator receiveKeyPairGenerator = KeyPairGenerator.getInstance("DH");
receiveKeyPairGenerator.initialize(dhParameterSpec);
KeyPair receiveKeyPair = receiveKeyPairGenerator.generateKeyPair();
PrivateKey receivePrivate = receiveKeyPair.getPrivate();
byte[] receivePublicKeyEncoded = receiveKeyPair.getPublic().getEncoded();
// 3.密钥构建
KeyAgreement receiveKeyAgreement = KeyAgreement.getInstance("DH");
receiveKeyAgreement.init(receivePrivate);
receiveKeyAgreement.doPhase(receivePublicKey, true);
SecretKey receiveDesKey = receiveKeyAgreement.generateSecret("DES"); // 生成本地密钥
KeyFactory sendKeyFactory = KeyFactory.getInstance("DH");
x509EncodedKeySpec = new X509EncodedKeySpec(receivePublicKeyEncoded);
PublicKey sendPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec);
PrivateKey sendPrivateKey = sendKeyPair.getPrivate();
KeyAgreement sendKeyAgreement = KeyAgreement.getInstance("DH");
sendKeyAgreement.init(sendPrivateKey);
sendKeyAgreement.doPhase(sendPublicKey, true);
// 生成发送方的本地密钥
SecretKey sendDesKey = sendKeyAgreement.generateSecret("DES");
if (receiveDesKey.equals(sendDesKey)) {
Log.i("DH----->", "jdkDH: " + "双方密钥相同");
}
// 4.加密
@SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE,sendDesKey); // 加密模式
byte[] result = cipher.doFinal(srcDH.getBytes()); //加密结果
Log.i("DH----->加密结果", "result: "+ Arrays.toString(result));
// 5.解密
cipher.init(Cipher.DECRYPT_MODE,receiveDesKey); // 解密模式
result = cipher.doFinal(result); //加密结果
Log.i("DH----->解密结果", "result: "+ new String(result)); // 解密的内容是加密时生成的结果
} catch (Exception e) {
e.printStackTrace();
}
}
RSA非对称加密算法
- 基于因子分解
代码实现
private static void jdkRSA() {
try {
//1.初始化密钥
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512); // 设置长度 最大值 6536
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic(); // RSA公钥
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate(); // RSA私钥
Log.i("RSA----->", "RSA公钥: "+rsaPublicKey);
Log.i("RSA----->", "RSA私钥: "+rsaPrivateKey);
//2.私钥加密、公钥解密 --- 加密
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(srcRSA.getBytes());
Log.i("RSA----->私钥加密、公钥解密", "-------加密: "+ Arrays.toString(result));
//3.私钥加密、公钥解密 --- 解密
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);
Log.i("RSA----->私钥加密、公钥解密", "-------解密: "+ new String(result));
// 4.公钥加密、私钥解密 --- 加密
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(srcRSA.getBytes());
Log.i("RSA----->公钥加密、私钥解密", "-------加密: "+ Arrays.toString(result));
// 5.公钥加密、私钥解密 --- 解密
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);
Log.i("RSA----->公钥加密、私钥解密", "-------解密: "+ new String(result));
} catch (Exception e) {
e.printStackTrace();
}
}
ElGamal算法
- 基于离散对数
- 只提供公钥加密算法
-
JDK里没有提供实现,在BC里(Bouncy Castle)实现
代码编写与RSA相似我们就不去演示了