• JAVA实现RSA加密解密 非对称算法


    首先RSA是一个非对称的加密算法。所以在使用该算法加密解密之前,必须先行生成密钥对。包含公钥和私钥

    JDK中提供了生成密钥对的类KeyPairGenerator,实比例如以下:

    public static Map<String, Object> genKeyPair() throws Exception {
    		// 获取公钥私钥密钥对的生成器
    		KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    		// 初始化确定密钥大小的密钥生成器
    		kpg.initialize(1024);
    		// 生成密钥对
    		KeyPair kp = kpg.generateKeyPair();
    		RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
    		RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
    		Map<String, Object> keyMap = new HashMap<String, Object>();
    		keyMap.put(PUBLIC_KEY, publicKey);
    		keyMap.put(PRIVATE_KEY, privateKey);
    		return keyMap;
    	}
    以上这段代码返回的是一个Map类型的数据。当中存储了公钥和私钥

    当你完毕了密钥对的生成之后,你就能够将公钥公开出去了。让相关的加密程序通过该公钥对实施RSA加密


    public static byte[] encryptByPublicKey(byte[] data, String publicKey)
                throws Exception {
            //data即是待加密的数据String.getBytes就可以
            byte[] keyBytes = Base64Utils.decode(publicKey);
            //依据指定的编码密钥创建一个新的X509EncodedKeySpec
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_ALGORITHM);
            //依据提供的密钥规范生成公钥对象
            Key publicK = keyFactory.generatePublic(x509KeySpec);
            // 对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //用密钥初始化加密模式的cipher。全部后面的doFinal方法做的是加密
            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;
        }
    

    加密完毕之后通过自己的私钥对密文进行解密

    public static byte[] decryptByPrivateKey(byte[] data, String privateKey)
    			throws Exception {
    		byte[] keyBytes = Base64Utils.decode(privateKey);
    		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    		KeyFactory keyFactory = KeyFactory.getInstance(ENCRYPT_ALGORITHM);
    		Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
    		Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
    		cipher.init(Cipher.DECRYPT_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_DECRYPT_BLOCK) {
    				cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
    			} else {
    				cache = cipher.doFinal(data, offSet, inputLen - offSet);
    			}
    			out.write(cache, 0, cache.length);
    			i++;
    			offSet = i * MAX_DECRYPT_BLOCK;
    		}
    		byte[] decryptedData = out.toByteArray();
    		out.close();
    		return decryptedData;
    	}
    生成密钥对:

    try {
    			Map<String, Object> keyMap = RSAUtils.genKeyPair();
    			publicKey = RSAUtils.getPublicKey(keyMap);
    			privateKey = RSAUtils.getPrivateKey(keyMap);
    			System.out.println("公钥-->" + publicKey);
    			System.out.println("私钥-->" + privateKey);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}

    执行结果展示:

    公钥-->MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjJOdVRlDN/5nWHmpFtc9XffgmT2SAj7b+yBk55HSr1iQQt5k8/4O5qdnk3qxhgIgWuSyDpxR2FK5dzfXsomjc0L2CZGaStAkbbvw1wbOSYo11cxNpkphn3PIVbuBxrpEuCJ4HrMKTuBk662aA0ysxy2/BrK4NXxtRlMxI+/BYsQIDAQAB
    私钥-->MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKMk51VGUM3/mdYeakW1z1d9+CZPZICPtv7IGTnkdKvWJBC3mTz/g7mp2eTerGGAiBa5LIOnFHYUrl3N9eyiaNzQvYJkZpK0CRtu/DXBs5JijXVzE2mSmGfc8hVu4HGukS4IngeswpO4GTrrZoDTKzHLb8Gsrg1fG1GUzEj78FixAgMBAAECgYBoQPTzsXOBsI0GH3maAoz1RDKHiMSYwz4Vopk8PZmxFa8GX801BbOPudLcRs+xnwlYPA0ONH8G1kB3AV7eUQrgxjHzqk61ahfbZ7w2yJl326Uag+q7SZI3bxoLKeqhCSD6GggvS9pSEgxu9u21GABxrYSGeRQe42sLLNpG8YKmAQJBAPv8j8MBMip+MhNYKMvPlmzA0/nUzLBLgZraHT0UMupEy6BHIYQnwXaabChs3QLrCMRt7payIK9CjO53oJPrrVkCQQClvhmgvursiUOiAzjkxgE11IPhw6FOx4nf/Om+jNnDEEO6VV//LNqwadKas1f7JwO6VyIsqJitPj9kuGTZm2MZAkBa5QeWd9/4o/y8LZjJq9++6u+Lts7+6L2fdf4GAjs7dgVdk0rruMt4VMue6WXvn4hSErV1dluD3KWpf01VDjZBAkEAjwWpBc5Z2L1mUGLpcHjwyGvXVjVDeEC12ERdzCGtNCdP2nYbvY4ONJdMtlQ2grKbA+x2wATIow6JE7gOxrzQ2QJBAJCWGti2LP9ftl2X5XhZ0VK+DOGIrdBzXs/g/zkKNh393VEJvB7qloK03aY4R4Vw4ssCUsf3YAShMQUpjoDFqEg=

    利用公钥加密。私钥解密:

    System.out.println("公钥加密——私钥解密");
    		System.out.println("加密前数据的内容是-->" + sourceStr);
    		byte[] data = sourceStr.getBytes();
    		byte[] encryptData = RSAUtils.encryptByPublicKey(data, publicKey);
    		System.out.println("加密后的数据内容是-->" + new String(encryptData));
    		byte[] decryptData = RSAUtils.decryptByPrivateKey(encryptData,
    				privateKey);
    		System.out.println("解密后的数据内容是-->" + new String(decryptData));

    公钥加密——私钥解密
    加密前数据的内容是-->这是一段待加密的数据
    加密后的数据内容是-->(���%5    [�͖W��uA- ��m�u�&w�2��gQ���-5�Q���`7:Й�C,�8t�qM�gJ��e2"�)y��͓�����    �Y��@�y*_�M�����x*;�f1���v֚�@�h�}P?X�2
    解密后的数据内容是-->这是一段待加密的数据

    附Base64Utils.java

    package rsa;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    
    public class Base64Utils {
    	private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    
    	/**
    	 * data[]进行编码
    	 * 
    	 * @param data
    	 * @return
    	 */
    	public static String encode(byte[] data) {
    		int start = 0;
    		int len = data.length;
    		StringBuffer buf = new StringBuffer(data.length * 3 / 2);
    
    		int end = len - 3;
    		int i = start;
    		int n = 0;
    
    		while (i <= end) {
    			int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff);
    
    			buf.append(legalChars[(d >> 18) & 63]);
    			buf.append(legalChars[(d >> 12) & 63]);
    			buf.append(legalChars[(d >> 6) & 63]);
    			buf.append(legalChars[d & 63]);
    
    			i += 3;
    
    			if (n++ >= 14) {
    				n = 0;
    				buf.append(" ");
    			}
    		}
    
    		if (i == start + len - 2) {
    			int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);
    
    			buf.append(legalChars[(d >> 18) & 63]);
    			buf.append(legalChars[(d >> 12) & 63]);
    			buf.append(legalChars[(d >> 6) & 63]);
    			buf.append("=");
    		} else if (i == start + len - 1) {
    			int d = (((int) data[i]) & 0x0ff) << 16;
    
    			buf.append(legalChars[(d >> 18) & 63]);
    			buf.append(legalChars[(d >> 12) & 63]);
    			buf.append("==");
    		}
    
    		return buf.toString();
    	}
    
    	private static int decode(char c) {
    		if (c >= 'A' && c <= 'Z')
    			return ((int) c) - 65;
    		else if (c >= 'a' && c <= 'z')
    			return ((int) c) - 97 + 26;
    		else if (c >= '0' && c <= '9')
    			return ((int) c) - 48 + 26 + 26;
    		else
    			switch (c) {
    			case '+':
    				return 62;
    			case '/':
    				return 63;
    			case '=':
    				return 0;
    			default:
    				throw new RuntimeException("unexpected code: " + c);
    			}
    	}
    
    	/**
    	 * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned.
    	 */
    
    	public static byte[] decode(String s) {
    
    		ByteArrayOutputStream bos = new ByteArrayOutputStream();
    		try {
    			decode(s, bos);
    		} catch (IOException e) {
    			throw new RuntimeException();
    		}
    		byte[] decodedBytes = bos.toByteArray();
    		try {
    			bos.close();
    			bos = null;
    		} catch (IOException ex) {
    			System.err.println("Error while decoding BASE64: " + ex.toString());
    		}
    		return decodedBytes;
    	}
    
    	private static void decode(String s, OutputStream os) throws IOException {
    		int i = 0;
    
    		int len = s.length();
    
    		while (true) {
    			while (i < len && s.charAt(i) <= ' ')
    				i++;
    
    			if (i == len)
    				break;
    
    			int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3)));
    
    			os.write((tri >> 16) & 255);
    			if (s.charAt(i + 2) == '=')
    				break;
    			os.write((tri >> 8) & 255);
    			if (s.charAt(i + 3) == '=')
    				break;
    			os.write(tri & 255);
    
    			i += 4;
    		}
    	}
    	
    	/**
    	 * data[]进行编码
    	 * 
    	 * @param data
    	 * @return
    	 */
    	public static String Base64Encoder(byte[] data) {
    		int start = 0;
    		int len = data.length;
    		StringBuffer buf = new StringBuffer(data.length * 3 / 2);
    
    		int end = len - 3;
    		int i = start;
    		int n = 0;
    
    		while (i <= end) {
    			int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff);
    
    			buf.append(legalChars[(d >> 18) & 63]);
    			buf.append(legalChars[(d >> 12) & 63]);
    			buf.append(legalChars[(d >> 6) & 63]);
    			buf.append(legalChars[d & 63]);
    
    			i += 3;
    
    			if (n++ >= 14) {
    				//不须要空格
    				n = 0;
    			}
    		}
    
    		if (i == start + len - 2) {
    			int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);
    
    			buf.append(legalChars[(d >> 18) & 63]);
    			buf.append(legalChars[(d >> 12) & 63]);
    			buf.append(legalChars[(d >> 6) & 63]);
    			buf.append("=");
    		} else if (i == start + len - 1) {
    			int d = (((int) data[i]) & 0x0ff) << 16;
    
    			buf.append(legalChars[(d >> 18) & 63]);
    			buf.append(legalChars[(d >> 12) & 63]);
    			buf.append("==");
    		}
    
    		return buf.toString();
    	}
    	
    }
    


  • 相关阅读:
    setHapticFeedbackEnabled在androi的作用
    Android 跑马灯
    jQuery中绑定事件的命名空间详解
    可见即所得的CSS编辑设计
    盘点8种CSS实现垂直居中水平居中的绝对定位居中技术
    用到的知识点
    用PS去除图片中文字的6个方法
    html页面头部里的meta
    px pt em对应关系
    phpMyAdmin安装与配置(涉及LAMP配置)
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6903085.html
Copyright © 2020-2023  润新知