非对称加密算法需要两个密钥:公钥和私钥。公钥]与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
DH1976年非对称加密算法思想被提出,但是当时并没有给出具体算法和方案,因为当时没有研究出单向函数(也就是信息摘要算法还没出现),但是IEEE的期刊中给出了通信时双方如何通过信息交换协商密钥的算法,也就是DH算法,通过该算法双方可以协商对称加密的密钥。
package com.demo; import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin; import javax.crypto.*; import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; public class dhdemo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { // 1.初始化发送方密钥 KeyPairGenerator sendKeyPairGenerator = KeyPairGenerator.getInstance("DH"); sendKeyPairGenerator.initialize(512); KeyPair sendKeyPair = sendKeyPairGenerator.generateKeyPair(); byte[] sendPublicKeyEnc = sendKeyPair.getPublic().getEncoded();//生成发送方公钥,发送给接收方(网络、文件...) // 2.初始化接收方密钥: KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH"); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(sendPublicKeyEnc); PublicKey receivePublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec); DHParameterSpec dhParameterSpec = ((DHPublicKey)receivePublicKey).getParams(); KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH"); receiverKeyPairGenerator.initialize(dhParameterSpec); KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair(); PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate(); byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded(); // 3.构建接收方密钥: KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH"); receiverKeyAgreement.init(receiverPrivateKey); receiverKeyAgreement.doPhase(receivePublicKey, true); SecretKey receiverDESKey = receiverKeyAgreement.generateSecret("DES");//接收方Key // 4.构建发送方密钥: KeyFactory sendKeyFactory = KeyFactory.getInstance("DH"); x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc); PublicKey sendPublicKey = sendKeyFactory.generatePublic(x509EncodedKeySpec); KeyAgreement sendKeyAgreement = KeyAgreement.getInstance("DH"); sendKeyAgreement.init(sendKeyPair.getPrivate()); sendKeyAgreement.doPhase(sendPublicKey, true); SecretKey sendDESKey = sendKeyAgreement.generateSecret("DES");//发送方Key // 5.发送方加密: Cipher sendCipher = Cipher.getInstance("DES"); sendCipher.init(Cipher.ENCRYPT_MODE, sendDESKey); byte[] sendResult = sendCipher.doFinal(name.getBytes()); System.out.println("sendResult :"+ HexBin.encode(sendResult)); // 6.接收方解密: Cipher receiverCipher = Cipher.getInstance("DES"); receiverCipher.init(Cipher.DECRYPT_MODE, receiverDESKey); byte[] receiverResult = receiverCipher.doFinal(sendResult); System.out.println("receiverResult : "+new String (receiverResult)); } } RSARSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。RSA算法实现了公钥加密、私钥解密 和私钥解密、公钥加密的一个机制。
也就是说使用公钥来进行加密,想要解密获取明文内容,就必须使用对应的私钥来进行解密。而在其中私钥中的内容其实是比较长的,而公钥里面的内容会偏短一些。因为私钥一般会储存在本地,而公钥会放到各大互联网上,公钥比私钥内容短也是为了方便传输和存储。
代码示例: package com.demo; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import sun.misc.BASE64Encoder; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class rsademo { private static String name = "xiaoming"; public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { // 1.初始化密钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");//设置获取RSA的密钥 keyPairGenerator.initialize(512);//设置密钥长度 KeyPair keyPair = keyPairGenerator.generateKeyPair();//生成密钥对 RSAPublicKey rsaPublic =(RSAPublicKey) keyPair.getPublic();//获取公钥 RSAPrivateKey rsaPrivate = (RSAPrivateKey)keyPair.getPrivate();//获取私钥 // System.out.println(new BASE64Encoder().encode(rsaPublic.getEncoded()));//输出公钥 System.out.println(""); // System.out.println(new BASE64Encoder().encode(rsaPrivate.getEncoded()));//输出私钥 // 2.私钥加密、公钥解密 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivate.getEncoded());//对密钥进行编码处理 KeyFactory rsa = KeyFactory.getInstance("RSA");//设置获取RSA的密钥 PrivateKey privateKey = rsa.generatePrivate(pkcs8EncodedKeySpec);//从提供的密钥规范生成私钥对象。 // 2.1私钥加密 Cipher encodecipher = Cipher.getInstance("RSA");//设置获取RSA的密钥 encodecipher.init(Cipher.ENCRYPT_MODE,privateKey);//设置为加密类型并传入私钥进行加密 byte[] res = encodecipher.doFinal(name.getBytes());//对内容进行加密 System.out.println(new BASE64Encoder().encode(res)); // 2.2公钥解密 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublic.getEncoded());//对公钥进行编码处理 rsa = KeyFactory.getInstance("RSA");//设置获取RSA的密钥 PublicKey publicKey = rsa.generatePublic(x509EncodedKeySpec);//从提供的密钥规范生成公钥对象。 Cipher decodecipher = Cipher.getInstance("RSA");//设置获取RSA的密钥 decodecipher.init(Cipher.DECRYPT_MODE,publicKey);//设置解密类型并传入公钥进行解密 byte[] decoderes = decodecipher.doFinal(res);//对内容进行解密 System.out.println(new String(decoderes)); } }