java代码实现RSA加解密,java代码rsa解密
分享于 点击 35040 次 点评:247
java代码实现RSA加解密,java代码rsa解密
一.前言
RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
二.示例代码
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; /** * RSA加解密工具类 * @author 丶晓权 * 在Linux中使用openssl * 生成私钥:openssl genrsa -out rsa_private_key.pem 1024 * 把RSA私钥转换成PKCS8格式:openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt * 生成RSA公钥:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem * 或使用程序中的方法生成密钥对 * */ public class SignatureUtil { /** * 公钥加密 * @param content加密前内容 * @param publicKey公钥 * @param charset加密编码 * @return 返回加密后的数据 * @throws Exception */ public static String rsaEncrypt(String content, String publicKey, String charset) throws Exception { PublicKey pubKey = getPublicKeyFromX509(new ByteArrayInputStream(publicKey.getBytes())); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, pubKey); byte[] data = (charset==null||charset.isEmpty()) content.getBytes() : content.getBytes(charset); int inputLen = data.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段加密 while (inputLen - offSet > 0) { if (inputLen - offSet > 117) { cache = cipher.doFinal(data, offSet, 117); } else { cache = cipher.doFinal(data, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * 117; } byte[] encryptedData = Base64.encodeBase64(out.toByteArray()); out.close(); return (charset==null||charset.isEmpty()) new String(encryptedData) : new String(encryptedData, charset); } /** * 私钥解密 * @param content待解密字符串 * @param privateKey 私钥key * @param charset 编码 * @return 返回的解密后信息 * @throws Exception 异常 */ public static String rsaDecrypt(String content, String privateKey, String charset) throws Exception { try { PrivateKey priKey = getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes())); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, priKey); byte[] encryptedData = (charset==null||charset.isEmpty()) Base64.decodeBase64(content.getBytes()) : Base64.decodeBase64(content.getBytes(charset)); int inputLen = encryptedData.length; ByteArrayOutputStream out = new ByteArrayOutputStream(); int offSet = 0; byte[] cache; int i = 0; // 对数据分段解密 while (inputLen - offSet > 0) { if (inputLen - offSet > 128) { cache = cipher.doFinal(encryptedData, offSet, 128); } else { cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); } out.write(cache, 0, cache.length); i++; offSet = i * 128; } byte[] decryptedData = out.toByteArray(); out.close(); return (charset==null||charset.isEmpty()) new String(decryptedData) : new String(decryptedData, charset); } catch (Exception e) { throw new Exception("EncodeContent = " + content + ",charset = " + charset, e); } } /** * RSA签名 * @param content * @param privateKey * @param charset * @return * @throws Exception */ public static String rsaSign(String content, String privateKey, String charset) throws Exception { try { PrivateKey priKey = getPrivateKeyFromPKCS8(new ByteArrayInputStream(privateKey.getBytes())); java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA"); signature.initSign(priKey); if (charset==null||charset.isEmpty()) { signature.update(content.getBytes()); } else { signature.update(content.getBytes(charset)); } byte[] signed = signature.sign(); return new String(Base64.encodeBase64(signed)); } catch (Exception e) { throw new Exception("RSAcontent = " + content + "; charset = " + charset, e); } } /** * 签名校验 * @param content * @param sign * @param publicKey * @param charset * @return * @throws Exception */ public static boolean rsaCheckContent(String content, String sign, String publicKey, String charset) throws Exception { try { PublicKey pubKey = getPublicKeyFromX509(new ByteArrayInputStream(publicKey.getBytes())); java.security.Signature signature = java.security.Signature.getInstance("SHA1WithRSA"); signature.initVerify(pubKey); if (charset==null||charset.isEmpty()) { signature.update(content.getBytes()); } else { signature.update(content.getBytes(charset)); } return signature.verify(Base64.decodeBase64(sign.getBytes())); } catch (Exception e) { throw new Exception("RSAcontent=" + content + ",sign=" + sign + ",charset=" + charset, e); } } /** * 获取公钥 * @param algorithm * @param ins * @return * @throws Exception */ public static PublicKey getPublicKeyFromX509(InputStream is) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); StringWriter writer = new StringWriter(); Reader in=new InputStreamReader(is); char[] buffer = new char[4096]; int amount; while ((amount = in.read(buffer)) >= 0) { writer.write(buffer, 0, amount); } byte[] encodedKey = writer.toString().getBytes(); encodedKey = Base64.decodeBase64(encodedKey); return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); } /** * 获取私钥 * @param algorithm * @param is * @return * @throws Exception */ public static PrivateKey getPrivateKeyFromPKCS8(InputStream is) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); StringWriter writer = new StringWriter(); Reader in=new InputStreamReader(is); char[] buffer = new char[4096]; int amount; while ((amount = in.read(buffer)) >= 0) { writer.write(buffer, 0, amount); } byte[] encodedKey = writer.toString().getBytes(); encodedKey = Base64.decodeBase64(encodedKey); return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey)); } /** * 生成密钥 * @return * @throws Exception */ public static KeyPair generateKeyPair() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA"); keyPairGen.initialize(1024); return keyPairGen.generateKeyPair(); } /** * 根据密钥对获取公钥 * @param keyPair * @return * @throws UnsupportedEncodingException */ public static String getRSAPublicKey(KeyPair keyPair,String charset) throws UnsupportedEncodingException { PublicKey publicKey = keyPair.getPublic(); byte[] encodeBase64 = Base64.encodeBase64(publicKey.getEncoded()); return (charset==null||charset.isEmpty()) new String(encodeBase64) : new String(encodeBase64, charset); } /** * 根据密钥对获取公钥 * @param keyPair * @return * @throws UnsupportedEncodingException */ public static String getRSAPrivateKey(KeyPair keyPair,String charset) throws UnsupportedEncodingException { PrivateKey privateKey = keyPair.getPrivate(); byte[] encodeBase64 = Base64.encodeBase64(privateKey.getEncoded()); return (charset==null||charset.isEmpty()) new String(encodeBase64) : new String(encodeBase64, charset); } }
三.测试代码
KeyPair keyPair = SignatureUtil.generateKeyPair(); String privateKey=SignatureUtil.getRSAPrivateKey(keyPair, "utf-8"); String publicKey=SignatureUtil.getRSAPublicKey(keyPair, "utf-8"); String rsaEncrypt = SignatureUtil.rsaEncrypt("测试", publicKey, "UTF-8");//加密 System.out.println(rsaEncrypt); String rsaEncrypt2 = SignatureUtil.rsaEncrypt("测试", publicKey, "GBK");//加密 System.out.println(rsaEncrypt2); System.out.println(SignatureUtil.rsaDecrypt(rsaEncrypt, privateKey, "UTF-8"));//解密 System.out.println(SignatureUtil.rsaDecrypt(rsaEncrypt, privateKey, "GBK"));//测试错误解密 System.out.println(SignatureUtil.rsaDecrypt(rsaEncrypt2, privateKey, "GBK"));//解密 String rsaSign = SignatureUtil.rsaSign("测试", privateKey, "UTF-8");//加签 String rsaSign2 = SignatureUtil.rsaSign("测试", privateKey, "GBK");//加签 System.out.println(rsaSign); System.out.println(rsaSign2); System.out.println(SignatureUtil.rsaCheckContent("测试", rsaSign, publicKey, "UTF-8"));//验签 System.out.println(SignatureUtil.rsaCheckContent("测试", rsaSign, publicKey, "GBK"));//测试错误验签 System.out.println(SignatureUtil.rsaCheckContent("测试", rsaSign2, publicKey, "GBK"));//验签
四.运行结果
HO2vj3HrzvuWPdF3gW0aqFqD4Ye5BONUcBWwcPEcX02SzD/tyMqsJFcRD1MHYzhlVArRW9+URzUGOpgqCo5oABP5GKP618T1UabJyCzv5sHgADURtERJDF7AXV+ud/5UD8h4koDMCFOa8EVP2CJW4MOWEgiRkY/zJJ9d09XwWyA= j7WKo6Qs1V+D2mq+eBkPJzlnyAH9crx9lSg0rS1/5lxbFQQN5n+XlD6g3JFBng1Y8M5gwJfALKIK2u+i43Ch0utbJF6XsILfKU5ILI2WBoTMbmHcxR+CGS3Tv+ueD5BtfqI1P1R0P1ayMbUDLeHWRcDFs+s3YI3vrB3ZIrXEnyk= 测试 娴嬭瘯 测试 lqi3ve6TO2yYs6rUEf6NuoTGDz6FbvL6XYxyYQbT1L18iSHNolJ+m71V8MYIenkEtVPl75KDs1UMrSTbxA/V5+2O1nWP4Iw+80Eg3536zvI4J1Od/6UVUOZzhubNctVpUXYD7LY4vncvAV/mGSpl6BRqW20HnP9MMVDek1YaF/8= ozcUhv19xhp/FveSQiU6MbBrwrjJBuMp1SiPdRkm4HJD+24r3tOcoHJrawSN99E/EYIAHZlcDPbOkABcMYKRJyHCdc18aRDWO/Sbf5121EWnk2NMdRKOtkuqfEbmSxjTjS/gUmcHEJd8Al4vvtz1kUHF7OdexXn++E38cWdBdIM= true false true
四.Base64工具类
public class Base64 { static final int CHUNK_SIZE = 76; static final byte[] CHUNK_SEPARATOR = "\r\n".getBytes(); static final int BASELENGTH = 255; static final int LOOKUPLENGTH = 64; static final int EIGHTBIT = 8; static final int SIXTEENBIT = 16; static final int TWENTYFOURBITGROUP = 24; static final int FOURBYTE = 4; static final int SIGN = -128; static final byte PAD = (byte) '='; private static byte[] base64Alphabet = new byte[BASELENGTH]; private static byte[] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; static { for (int i = 0; i < BASELENGTH; i++) { base64Alphabet[i] = (byte) -1; } for (int i = 'Z'; i >= 'A'; i--) { base64Alphabet[i] = (byte) (i - 'A'); } for (int i = 'z'; i >= 'a'; i--) { base64Alphabet[i] = (byte) (i - 'a' + 26); } for (int i = '9'; i >= '0'; i--) { base64Alphabet[i] = (byte) (i - '0' + 52); } base64Alphabet['+'] = 62; base64Alphabet['/'] = 63; for (int i = 0; i <= 25; i++) { lookUpBase64Alphabet[i] = (byte) ('A' + i); } for (int i = 26, j = 0; i <= 51; i++, j++) { lookUpBase64Alphabet[i] = (byte) ('a' + j); } for (int i = 52, j = 0; i <= 61; i++, j++) { lookUpBase64Alphabet[i] = (byte) ('0' + j); } lookUpBase64Alphabet[62] = (byte) '+'; lookUpBase64Alphabet[63] = (byte) '/'; } private static boolean isBase64(byte octect) { if (octect == PAD) { return true; } else if (base64Alphabet[octect] == -1) { return false; } else { return true; } } public static boolean isArrayByteBase64(byte[] arrayOctect) { arrayOctect = discardWhitespace(arrayOctect); int length = arrayOctect.length; if (length == 0) { return true; } for (int i = 0; i < length; i++) { if (!isBase64(arrayOctect[i])) { return false; } } return true; } public static byte[] encodeBase64(byte[] binaryData) { return encodeBase64(binaryData, false); } public static byte[] encodeBase64Chunked(byte[] binaryData) { return encodeBase64(binaryData, true); } public Object decode(Object pObject) throws Exception { if (!(pObject instanceof byte[])) { throw new Exception("Parameter supplied to Base64 decode is not a byte[]"); } return decode((byte[]) pObject); } public byte[] decode(byte[] pArray) { return decodeBase64(pArray); } public static byte[] encodeBase64(byte[] binaryData, boolean isChunked) { int lengthDataBits = binaryData.length * EIGHTBIT; int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; byte encodedData[] = null; int encodedDataLength = 0; int nbrChunks = 0; if (fewerThan24bits != 0) { encodedDataLength = (numberTriplets + 1) * 4; } else { encodedDataLength = numberTriplets * 4; } if (isChunked) { nbrChunks = (CHUNK_SEPARATOR.length == 0 0 : (int) Math.ceil((float) encodedDataLength / CHUNK_SIZE)); encodedDataLength += nbrChunks * CHUNK_SEPARATOR.length; } encodedData = new byte[encodedDataLength]; byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; int encodedIndex = 0; int dataIndex = 0; int i = 0; int nextSeparatorIndex = CHUNK_SIZE; int chunksSoFar = 0; for (i = 0; i < numberTriplets; i++) { dataIndex = i * 3; b1 = binaryData[dataIndex]; b2 = binaryData[dataIndex + 1]; b3 = binaryData[dataIndex + 2]; l = (byte) (b2 & 0x0f); k = (byte) (b1 & 0x03); byte val1 = ((b1 & SIGN) == 0) (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); byte val2 = ((b2 & SIGN) == 0) (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); byte val3 = ((b3 & SIGN) == 0) (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc); encodedData[encodedIndex] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2 | (k << 4)]; encodedData[encodedIndex + 2] = lookUpBase64Alphabet[(l << 2) | val3]; encodedData[encodedIndex + 3] = lookUpBase64Alphabet[b3 & 0x3f]; encodedIndex += 4; if (isChunked) { if (encodedIndex == nextSeparatorIndex) { System.arraycopy(CHUNK_SEPARATOR, 0, encodedData, encodedIndex, CHUNK_SEPARATOR.length); chunksSoFar++; nextSeparatorIndex = (CHUNK_SIZE * (chunksSoFar + 1)) + (chunksSoFar * CHUNK_SEPARATOR.length); encodedIndex += CHUNK_SEPARATOR.length; } } } dataIndex = i * 3; if (fewerThan24bits == EIGHTBIT) { b1 = binaryData[dataIndex]; k = (byte) (b1 & 0x03); byte val1 = ((b1 & SIGN) == 0) (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); encodedData[encodedIndex] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex + 1] = lookUpBase64Alphabet[k << 4]; encodedData[encodedIndex + 2] = PAD; encodedData[encodedIndex + 3] = PAD; } else if (fewerThan24bits == SIXTEENBIT) { b1 = binaryData[dataIndex]; b2 = binaryData[dataIndex + 1]; l = (byte) (b2 & 0x0f); k = (byte) (b1 & 0x03); byte val1 = ((b1 & SIGN) == 0) (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0); byte val2 = ((b2 & SIGN) == 0) (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0); encodedData[encodedIndex] = lookUpBase64Alphabet[val1]; encodedData[encodedIndex + 1] = lookUpBase64Alphabet[val2 | (k << 4)]; encodedData[encodedIndex + 2] = lookUpBase64Alphabet[l << 2]; encodedData[encodedIndex + 3] = PAD; } if (isChunked) { if (chunksSoFar < nbrChunks) { System.arraycopy(CHUNK_SEPARATOR, 0, encodedData, encodedDataLength - CHUNK_SEPARATOR.length, CHUNK_SEPARATOR.length); } } return encodedData; } public static byte[] decodeBase64(byte[] base64Data) { base64Data = discardNonBase64(base64Data); if (base64Data.length == 0) { return new byte[0]; } int numberQuadruple = base64Data.length / FOURBYTE; byte decodedData[] = null; byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; int encodedIndex = 0; int dataIndex = 0; int lastData = base64Data.length; while (base64Data[lastData - 1] == PAD) { if (--lastData == 0) { return new byte[0]; } } decodedData = new byte[lastData - numberQuadruple]; for (int i = 0; i < numberQuadruple; i++) { dataIndex = i * 4; marker0 = base64Data[dataIndex + 2]; marker1 = base64Data[dataIndex + 3]; b1 = base64Alphabet[base64Data[dataIndex]]; b2 = base64Alphabet[base64Data[dataIndex + 1]]; if (marker0 != PAD && marker1 != PAD) { b3 = base64Alphabet[marker0]; b4 = base64Alphabet[marker1]; decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); } else if (marker0 == PAD) { decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); } else if (marker1 == PAD) { b3 = base64Alphabet[marker0]; decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)); } encodedIndex += 3; } return decodedData; } static byte[] discardWhitespace(byte[] data) { byte groomedData[] = new byte[data.length]; int bytesCopied = 0; for (int i = 0; i < data.length; i++) { switch (data[i]) { case (byte) ' ': case (byte) '\n': case (byte) '\r': case (byte) '\t': break; default: groomedData[bytesCopied++] = data[i]; } } byte packedData[] = new byte[bytesCopied]; System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); return packedData; } static byte[] discardNonBase64(byte[] data) { byte groomedData[] = new byte[data.length]; int bytesCopied = 0; for (int i = 0; i < data.length; i++) { if (isBase64(data[i])) { groomedData[bytesCopied++] = data[i]; } } byte packedData[] = new byte[bytesCopied]; System.arraycopy(groomedData, 0, packedData, 0, bytesCopied); return packedData; } public Object encode(Object pObject) throws Exception { if (!(pObject instanceof byte[])) { throw new Exception("Parameter supplied to Base64 encode is not a byte[]"); } return encode((byte[]) pObject); } public byte[] encode(byte[] pArray) { return encodeBase64(pArray, false); } }
用户点评