RSA加密解密之後驗籤等操做筆記。留着方便本身方查找。java
package com.xxx.test.utils; 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.ArrayList; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; @SuppressWarnings("unused") public class RSATest { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); byte[] publicKey = key.getEncoded(); return encryptBASE64(key.getEncoded()); } public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); byte[] privateKey = key.getEncoded(); return encryptBASE64(key.getEncoded()); } public static byte[] decryptBASE64(String key) throws Exception { return (new BASE64Decoder()).decodeBuffer(key); } public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); } public static Map<String, Object> initKey() 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; } /** * <p> * 用私鑰對信息生成數字簽名 * </p> * * @param data * 已加密數據 * @param privateKey * 私鑰(BASE64編碼) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(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 (new BASE64Encoder()).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 = (new BASE64Decoder()).decodeBuffer(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((new BASE64Decoder()).decodeBuffer(sign)); } /** * <P> * 私鑰解密 * </p> * * @param encryptedData * 已加密數據 * @param privateKey * 私鑰(BASE64編碼) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(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 = (new BASE64Decoder()).decodeBuffer(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 = (new BASE64Decoder()).decodeBuffer(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 = (new BASE64Decoder()).decodeBuffer(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; } public static void main(String[] args) { Map<String, Object> keyMap; try { keyMap = initKey(); String publicKey = getPublicKey(keyMap); System.out.println("publicKey: "); System.out.println(publicKey); String privateKey = getPrivateKey(keyMap); System.out.println("privateKey: "); System.out.println(privateKey); } catch (Exception e) { e.printStackTrace(); } System.out.println("-----------------------------------------"); Map<String, Object> keyMapA; Map<String, Object> keyMapB; try { keyMapA = initKey(); keyMapB = initKey(); System.out.println(keyMapA.equals(keyMapB)); String ApublicKey = getPublicKey(keyMapA); String BpublicKey = getPublicKey(keyMapB); String AprivateKey = getPrivateKey(keyMapA); String BprivateKey = getPrivateKey(keyMapB); System.out.println("-------------"); System.out.println("ApublicKey:" + ApublicKey); System.out.println("AprivateKey:" + AprivateKey); System.out.println("-------------"); System.out.println("BpublicKey:" + BpublicKey); System.out.println("BprivateKey:" + BprivateKey); System.out.println("----------------------------------------"); String source1 = "這個表要要加密的內容,咱們如今開始處理。"; System.out.println("加密前文字:\n" + source1); byte[] data1 = source1.getBytes(); byte[] encodedData1 = encryptByPublicKey(data1, ApublicKey); System.out.println("加密後文字:\n" + new String(encodedData1)); byte[] decodedData1 = decryptByPrivateKey(encodedData1, AprivateKey); String target1 = new String(decodedData1); System.out.println("解密後文字: \n" + target1); String source2 = "這個表要要加密的內容,咱們如今開始處理,用B的私鑰進行加密,而後得取字符串,發給A,A收到加密字符串後,利用B的公鑰進行解密。"; System.out.println("原文字:\n" + source2); byte[] data2 = source2.getBytes(); byte[] encodedData2 = encryptByPrivateKey(data2, BprivateKey); System.out.println("加密後:\n" + new String(encodedData2)); byte[] decodedData2 = decryptByPublicKey(encodedData2, BpublicKey); String target2 = new String(decodedData2); System.out.println("解密後: \n" + target2); System.out.println("私鑰簽名——公鑰驗證簽名"); String sign2 = sign(encodedData2, BprivateKey); System.out.println("簽名: \n" + sign2); boolean status2 = verify(encodedData2, BpublicKey, sign2); System.out.println("驗證結果: \n" + status2); } catch (Exception e) { e.printStackTrace(); } } }
執行結果以下:web
這個就把RSA的常規使用放在這裏方便之後查找。編碼
這個把Base64換成java8的base64了,以下:加密
package com.imddy.tweb.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.Base64; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; @SuppressWarnings("unused") public class RSATest0 { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); byte[] publicKey = key.getEncoded(); return encryptBASE64(key.getEncoded()); } public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); byte[] privateKey = key.getEncoded(); return encryptBASE64(key.getEncoded()); } public static byte[] decryptBASE64(String key) throws Exception { //return (new BASE64Decoder()).decodeBuffer(key); return Base64.getDecoder().decode(key); } public static String encryptBASE64(byte[] key) throws Exception { //return (new BASE64Encoder()).encodeBuffer(key); return Base64.getEncoder().encodeToString(key); } public static Map<String, Object> initKey() 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; } /** * <p> * 用私鑰對信息生成數字簽名 * </p> * * @param data * 已加密數據 * @param privateKey * 私鑰(BASE64編碼) * * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { //byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(privateKey); byte[] keyBytes = Base64.getDecoder().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 (new BASE64Encoder()).encode(signature.sign()); return Base64.getEncoder().encodeToString(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 = (new BASE64Decoder()).decodeBuffer(publicKey); byte[] keyBytes = Base64.getDecoder().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((new BASE64Decoder()).decodeBuffer(sign)); return signature.verify(Base64.getDecoder().decode(sign)); } /** * <P> * 私鑰解密 * </p> * * @param encryptedData * 已加密數據 * @param privateKey * 私鑰(BASE64編碼) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { //byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(privateKey); byte[] keyBytes = Base64.getDecoder().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 = (new BASE64Decoder()).decodeBuffer(publicKey); byte[] keyBytes = Base64.getDecoder().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 = (new BASE64Decoder()).decodeBuffer(publicKey); byte[] keyBytes = Base64.getDecoder().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 = (new BASE64Decoder()).decodeBuffer(privateKey); byte[] keyBytes = Base64.getDecoder().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; } public static void main(String[] args) { Map<String, Object> keyMap; try { keyMap = initKey(); String publicKey = getPublicKey(keyMap); System.out.println("publicKey: "); System.out.println(publicKey); String privateKey = getPrivateKey(keyMap); System.out.println("privateKey: "); System.out.println(privateKey); } catch (Exception e) { e.printStackTrace(); } System.out.println("-----------------------------------------"); Map<String, Object> keyMapA; Map<String, Object> keyMapB; try { keyMapA = initKey(); keyMapB = initKey(); System.out.println(keyMapA.equals(keyMapB)); String ApublicKey = getPublicKey(keyMapA); String BpublicKey = getPublicKey(keyMapB); String AprivateKey = getPrivateKey(keyMapA); String BprivateKey = getPrivateKey(keyMapB); System.out.println("-------------"); System.out.println("ApublicKey:" + ApublicKey); System.out.println("AprivateKey:" + AprivateKey); System.out.println("-------------"); System.out.println("BpublicKey:" + BpublicKey); System.out.println("BprivateKey:" + BprivateKey); System.out.println("----------------------------------------"); String source1 = "這個表要要加密的內容,咱們如今開始處理。"; System.out.println("加密前文字:\n" + source1); byte[] data1 = source1.getBytes(); byte[] encodedData1 = encryptByPublicKey(data1, ApublicKey); System.out.println("加密後文字:\n" + new String(encodedData1)); byte[] decodedData1 = decryptByPrivateKey(encodedData1, AprivateKey); String target1 = new String(decodedData1); System.out.println("解密後文字: \n" + target1); String source2 = "這個表要要加密的內容,咱們如今開始處理,用B的私鑰進行加密,而後得取字符串,發給A,A收到加密字符串後,利用B的公鑰進行解密。"; System.out.println("原文字:\n" + source2); byte[] data2 = source2.getBytes(); byte[] encodedData2 = encryptByPrivateKey(data2, BprivateKey); System.out.println("加密後:\n" + new String(encodedData2)); byte[] decodedData2 = decryptByPublicKey(encodedData2, BpublicKey); String target2 = new String(decodedData2); System.out.println("解密後: \n" + target2); System.out.println("私鑰簽名——公鑰驗證簽名"); String sign2 = sign(encodedData2, BprivateKey); System.out.println("簽名: \n" + sign2); boolean status2 = verify(encodedData2, BpublicKey, sign2); System.out.println("驗證結果: \n" + status2); } catch (Exception e) { e.printStackTrace(); } } }