RSA 加密-重写base64 适用于反射
来源:互联网 发布:c# socket接收数据 编辑:程序博客网 时间:2024/06/07 12:31
package com.pingan.haofang.connector.common.secretutil;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;/** * @Title: RSAUtil不对称加解密工具类 * @Description: 处理数据传输加密问题 * @Team: 新金融业务研发团队 * @Author wangcs * @Date 2017年05月27日 * @Version V1.0 */public class RSAUtils { /** * 加密算法RSA */ public static final String KEY_ALGORITHM = "RSA"; /** * 签名算法 */ public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; /** * 获取公钥的key */ private static final String PUBLIC_KEY = "RSAPingAnKey1"; /** * 获取私钥的key */ private static final String PRIVATE_KEY = "RSAHaoFangKey1"; /** * RSA最大加密明文大小 */ private static final int MAX_ENCRYPT_BLOCK = 117; /** * RSA最大解密密文大小 */ private static final int MAX_DECRYPT_BLOCK = 128; /** * 生成密钥对(公钥和私钥) * @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; } /** * 用私钥对信息生成数字签名 * @param data 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { byte[] keyBytes = RsaBase64Utils.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 RsaBase64Utils.encode(signature.sign()); } /** * 校验数字签名 * @param data 已加密数据 * @param publicKey 公钥(BASE64编码) * @param sign 数字签名 * @return * @throws Exception * */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { byte[] keyBytes = RsaBase64Utils.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(RsaBase64Utils.decode(sign)); } /** * 私钥解密 * @param encryptedData 已加密数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception { byte[] keyBytes = RsaBase64Utils.decode(privateKey); PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//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; } /** * 公钥解密 * @param encryptedData 已加密数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception { byte[] keyBytes = RsaBase64Utils.decode(publicKey); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicK = keyFactory.generatePublic(x509KeySpec); Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 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; } /** * 公钥加密 * @param data 源数据 * @param publicKey 公钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPublicKey(String source, String publicKey)throws Exception { byte[] keyBytes = RsaBase64Utils.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); byte[] data = source.getBytes(); 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; } /** * 私钥加密 * @param data 源数据 * @param privateKey 私钥(BASE64编码) * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception { byte[] keyBytes = RsaBase64Utils.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; } /** * 获取私钥 * @param keyMap 密钥对 * @return * @throws Exception */ public static String getPrivateKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return RsaBase64Utils.encode(key.getEncoded()); } /** * 获取公钥 * @param keyMap 密钥对 * @return * @throws Exception */ public static String getPublicKey(Map<String, Object> keyMap) throws Exception { Key key = (Key) keyMap.get(PUBLIC_KEY); return RsaBase64Utils.encode(key.getEncoded()); }}
package com.pingan.haofang.connector.common.secretutil;import java.util.Map;public class RSATester { static String publicKey; static String privateKey; static { try { Map<String, Object> keyMap = RSAUtils.genKeyPair(); publicKey = RSAUtils.getPublicKey(keyMap); privateKey = RSAUtils.getPrivateKey(keyMap); System.err.println("公钥: \n\r" + publicKey); System.err.println("私钥: \n\r" + privateKey); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { test(); ///testSign(); } static void test() throws Exception { System.err.println("公钥加密——私钥解密"); String source = "23452345sr这是一行没有任何意义的文字,你看完了等于没看,不是吗fgsdfgaet WEDasDsdgaaw?"; System.out.println("\r加密前文字:\r\n" + source); byte[] encodedData = RSAUtils.encryptByPublicKey(source, publicKey); System.out.println("加密后文字:\r\n" + new String(encodedData)); byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, privateKey); String target = new String(decodedData); System.out.println("解密后文字: \r\n" + target); }/* static void testSign() throws Exception { System.err.println("私钥加密——公钥解密"); String source = "这是一行测试RSA数字签名的无意义文字"; System.out.println("原文字:\r\n" + source); byte[] data = source.getBytes(); byte[] encodedData = RSAUtils.encryptByPrivateKey(data, privateKey); System.out.println("加密后:\r\n" + new String(encodedData)); byte[] decodedData = RSAUtils.decryptByPublicKey(encodedData, publicKey); String target = new String(decodedData); System.out.println("解密后: \r\n" + target); System.err.println("私钥签名——公钥验证签名"); String sign = RSAUtils.sign(encodedData, privateKey); System.err.println("签名:\r" + sign); boolean status = RSAUtils.verify(encodedData, publicKey, sign); System.err.println("验证结果:\r" + status); }*/}
package com.pingan.haofang.connector.common.secretutil; 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 com.pingan.haofang.connector.common.creditutils.Base64PYZX; /** * @Title: BASE64编码解码工具包 * @Description: 依赖javabase64-1.3.1.jar * @Team: 新金融业务研发团队 * @Author wangcs * @Date 2017年05月27日 * @Version V1.0 */public class RsaBase64Utils { /** * 文件读取缓冲区大小 */ private final int CACHE_SIZE = 1024; /** * BASE64字符串解码为二进制数据 * @param base64 * @return * @throws Exception */ public static byte[] decode(String base64) throws Exception { return new Base64PYZX().decode(base64); } /** * 二进制数据编码为BASE64字符串 * @param bytes * @return * @throws Exception */ public static String encode(byte[] bytes) throws Exception { return new String(new Base64PYZX().encode(bytes)); } /** * 将文件编码为BASE64字符串 * 大文件慎用,可能会导致内存溢出 * @param filePath 文件绝对路径 * @return * @throws Exception */ public String encodeFile(String filePath) throws Exception { byte[] bytes = fileToByte(filePath); return encode(bytes); } /** * BASE64字符串转回文件 * @param filePath 文件绝对路径 * @param base64 编码字符串 * @throws Exception */ public void decodeToFile(String filePath, String base64) throws Exception { byte[] bytes = decode(base64); byteArrayToFile(bytes, filePath); } /** * 文件转换为二进制数组 * @param filePath 文件路径 * @return * @throws Exception */ public 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; } /** * 二进制数据写文件 * @param bytes 二进制数据 * @param filePath 文件生成目录 */ public 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 com.pingan.haofang.connector.common.creditutils;/** * <p>Title: 深圳市个人信用征信系统</p> * <p>Description: Base64编码,提供二进制流与字符串之间的转换</p> * <p>Copyright: Copyright (c) 2005 Sino-Hawk Credit Rating Corpration. All rights reserved.</p> * @version 2.0 */public class Base64PYZX{/** * how we separate lines, e.g. \n, \r\n, \r etc. */private String lineSeparator = System.getProperty("line.separator");/** * max chars per line, excluding lineSeparator. A multiple of 4. */private int lineLength = 72;/* constructor */public Base64PYZX (){}/** * Encode an arbitrary array of bytes as Base64 printable ASCII. * It will be broken into lines of 72 chars each. The last line is not * terminated with a line separator. * The output will always have an even multiple of data characters, * exclusive of \n. It is padded out with =. */public String encode (byte[] b){// Each group or partial group of 3 bytes becomes four chars// covered quotientint outputLength = ((b.length + 2) / 3) * 4;// account for trailing newlines, on all but the very last lineif (lineLength != 0){int lines = (outputLength + lineLength - 1) / lineLength - 1;if (lines > 0){outputLength += lines * lineSeparator.length();}}// must be local for recursion to work.StringBuffer sb = new StringBuffer(outputLength);// must be local for recursion to work.int linePos = 0;// first deal with even multiples of 3 bytes.int len = (b.length / 3) * 3;int leftover = b.length - len;for (int i = 0;i < len;i += 3){// Start a new line if next 4 chars won't fit on the current line// We can't encapsulete the following code since the variable need to// be local to this incarnation of encode.linePos += 4;if (linePos > lineLength){if (lineLength != 0){sb.append(lineSeparator);}linePos = 4;}// get next three bytes in unsigned form lined up,// in big-endian orderint combined = b[i + 0] & 0xff;combined <<= 8;combined |= b[i + 1] & 0xff;combined <<= 8;combined |= b[i + 2] & 0xff;// break those 24 bits into a 4 groups of 6 bits,// working LSB to MSB.int c3 = combined & 0x3f;combined >>>= 6;int c2 = combined & 0x3f;combined >>>= 6;int c1 = combined & 0x3f;combined >>>= 6;int c0 = combined & 0x3f;// Translate into the equivalent alpha character// emitting them in big-endian order.sb.append(valueToChar[c0]);sb.append(valueToChar[c1]);sb.append(valueToChar[c2]);sb.append(valueToChar[c3]);}// deal with leftover bytesswitch (leftover){case 0:default:// nothing to dobreak;case 1:// One leftover byte generates xx==// Start a new line if next 4 chars won't fit on the current linelinePos += 4;if (linePos > lineLength){if (lineLength != 0){sb.append(lineSeparator);}linePos = 4;}// Handle this recursively with a faked complete triple.// Throw away last two chars and replace with ==sb.append(encode(new byte[]{b[len],0,0}).substring(0,2));sb.append("==");break;case 2:// Two leftover bytes generates xxx=// Start a new line if next 4 chars won't fit on the current linelinePos += 4;if (linePos > lineLength){if (lineLength != 0){sb.append(lineSeparator);}linePos = 4;}// Handle this recursively with a faked complete triple.// Throw away last char and replace with =sb.append(encode(new byte[]{b[len],b[len + 1],0}).substring(0,3));sb.append("=");break;} // end switch;if (outputLength != sb.length()){System.out.println("oops: minor program flaw: output length mis-estimated");System.out.println("estimate:" + outputLength);System.out.println("actual:" + sb.length());}return sb.toString();} // end encode/** * decode a well-formed complete Base64 string back into an array of bytes. * It must have an even multiple of 4 data characters (not counting \n), * padded out with = as needed. */public byte[] decode (String s){// estimate worst case size of output array, no embedded newlines.byte[] b = new byte[(s.length() / 4) * 3];// tracks where we are in a cycle of 4 input chars.int cycle = 0;// where we combine 4 groups of 6 bits and take apart as 3 groups of 8.int combined = 0;// how many bytes we have prepared.int j = 0;// will be an even multiple of 4 chars, plus some embedded \nint len = s.length();int dummies = 0;for (int i = 0;i < len;i++){int c = s.charAt(i);int value = (c <= 255) ? charToValue[c] : IGNORE;// there are two magic values PAD (=) and IGNORE.switch (value){case IGNORE:// e.g. \n, just ignore it.break;case PAD:value = 0;dummies++;// fallthroughdefault:/* regular value character */switch (cycle){case 0:combined = value;cycle = 1;break;case 1:combined <<= 6;combined |= value;cycle = 2;break;case 2:combined <<= 6;combined |= value;cycle = 3;break;case 3:combined <<= 6;combined |= value;// we have just completed a cycle of 4 chars.// the four 6-bit values are in combined in big-endian order// peel them off 8 bits at a time working lsb to msb// to get our original 3 8-bit bytes backb[j + 2] = (byte)combined;combined >>>= 8;b[j + 1] = (byte)combined;combined >>>= 8;b[j] = (byte)combined;j += 3;cycle = 0;break;}break;}} // end forif (cycle != 0){throw new ArrayIndexOutOfBoundsException("Input to decode not an even multiple of 4 characters; pad with =.");}j -= dummies;if (b.length != j){byte[] b2 = new byte[j];System.arraycopy(b,0,b2,0,j);b = b2;}return b;} // end decode/** * determines how long the lines are that are generated by encode. * Ignored by decode. * @param length 0 means no newlines inserted. Must be a multiple of 4. */public void setLineLength (int length){this.lineLength = (length / 4) * 4;}/** * How lines are separated. * Ignored by decode. * @param lineSeparator may be "" but not null. * Usually contains only a combination of chars \n and \r. * Could be any chars not in set A-Z a-z 0-9 + /. */public void setLineSeparator (String lineSeparator){this.lineSeparator = lineSeparator;}/** * letter of the alphabet used to encode binary values 0..63 */static final char[] valueToChar = new char[64];/** * binary value encoded by a given letter of the alphabet 0..63 */static final int[] charToValue = new int[256];/** * Marker value for chars we just ignore, e.g. \n \r high ascii */static final int IGNORE = -1;/** * Marker for = trailing pad */static final int PAD = -2;static/* initialise valueToChar and charToValue tables */{// build translate valueToChar table only once.// 0..25 -> 'A'..'Z'for (int i = 0;i <= 25;i++){valueToChar[i] = (char)('A' + i);// 26..51 -> 'a'..'z'}for (int i = 0;i <= 25;i++){valueToChar[i + 26] = (char)('a' + i);// 52..61 -> '0'..'9'}for (int i = 0;i <= 9;i++){valueToChar[i + 52] = (char)('0' + i);}valueToChar[62] = '+';valueToChar[63] = '/';// build translate charToValue table only once.for (int i = 0;i < 256;i++){charToValue[i] = IGNORE; // default is to ignore}for (int i = 0;i < 64;i++){charToValue[valueToChar[i]] = i;}charToValue['='] = PAD;}/** * used to disable test driver */private static final boolean debug = false;/** * debug display array */public static void show (byte[] b){for (int i = 0;i < b.length;i++){System.out.print(Integer.toHexString(b[i] & 0xff) + " ");}System.out.println();}/** * debug display array */public static void display (byte[] b){for (int i = 0;i < b.length;i++){System.out.print((char)b[i]);}System.out.println();}/** * test driver */public static void main (String[] args){if (debug){byte[] a = {(byte)0xfc,(byte)0x0f,(byte)0xc0};byte[] b = {(byte)0x03,(byte)0xf0,(byte)0x3f};byte[] c = {(byte)0x00,(byte)0x00,(byte)0x00};byte[] d = {(byte)0xff,(byte)0xff,(byte)0xff};byte[] e = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1};byte[] f = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1,(byte)2};byte[] g = {(byte)0xfc,(byte)0x0f,(byte)0xc0,(byte)1,(byte)2,(byte)3};byte[] h = "AAAAAAAAAAB".getBytes();show(a);show(b);show(c);show(d);show(e);show(f);show(g);show(h);Base64PYZX b64 = new Base64PYZX();show(b64.decode(b64.encode(a)));show(b64.decode(b64.encode(b)));show(b64.decode(b64.encode(c)));show(b64.decode(b64.encode(d)));show(b64.decode(b64.encode(e)));show(b64.decode(b64.encode(f)));show(b64.decode(b64.encode(g)));show(b64.decode(b64.encode(h)));b64.setLineLength(8);show((b64.encode(h)).getBytes());}} // end main} // end Base64
阅读全文
0 0
- RSA 加密-重写base64 适用于反射
- RSA+Base64加密
- iOS - 加密 Base64 MD5 DES AES RSA
- Android中RSA+BASE64加密解密
- golang实现md5、RSA、base64 加密解密
- 前端RSA加密及压缩base64
- C#BASE64加密解密(适用于处理加密文件名)
- C#.NET 加密解密:AES/DES/Base64/RSA/MD5/SHA256
- C#.NET 加密解密:AES/DES/Base64/RSA/MD5/SHA256
- C#.NET 加密解密:AES/DES/Base64/RSA/MD5/SHA256
- IOS下RSA&base64与Java端加密解密备忘
- RSA 加密与Base64 +号变空格的问题
- 通过Base64加密解密解决RSA中文解密乱码问题
- java之RSA和Base64加密帮助类
- RSA+SHA256+BASE64对数据进行加密解密及校验
- 数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)
- 数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)
- 数据传输加密:非对称加密算法RSA+对称算法AES(适用于java,android和Web)
- iOS ijkplayer 音视频同步
- angularJs过滤器(货币转换,大小写,字数限制,日期)
- Go语言二维数组的传参
- Kotlin编程之类的介绍和使用
- 面试的角度诠释Java工程师(一)
- RSA 加密-重写base64 适用于反射
- VMware中解决ubuntu不能连接网络问题
- CListCtrl使用
- OpenCV使用FindContours进行二维码定位
- IBM Websphere MQ _01 基本操作
- Web Moudle
- java初学者最关心的五个问题
- iReport_web开发配置向导
- RxJava操作符 reduce & scan