首页 > 学院 > 开发设计 > 正文

用java语言进行RSA加解密

2019-11-14 10:32:38
字体:
来源:转载
供稿:网友

第一种情况:生成密钥对,并进行加解密测试。需要两个类Base64Utils及MyRSA,如下

package rsatest;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.util.Base64;/** * Created by Administrator on 2017/1/13. */public class Base64Utils {    /**     * 文件读取缓冲区大小     */    PRivate static final int CACHE_SIZE = 1024;    /**     * <p>     * BASE64字符串解码为二进制数据     * </p>     *     * @param base64     * @return     * @throws Exception     */    public static byte[] decode(String base64) throws Exception {    	Base64.getDecoder().decode(base64.getBytes());        return Base64.getDecoder().decode(base64.getBytes());    }    /**     * <p>     * 二进制数据编码为BASE64字符串     * </p>     *     * @param bytes     * @return     * @throws Exception     */    public static String encode(byte[] bytes) throws Exception {        return new String(Base64.getEncoder().encode(bytes));    }    /**     * <p>     * 将文件编码为BASE64字符串     * </p>     * <p>     * 大文件慎用,可能会导致内存溢出     * </p>     *     * @param filePath 文件绝对路径     * @return     * @throws Exception     */    public static String encodeFile(String filePath) throws Exception {        byte[] bytes = fileToByte(filePath);        return encode(bytes);    }    /**     * <p>     * BASE64字符串转回文件     * </p>     *     * @param filePath 文件绝对路径     * @param base64   编码字符串     * @throws Exception     */    public static void decodeToFile(String filePath, String base64) throws Exception {        byte[] bytes = decode(base64);        byteArrayToFile(bytes, filePath);    }    /**     * <p>     * 文件转换为二进制数组     * </p>     *     * @param filePath 文件路径     * @return     * @throws Exception     */    public static byte[] fileToByte(String filePath) throws Exception {        byte[] data = new byte[0];        File file = new File(filePath);        if (file.exists()) {            FileInputStream in = new FileInputStream(file);            ByteArrayOutputStream out = new ByteArrayOutputStream(2048);            byte[] cache = new byte[CACHE_SIZE];            int nRead = 0;            while ((nRead = in.read(cache)) != -1) {                out.write(cache, 0, nRead);                out.flush();            }            out.close();            in.close();            data = out.toByteArray();        }        return data;    }    /**     * <p>     * 二进制数据写文件     * </p>     *     * @param bytes    二进制数据     * @param filePath 文件生成目录     */    public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {        InputStream in = new ByteArrayInputStream(bytes);        File destFile = new File(filePath);        if (!destFile.getParentFile().exists()) {            destFile.getParentFile().mkdirs();        }        destFile.createNewFile();        OutputStream out = new FileOutputStream(destFile);        byte[] cache = new byte[CACHE_SIZE];        int nRead = 0;        while ((nRead = in.read(cache)) != -1) {            out.write(cache, 0, nRead);            out.flush();        }        out.close();        in.close();    }}
package rsatest;import java.security.InvalidKeyException;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;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;import java.util.Base64;import java.util.HashMap;import java.util.Map;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;public class MyRSA {	public static final String KEY_ALGORITHM = "RSA";		public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";	public static final String PUBLIC_KEY = "publicKey";	public static final String PRIVATE_KEY = "privateKey";	/** RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024 */	public static final int KEY_SIZE = 2048;	public static final String PLAIN_TEXT = "你好,2017";		public static void main(String[] args) throws Exception {		//生成密钥对		Map<String, byte[]> keyMap = generateKeyBytes();	    		PublicKey publicKey = restorePublicKey(keyMap.get(PUBLIC_KEY));		PrivateKey privateKey = restorePrivateKey(keyMap.get(PRIVATE_KEY));		// 用公钥加密		byte[] encodedText = RSAEncode(publicKey, PLAIN_TEXT.getBytes());				System.out.println("加密结果: " + Base64Utils.encode(encodedText));				//用私钥解密		System.out.println("解密结果: " + RSADecode(privateKey, encodedText));	}	/**	 * 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥	 *	 * @return	 */	public static Map<String, byte[]> generateKeyBytes() {		try {			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);			keyPairGenerator.initialize(KEY_SIZE);			KeyPair keyPair = keyPairGenerator.generateKeyPair();			RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();			Map<String, byte[]> keyMap = new HashMap<String, byte[]>();			keyMap.put(PUBLIC_KEY, publicKey.getEncoded());			keyMap.put(PRIVATE_KEY, privateKey.getEncoded());			return keyMap;		} catch (NoSuchAlgorithmException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 还原公钥,X509EncodedKeySpec 用于构建公钥的规范	 *	 * @param keyBytes	 * @return	 */	public static PublicKey restorePublicKey(byte[] keyBytes) {		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);		try {			KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);			PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);			return publicKey;		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范	 *	 * @param keyBytes	 * @return	 */	public static PrivateKey restorePrivateKey(byte[] keyBytes) {		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);		try {			KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);			PrivateKey privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);			return privateKey;		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 加密,三步走。	 *	 * @param key	 * @param plainText	 * @return	 */	public static byte[] RSAEncode(PublicKey key, byte[] plainText) {		try {			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);			cipher.init(Cipher.ENCRYPT_MODE, key);			return cipher.doFinal(plainText);		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException				| BadPaddingException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 	 *	 * @param key	 * @param encodedText	 * @return	 */	public static String RSADecode(PrivateKey key, byte[] encodedText) {		try {			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);			cipher.init(Cipher.DECRYPT_MODE, key);			return new String(cipher.doFinal(encodedText));		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException				| BadPaddingException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}}通过上面两个类可以进行测试。

第二种情况:在平时开发中,往往是用只需要用公钥加密或者是用私钥解密,公私钥和密文是String类型的,下面测试一下用私钥来解密一串密文。

package rsatest;import java.security.InvalidKeyException;import java.security.Key;import java.security.KeyFactory;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;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;import java.util.Base64;import java.util.HashMap;import java.util.Map;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;public class MyRSA {	public static final String KEY_ALGORITHM = "RSA";	public static final String CIPHER_ALGORITHM = "RSA/ECB/PKCS1Padding";	public static final String PUBLIC_KEY = "publicKey";	public static final String PRIVATE_KEY = "privateKey";	/** RSA密钥长度必须是64的倍数,在512~65536之间。默认是1024 */	public static final int KEY_SIZE = 2048;	public static final String PLAIN_TEXT = "你好,2017";		    //以下是一对RSA公私钥,result是一串用公钥加密后的密文	private static String private_key_string = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC/"			+ "TFxb6tApaTQ+N6du3T+F0/NcPw0aR5YeGqUxL6p4wcx7WbKWmSqcCeWmtlqzidp5mPUp107coeSt45"			+ "TKYBAhDOh8D3CshoZiagrlL4lyPTZPM4UUSmt3jrVLI+NAjDwoCZE/EI6FBL4ATXAUqBjVA4Y2QmBF"			+ "sAtkTNbN67CYTDn4p6T47Cvi1zLhk0UZOrUSVAHnJqfT/xo6utyQWpUHhbVRSxTTcfSxf6CYnmYt0e"			+ "AE+tto5NTZt3LaNxokUKyhsTGt8vnQnfqhj0uPgOMAyWE9jHnD/rIkPEEIjdzG6kUgamffjjNC7+KR"			+ "sdc9Pdf8i0fEDkXwaXgzA3KVz3/5AgMBAAECggEBAK61AYCc0eGQCDtuPoa8n0AM0ywDFWdTy6DQut9"			+ "R5gGFFMfuonBxj/2T+F2qGunvU01MSVMeJRLQ8/VvbDrrQQ+8hzKOM1wNO/vzVuH66S8hAlGQ/tAKK"			+ "120QpROQUR5DpOOMU2ERHTtYM0L6/mhj5QzNManFh9u6OiAWIkV4GElX6QBlaIDHInjt5Fnlf6QOiZ"			+ "ZpJQdCsftgTZe8oNUf4TdeUIkez1RcOqMSo8WkaQFScMI6QgLTt4DJtdc+G5ZaVfB1egziBl2ApRbO"			+ "WdGgGPIR/fNy/11oMvMHCCr16ewYKyxjxFn2iHtTC5gbuzIXTuSJn2D/mlQCmHxdMoT2VECgYEA67D"			+ "9al4FjIUGfhVK6orpGXaezr6Xt7Nwy+OeTrX6tqpj8krC7jSjNz2iFZMZmbB5C+Tr7h2AnZNLj4H7V"			+ "E/IidyFksjlGxLVE3ZYeNaj2o3HslTcDKaEvyI+CO9a0vRj9d9aF33Ym828JL0CiLVaIB8iuvdXItF"			+ "S3Ni9KagXpHUCgYEAz8gfsH9uCwxB7uPALAdMAYnoP3TN618BWQm3RZS2atP2vvw5m6XvRnmsQc3C5"			+ "lr0a1VycWg8LqWO0w0CaspsnsBH5fjhkx3+koxWDTW/d25wo0MMlR5BpekQ9SdK7doRw62BZxoeavs"			+ "Q/lgpYA2pCSTNBi+999XdrND4ZjHfLPUCgYApKdI4n48siZcmsiVRbU1kyxjVVug8hzRuB6UAbjwJZ"			+ "xzpljERVVQkM7l5NyXDd9TMRQEHp1NtMeqCd9sjUIPfwAn8JuYMom9gZMzy3dnkM9rqxHNiKjsI/rw"			+ "C53rfWRuUN5wOekY4f+gaKoCky7ef4JA6QzSOuixUse3ntpnaeQKBgFVbpkEQqHlbaL6ly22K9dtv9"			+ "vwSlQGLfvc/+Y1ZIXNTbntZDKV3jouKMoy55cZSOTTa3m/eXVLgaoMjRd8y88LnxOGh07FnUgyMIFG"			+ "+8dAzi4xWYBXmXxu0WmYL5Uk/G6siXRWo8jQKvhluyFiQZA/AkYVoGYd10WJMWq9I76D9AoGBAOKfB"			+ "WmhYsfj3WikP3eDLJ0P7/xqivWCubaPaaUcoBv4ARNePUNJ9B3VZjs6sh0voxJH5cTTWqNbKZaLYMq"			+ "ZVn6tF9/0qIXIWtUsxLDzWGgf31304rplouFsapjforNQ45yHSaHfVRrUo4MUw77nV5X3Y0iUbVaHg" 			+ "F9Cer0IIoWc";	private static String public_key_string = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv0xcW+rQK"			+ "Wk0Pjenbt0/hdPzXD8NGkeWHhqlMS+qeMHMe1mylpkqnAnlprZas4naeZj1KddO3KHkreOUymAQIQzof"			+ "A9wrIaGYmoK5S+Jcj02TzOFFEprd461SyPjQIw8KAmRPxCOhQS+AE1wFKgY1QOGNkJgRbALZEzWzeuwm"			+ "Ew5+Kek+Owr4tcy4ZNFGTq1ElQB5yan0/8aOrrckFqVB4W1UUsU03H0sX+gmJ5mLdHgBPrbaOTU2bdy2"			+ "jcaJFCsobExrfL50J36oY9Lj4DjAMlhPYx5w/6yJDxBCI3cxupFIGpn344zQu/ikbHXPT3X/ItHxA5F"			+ "8Gl4MwNylc9/+QIDAQAB";	private static String result = "vszajgjdXNoK+bCr0khX0XXdXH4+SG4yksn2huNIOXGh1xQ9nxo9tyv2mJuBtoTeE9CW"			+ "0W/btNJ6clb7HAKRzlwsAOhHW1CzdMV6HIyGPR9IFyh3dJS0nUIPlUjyNWl6OL7v+zLGpXsfG/9Fqg4C"			+ "AlAtn+uM+sjcl+STzmeKg2IU4SqQdeFzPKZk3e36z3WIyDIWG6ef4wqZxW7yZKWUwtNMMIMMEc37umHW"			+ "4Oxwjkld/EVctOTITUuZ3OHyybiSXyk+scGh/LNCFI07zqCGgrc6JPaSeKKjAemsC10ShDO4l4nUSKsF"			+ "FQPC14nUqfh1d/qx3y15YPTQwM2BnAx8ZQ==";	public static void main(String[] args) throws Exception {				String str=decryptByPrivateKey(private_key_string, result);				System.out.println("---解密出来的明文是---="+str);	}	/**	 * 生成密钥对。注意这里是生成密钥对KeyPair,再由密钥对获取公私钥	 *	 * @return	 */	public static Map<String, byte[]> generateKeyBytes() {		try {			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);			keyPairGenerator.initialize(KEY_SIZE);			KeyPair keyPair = keyPairGenerator.generateKeyPair();			RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();			Map<String, byte[]> keyMap = new HashMap<String, byte[]>();			keyMap.put(PUBLIC_KEY, publicKey.getEncoded());			keyMap.put(PRIVATE_KEY, privateKey.getEncoded());			return keyMap;		} catch (NoSuchAlgorithmException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 还原公钥,X509EncodedKeySpec 用于构建公钥的规范	 *	 * @param keyBytes	 * @return	 */	public static PublicKey restorePublicKey(byte[] keyBytes) {		X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);		try {			KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);			PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);			return publicKey;		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 还原私钥,PKCS8EncodedKeySpec 用于构建私钥的规范	 *	 * @param keyBytes	 * @return	 */	public static PrivateKey restorePrivateKey(byte[] keyBytes) {		PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);		try {			KeyFactory factory = KeyFactory.getInstance(KEY_ALGORITHM);			PrivateKey privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);			return privateKey;		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 加密,三步走。	 *	 * @param key	 * @param plainText	 * @return	 */	public static byte[] RSAEncode(PublicKey key, byte[] plainText) {		try {			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);			cipher.init(Cipher.ENCRYPT_MODE, key);			return cipher.doFinal(plainText);		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException				| BadPaddingException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 	 *	 * @param key	 * @param encodedText	 * @return	 */	public static String RSADecode(PrivateKey key, byte[] encodedText) {		try {			Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);			cipher.init(Cipher.DECRYPT_MODE, key);			return new String(cipher.doFinal(encodedText));		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException				| BadPaddingException e) {			// TODO Auto-generated catch block			e.printStackTrace();		}		return null;	}	/**	 * 解密	 * 	 * @param cipherText	 *            密文	 * @param privateKey	 *            私钥	 * @throws Exception	 *             异常	 */	private static String decryptByPrivateKey(String privateKey, String cipherText) {		byte[] keyBytes = new byte[0];		try {			keyBytes = Base64Utils.decode(privateKey);			PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);			KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);			PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);				return RSADecode(privateK, Base64Utils.decode(cipherText));		} catch (Exception e) {			e.printStackTrace();						return "";					}	}}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表