java编写非对称加密,解密,RSA
上半截:北京大学 肖臻 讲解
什么是非对称加密? 答:就是具有公钥 私钥的一对密钥, 对称加密则是相反 只有一个密钥串
概念:
公钥是可以公开的,
私钥是不可以公开的
使用说明: 别人可以使用我的公钥加密给我传输数据,我收到数据后可以使用自己的私钥解密数据
签名:
签名用的是自己的私钥,验证签名用的是我的私钥
使用公钥加密就只能有私钥可以解密,
使用私钥加密 就只能用公钥解密
下半截
demo 1
package com.fingerchar.core.util; import java.io.ByteArrayOutputStream; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RsaUtils { private static final Logger logger = LoggerFactory.getLogger(RsaUtils.class); /** */ /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** */ /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** */ /** * 获取公钥的key */ public static final String PUBLIC_KEY = "RSAPublicKey"; /** */ /** * 获取私钥的key */ public static final String PRIVATE_KEY = "RSAPrivateKey"; /** */ /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** */ /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** */ /** * <p> * 生成密钥对(公钥和私钥) * </p> * * @return * @throws Exception */ public static Map<String, Object> genKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static void main(String[] args) throws Exception{ Map<String,Object> map=genKeyPair(); /** * 私钥=MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKbKxLYJaD27+Gn4ozo9wBeO84ZWKwyMHlJBBx7z6Hi40pWoOyO6yDEQ6g5GcpWbDsoriJJIlWJosO02gyFVymu8UQKd3/o3y53My6ABgfvzelW/Qj9PSLpzDka6cfx6+0XJ13pL+ICKrau5fIiLfqZsR4E2yXnk7kSwbpNGzwxbAgMBAAECgYAJCY2VC3dxeODh5Q37FuN0o1NAoSSd/m2aKVnYbIDZIbKPV1k0+2bjebYk5d5JiuhHPgqdWn91oJSNldmPEdXw36q+G76ODhy9LcMIzKYYTusj4QsdwTAtYP1rvm7AJjq5TVgvXAJXdyUHvQ3x5ingIcA8klkmVEvVorgyyZKqCQJBAPol3aYHX5In7gZWw8+6wnpF9x+5UJqvgsvo2NG1iDvZXgA/qIuTVm5mnyh/sSc07EktL4/s9iMZy+jMEw8iW8UCQQCqsa9ZsyFpYpD0pv73PzB2AAuPPgsEDJitXE+RnOhjjFj3snFZnO4Fv715lJlibgpUrQDwMwx79e11Gdlph6mfAkB6cTR4Q12tfewNoETClokBLuQS3DOvM7/TLcuLgs8HdJOFjaNjhqAk9Aht22sMZORPwVVpnrSwY70i21ls7AV9AkEAqfb9vJqilVYhMosqbDVOYuEOoZZMz75fNJgrXrnXqHAykonrVijt1WmkGHD//kPGI6SUv5iFQNWTmbuggfUkzwJBAIFpuuwGxMzFNscoFQ4/dV5y96LH+C86hL5jwAq4uh434BabOgr+2aZ1bgpR7A+ue1sVMFU2fXWdL4FGe51W0Jo= * 公钥=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmysS2CWg9u/hp+KM6PcAXjvOGVisMjB5SQQce8+h4uNKVqDsjusgxEOoORnKVmw7KK4iSSJViaLDtNoMhVcprvFECnd/6N8udzMugAYH783pVv0I/T0i6cw5GunH8evtFydd6S/iAiq2ruXyIi36mbEeBNsl55O5EsG6TRs8MWwIDAQAB */ String privateKey="MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKbKxLYJaD27+Gn4ozo9wBeO84ZWKwyMHlJBBx7z6Hi40pWoOyO6yDEQ6g5GcpWbDsoriJJIlWJosO02gyFVymu8UQKd3/o3y53My6ABgfvzelW/Qj9PSLpzDka6cfx6+0XJ13pL+ICKrau5fIiLfqZsR4E2yXnk7kSwbpNGzwxbAgMBAAECgYAJCY2VC3dxeODh5Q37FuN0o1NAoSSd/m2aKVnYbIDZIbKPV1k0+2bjebYk5d5JiuhHPgqdWn91oJSNldmPEdXw36q+G76ODhy9LcMIzKYYTusj4QsdwTAtYP1rvm7AJjq5TVgvXAJXdyUHvQ3x5ingIcA8klkmVEvVorgyyZKqCQJBAPol3aYHX5In7gZWw8+6wnpF9x+5UJqvgsvo2NG1iDvZXgA/qIuTVm5mnyh/sSc07EktL4/s9iMZy+jMEw8iW8UCQQCqsa9ZsyFpYpD0pv73PzB2AAuPPgsEDJitXE+RnOhjjFj3snFZnO4Fv715lJlibgpUrQDwMwx79e11Gdlph6mfAkB6cTR4Q12tfewNoETClokBLuQS3DOvM7/TLcuLgs8HdJOFjaNjhqAk9Aht22sMZORPwVVpnrSwY70i21ls7AV9AkEAqfb9vJqilVYhMosqbDVOYuEOoZZMz75fNJgrXrnXqHAykonrVijt1WmkGHD//kPGI6SUv5iFQNWTmbuggfUkzwJBAIFpuuwGxMzFNscoFQ4/dV5y96LH+C86hL5jwAq4uh434BabOgr+2aZ1bgpR7A+ue1sVMFU2fXWdL4FGe51W0Jo="; String publicKey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmysS2CWg9u/hp+KM6PcAXjvOGVisMjB5SQQce8+h4uNKVqDsjusgxEOoORnKVmw7KK4iSSJViaLDtNoMhVcprvFECnd/6N8udzMugAYH783pVv0I/T0i6cw5GunH8evtFydd6S/iAiq2ruXyIi36mbEeBNsl55O5EsG6TRs8MWwIDAQAB"; // System.out.println("私钥="+getPrivateKey(map)); //System.out.println("公钥="+getPublicKey(map)); //私钥签名 String signData=sign("这是一个秘密".getBytes(),privateKey); System.out.println("签名后的数据="+signData); //公钥验签 boolean verflag=verify("这是一个秘密".getBytes(),publicKey,signData); System.out.println("验签结果="+verflag); //公钥加密 String message= encryptedDataOnJava("这是另一个秘密",publicKey); System.out.println("公钥加密"+message); // String s = decryptByPublicKey(message, publicKey); // System.out.println("公钥解密"+s); //私钥解密 //String message1=encryptByPrivateKey("这是一个私钥加密",privateKey);//私钥加密 String s1 = decryptDataOnJava(message, privateKey);//私钥解密 System.out.println("私钥解密"+s1); } /** */ /** * <p> * 用私钥对信息生成数字签名 * </p> * * @param data * 已加密数据 * @param privateKey * 私钥(BASE64编码) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); return Base64Utils.encode(signature.sign()); } /** */ /** * <p> * 校验数字签名 * </p> * * @param data * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @param sign * 数字签名 * * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PublicKey publicK = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); return signature.verify(Base64Utils.decode(sign)); } /** */ /** * <P> * 私钥解密 * </p> * * @param encryptedData * 已加密数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** */ /** * <p> * 公钥解密 * </p> * * @param encryptedData * 已加密数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicK); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_DECRYPT_BLOCK) { cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_DECRYPT_BLOCK; } byte[] decryptedData = out.toByteArray(); out.close(); return decryptedData; } /** */ /** * <p> * 公钥加密 * </p> * * @param data * 源数据 * @param publicKey * 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { byte[] keyBytes = Base64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** */ /** * <p> * 私钥加密 * </p> * * @param data * 源数据 * @param privateKey * 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = Base64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateK); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * MAX_ENCRYPT_BLOCK; } byte[] encryptedData = out.toByteArray(); out.close(); return encryptedData; } /** */ /** * <p> * 获取私钥 * </p> * * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return Base64Utils.encode(key.getEncoded()); } /** */ /** * <p> * 获取公钥 * </p> * * @param keyMap * 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return Base64Utils.encode(key.getEncoded()); } public static String encryptByPrivateKey(String data, String privateKey) { try { return Base64Utils.encode(encryptByPrivateKey(data.getBytes(), privateKey)); } catch (Exception e) { logger.error("私钥加密失败", e); throw new RuntimeException(e); } } public static String decryptByPublicKey(String data, String publicKey) { try { return new String(decryptByPublicKey(Base64Utils.decode(data), publicKey), "utf-8"); } catch (Exception e) { logger.error("公钥解密密失败", e); throw new RuntimeException(e); } } /** * java端公钥加密 */ public static String encryptedDataOnJava(String data, String PUBLICKEY) { try { data = Base64Utils.encode(encryptByPublicKey(data.getBytes(), PUBLICKEY)); } catch (Exception e) { System.out.println("公钥加密失败"); } return data; } /** * java端私钥解密 */ public static String decryptDataOnJava(String data, String PRIVATEKEY) { String temp = ""; try { byte[] rs = Base64Utils.decode(data); temp = new String(RsaUtils.decryptByPrivateKey(rs, PRIVATEKEY),"UTF-8"); //以utf-8的方式生成字符串 } catch (Exception e) { e.printStackTrace(); } return temp; } // public static void main(String[] args) throws Exception { // String key = "Ked6XibKqaUVZ7e0zQK3P+55vZNiIFoQl8b0GBuV+mUUCijMT8lXtJ8BCqjlPt4kxgQ9+yDaWbYwGmI9ux9ZoOqdM7EqTNjT5mUbkKFXgnwfW11cIepsZOoZ1gA/wdJYCcojHhTWPdZtRSwhtDB0QhkZw8/kmzeWbR51I0kxdqk="; // String privateKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCOffhtZ452VhXRh25R33xYykddl092QiYdUsnq3Ek6BLYQw+pc7uD/dqcQ2H1/cgznc/wkqp/YbIDeLAa2SffEqzukuGflTc34M928Ee+lTMDqL6E6sXz1bePKtZ/KV8KCdkS/wzMEW937qx+iXMuBUhjQNOFYJHUYKJNO8O9OJQIDAQAB"; // System.out.println(RsaUtils.decryptByPublicKey(key, privateKey)); // } }
demo2
非对称加密已经被评为加密标准,主要包含(公钥加密私钥解密,或者私钥加密公钥解密)本文主要讲解的是如何用java生成 公钥和私钥并且 进行字符串加密 和字符串解密
//如需要代码copy如下
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import sun.applet.resources.MsgAppletViewer;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class KeyRSA1 {
//密钥对生成器
private KeyPairGenerator keyPairGenerator;
//密钥对 里面包含(公钥he 私钥)
private KeyPair keyPair;
//公钥对象
private PublicKey publicKey;
//私钥对象
private PrivateKey privateKey;
//加密解密通用类型
private String keyType = "RSA";
/*** 构造函数
* @param keySize 密钥长度取值范围(512-16384)建议1024或者2048 别整太长降低性能
* @throws Exception*/
public KeyRSA1(int keySize) throws Exception {
// 1创建 keypairGengerator密钥生成器对象
keyPairGenerator = KeyPairGenerator.getInstance(keyType);
// 2指定密钥生成器的长度
keyPairGenerator.initialize(keySize);
// 3创建 keypair 根据密钥生成器获取密钥对 里面包含(公钥和私钥)
keyPair = keyPairGenerator.genKeyPair();
// 4 根据密钥对 创建 公钥
publicKey = keyPair.getPublic();
// 5 根据密钥对 创建 私钥
privateKey = keyPair.getPrivate();
}
// 使用公🔑加密
public String encrypt(String str) throws Exception {
//创建密钥类 keyType 为rsa
Cipher cipher = Cipher.getInstance(keyType);
// 指定密钥类是 加密 注意 CIPHER类ENCRYPT_MODE常量是 加密 publicKey公钥
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//进行公钥加密处理
byte[] bytes = cipher.doFinal(str.getBytes());
BASE64Encoder encoder=new BASE64Encoder();
//返回base64 编码加密之后的字符串
return encoder.encode(bytes);
}
// 使用私🔑解密
public String decrypt(String str) throws Exception {
//创建密钥类 keyType 为rsa
Cipher cipher = Cipher.getInstance(keyType);
//指定密钥是解密类型的 Cipher DECRYPT_MODE 解密privateKey私钥
cipher.init(Cipher.DECRYPT_MODE, privateKey);
BASE64Decoder decoder=new BASE64Decoder();
//进行base64解密
byte[] bytes1=decoder.decodeBuffer(str);
//私钥解密
byte[] bytes = cipher.doFinal(bytes1);
//得到结果是字节数组 把字节数组编程字符串返回解密后的字符串
return new String(bytes);
}
}
//测试类代码copy如下
public static void main(String[] args) {
try {
KeyRSA1 key = new KeyRSA1(1024);
String str = "数据加密内容";
System.out.println("要加密的内容是===" + str);
String encryptResult = key.encrypt(str);
System.out.println("加密后的秘文是===" + encryptResult);
String decryptResult = key.decrypt(encryptResult);
System.out.println("解密后的数据是===" + decryptResult);
} catch (Exception e) {
e.printStackTrace();
}
}