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();
        }

    }

 

posted @ 2018-04-21 17:11  郎小乐  阅读(607)  评论(0编辑  收藏  举报