第一种情况:生成密钥对,并进行加解密测试。需要两个类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 ""; } }}
新闻热点
疑难解答