├── Base64Utils ├── DataUtils ├── README.md ├── RSATest └── RSAUtils /Base64Utils: -------------------------------------------------------------------------------- 1 | package com.yiban.data; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.FileOutputStream; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | 11 | import it.sauronsoftware.base64.Base64; 12 | 13 | /** *//** 14 | *
15 | * BASE64编码解码工具包 16 | *
17 | *18 | * 依赖javabase64-1.3.1.jar 19 | *
20 | * 21 | * @author jun 22 | * @date 2012-5-19 23 | * @version 1.0 24 | */ 25 | public class Base64Utils { 26 | 27 | /** *//** 28 | * 文件读取缓冲区大小 29 | */ 30 | private static final int CACHE_SIZE = 1024; 31 | 32 | /** *//** 33 | *34 | * BASE64字符串解码为二进制数据 35 | *
36 | * 37 | * @param base64 38 | * @return 39 | * @throws Exception 40 | */ 41 | public static byte[] decode(String base64) throws Exception { 42 | return Base64.decode(base64.getBytes()); 43 | } 44 | 45 | /** *//** 46 | *47 | * 二进制数据编码为BASE64字符串 48 | *
49 | * 50 | * @param bytes 51 | * @return 52 | * @throws Exception 53 | */ 54 | public static String encode(byte[] bytes) throws Exception { 55 | return new String(Base64.encode(bytes)); 56 | } 57 | 58 | /** *//** 59 | *60 | * 将文件编码为BASE64字符串 61 | *
62 | *63 | * 大文件慎用,可能会导致内存溢出 64 | *
65 | * 66 | * @param filePath 文件绝对路径 67 | * @return 68 | * @throws Exception 69 | */ 70 | public static String encodeFile(String filePath) throws Exception { 71 | byte[] bytes = fileToByte(filePath); 72 | return encode(bytes); 73 | } 74 | 75 | /** *//** 76 | *77 | * BASE64字符串转回文件 78 | *
79 | * 80 | * @param filePath 文件绝对路径 81 | * @param base64 编码字符串 82 | * @throws Exception 83 | */ 84 | public static void decodeToFile(String filePath, String base64) throws Exception { 85 | byte[] bytes = decode(base64); 86 | byteArrayToFile(bytes, filePath); 87 | } 88 | 89 | /** *//** 90 | *91 | * 文件转换为二进制数组 92 | *
93 | * 94 | * @param filePath 文件路径 95 | * @return 96 | * @throws Exception 97 | */ 98 | public static byte[] fileToByte(String filePath) throws Exception { 99 | byte[] data = new byte[0]; 100 | File file = new File(filePath); 101 | if (file.exists()) { 102 | FileInputStream in = new FileInputStream(file); 103 | ByteArrayOutputStream out = new ByteArrayOutputStream(2048); 104 | byte[] cache = new byte[CACHE_SIZE]; 105 | int nRead = 0; 106 | while ((nRead = in.read(cache)) != -1) { 107 | out.write(cache, 0, nRead); 108 | out.flush(); 109 | } 110 | out.close(); 111 | in.close(); 112 | data = out.toByteArray(); 113 | } 114 | return data; 115 | } 116 | 117 | /** *//** 118 | *119 | * 二进制数据写文件 120 | *
121 | * 122 | * @param bytes 二进制数据 123 | * @param filePath 文件生成目录 124 | */ 125 | public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception { 126 | InputStream in = new ByteArrayInputStream(bytes); 127 | File destFile = new File(filePath); 128 | if (!destFile.getParentFile().exists()) { 129 | destFile.getParentFile().mkdirs(); 130 | } 131 | destFile.createNewFile(); 132 | OutputStream out = new FileOutputStream(destFile); 133 | byte[] cache = new byte[CACHE_SIZE]; 134 | int nRead = 0; 135 | while ((nRead = in.read(cache)) != -1) { 136 | out.write(cache, 0, nRead); 137 | out.flush(); 138 | } 139 | out.close(); 140 | in.close(); 141 | } 142 | 143 | 144 | } 145 | -------------------------------------------------------------------------------- /DataUtils: -------------------------------------------------------------------------------- 1 | /** 2 | * DataUtils.java 3 | * 2014-10-10 下午7:40:02 4 | * Administrator JUN 5 | */ 6 | package com.yiban.data; 7 | 8 | import org.json.JSONObject; 9 | 10 | import android.util.Log; 11 | 12 | /** 13 | * @author Administrator 14 | *暴露加密和解密算法的工具类 15 | */ 16 | public final class DataUtils { 17 | public static final String TAG="DataUtils"; 18 | //封装的公钥和私钥 可以采用2对不配套的来处理(更安全 当然也可以使用一套rsa) 19 | //第一对公钥 20 | private static final String DEFAULT_PUBLIC_KEY = "your first pair public key"; 21 | // private static final String DEFAULT_PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOiy8fWAKlBNNktcYxxJ56oONa4NVjT4BpvVVu0YmpZ2Q93fYPiERTAWNUn4UlurtSm8UUNDeTbLaf/WvPFZqkWT974E00JIo/17r45/VIuzzdKjbt2CIB4AqZ1CjHB9euC8/X9BEwknSLqbcJFHJOVc75wwZtipG/WJNP25pGiVAgMBAAECgYEAv4PXY8hyCtkhYHDPGU8yHWHIiFFtq/ad6c9x1X00bbU0Mf1Q3/hswSDmBtUbY1s0pP7amtODhbdwrCFeK/0yBrOegb2fQeJs/QL6/y4/DPzRB21k9N8cQjgmv5tQb72fwdY8nDROXnzKQceMo6b/xkWaIhvhdUq6nCqPvoIGRIECQQD+lOKTQk769G9BQd7HW+2H2NioPbxri+V27daC1M5uBfBj8Wt3NDJ5IyMvOHz5yTlm8FsE2Zz1/aFdLJ/Rv4IRAkEA6f7ZOMcuxlRsAiN708+r3q3sxAyBood+qAJ1MKhOrdR94RcAPUkcjFTZ8j1v0eclj6+w2RChcpb5Ath93ia6RQJBAP3b6x+axHUcn4A8NfEn6vFGu6zwet3nT3bLbddia0JtK6wNhfMFGruO3TvuITlXfaT3UlvAv/LP6kOmBuw6AnECQQDR3r29awjM4ZMuJ908EJs6Ugx1mjH7MEOtNOcfCRXoWxm79QFF9nkgdEo2NlxAi2zo/s9DIONs/3O/1aSux1VxAkBkkOdc0f2ogWZHqtCYfVfYjwbMvlW/6lnbq0B76V1SVqogoSubwnF7EUBdmqpzWmzqM4xURBh9QqDnUUfBzPMW"; 22 | // private static final String DEFAULT_PRIVATE_KEY=""; 23 | //第二队私钥 24 | private static final String DEFAULT_PRIVATE_KEY = "your second pair private key"; 25 | 26 | public static String encodeRequest(JSONObject json) throws Exception{ 27 | byte[] data = json.toString().getBytes(); 28 | byte[] encodedData = RSAUtils.encryptByPublicKey(data, DEFAULT_PUBLIC_KEY); 29 | System.out.println("加密后文字:\r\n" + new String(encodedData)); 30 | Log.i(TAG,"网络传输的字符串:"+Base64Utils.encode(encodedData)); 31 | 32 | return Base64Utils.encode(encodedData); 33 | 34 | } 35 | 36 | 37 | public static String decodeAppResponse(String response) throws Exception{ 38 | Log.i(TAG,"需要解密的字符串"+response); 39 | byte[] responseData = Base64Utils.decode(response); 40 | byte[] decodedData = RSAUtils.decryptByPrivateKey(responseData, 41 | DEFAULT_PRIVATE_KEY); 42 | String responseText = new String(decodedData); 43 | System.out.println("解密后文字: \r\n" + responseText); 44 | Log.i(TAG,"解密后的字符串"+response); 45 | return responseText; 46 | } 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | java-android-rsa 2 | ================ 3 | 4 | java和android 通用的rsa 加密封装 5 | -------------------------------------------------------------------------------- /RSATest: -------------------------------------------------------------------------------- 1 | package data; 2 | 3 | import org.json.JSONObject; 4 | 5 | public class RSATest { 6 | private static final String DEFAULT_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDosvH1gCpQTTZLXGMcSeeqDjWuDVY0+Aab1VbtGJqWdkPd32D4hEUwFjVJ+FJbq7UpvFFDQ3k2y2n/1rzxWapFk/e+BNNCSKP9e6+Of1SLs83So27dgiAeAKmdQoxwfXrgvP1/QRMJJ0i6m3CRRyTlXO+cMGbYqRv1iTT9uaRolQIDAQAB"; 7 | private static final String DEFAULT_PRIVATE_KEY = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOiy8fWAKlBNNktcYxxJ56oONa4NVjT4BpvVVu0YmpZ2Q93fYPiERTAWNUn4UlurtSm8UUNDeTbLaf/WvPFZqkWT974E00JIo/17r45/VIuzzdKjbt2CIB4AqZ1CjHB9euC8/X9BEwknSLqbcJFHJOVc75wwZtipG/WJNP25pGiVAgMBAAECgYEAv4PXY8hyCtkhYHDPGU8yHWHIiFFtq/ad6c9x1X00bbU0Mf1Q3/hswSDmBtUbY1s0pP7amtODhbdwrCFeK/0yBrOegb2fQeJs/QL6/y4/DPzRB21k9N8cQjgmv5tQb72fwdY8nDROXnzKQceMo6b/xkWaIhvhdUq6nCqPvoIGRIECQQD+lOKTQk769G9BQd7HW+2H2NioPbxri+V27daC1M5uBfBj8Wt3NDJ5IyMvOHz5yTlm8FsE2Zz1/aFdLJ/Rv4IRAkEA6f7ZOMcuxlRsAiN708+r3q3sxAyBood+qAJ1MKhOrdR94RcAPUkcjFTZ8j1v0eclj6+w2RChcpb5Ath93ia6RQJBAP3b6x+axHUcn4A8NfEn6vFGu6zwet3nT3bLbddia0JtK6wNhfMFGruO3TvuITlXfaT3UlvAv/LP6kOmBuw6AnECQQDR3r29awjM4ZMuJ908EJs6Ugx1mjH7MEOtNOcfCRXoWxm79QFF9nkgdEo2NlxAi2zo/s9DIONs/3O/1aSux1VxAkBkkOdc0f2ogWZHqtCYfVfYjwbMvlW/6lnbq0B76V1SVqogoSubwnF7EUBdmqpzWmzqM4xURBh9QqDnUUfBzPMW"; 8 | 9 | public static void main(String[] args) throws Exception { 10 | test(); 11 | // testSign(); 12 | // encodeRequest(null); 13 | } 14 | 15 | static void test() throws Exception { 16 | System.err.println("公钥加密——私钥解密"); 17 | String source = "这是一行没有任何意义的文字,你看完了等于没看士大夫反反复复反反复复反反复复反反复复多发时段发生的发生的发生的发生的发生的发生的发生的发生的发生的发生的发生的发生的发生的发生的发生,不是吗?这是一行没有任何意义的文字,asdfsdafsdafsfasdfdfsa你看完了等于没看,不是吗?这是一行没有任何意义的文字,你看完了等于没看,不是吗?这是一行没有任何意义的文字,你看完了等于没看,不是吗?这是一行没有任何意义的文字,你看完了等于没看,不是吗?这是一行没有任何意义的文字,你看完了等于没看,不是吗?这是一行没有任何意义的文字,你看完了等于没看,不是吗?"; 18 | System.out.println("\r加密前文字:\r\n" + source); 19 | byte[] data = source.getBytes(); 20 | byte[] encodedData = RSAUtils.encryptByPublicKey(data, DEFAULT_PUBLIC_KEY); 21 | System.out.println("加密后文字:\r\n" + new String(encodedData)); 22 | byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, 23 | DEFAULT_PRIVATE_KEY); 24 | String target = new String(decodedData); 25 | System.out.println("解密后文字: \r\n" + target); 26 | } 27 | 28 | static void encodeRequest(JSONObject json) throws Exception{ 29 | JSONObject jsonObject = new JSONObject(); 30 | for(int i=0;i<1000;i++){ 31 | jsonObject.put(i+"","value"+i); 32 | } 33 | byte[] data = jsonObject.toString().getBytes(); 34 | byte[] encodedData = RSAUtils.encryptByPublicKey(data, DEFAULT_PUBLIC_KEY); 35 | System.out.println("加密后文字:\r\n" + new String(encodedData)); 36 | byte[] decodedData = RSAUtils.decryptByPrivateKey(encodedData, 37 | DEFAULT_PRIVATE_KEY); 38 | String target = new String(decodedData); 39 | System.out.println("解密后文字: \r\n" + target); 40 | } 41 | 42 | 43 | 44 | 45 | } 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /RSAUtils: -------------------------------------------------------------------------------- 1 | package data; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.security.Key; 5 | import java.security.KeyFactory; 6 | import java.security.KeyPair; 7 | import java.security.KeyPairGenerator; 8 | import java.security.PrivateKey; 9 | import java.security.PublicKey; 10 | import java.security.Signature; 11 | import java.security.interfaces.RSAPrivateKey; 12 | import java.security.interfaces.RSAPublicKey; 13 | import java.security.spec.PKCS8EncodedKeySpec; 14 | import java.security.spec.X509EncodedKeySpec; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | 18 | import javax.crypto.Cipher; 19 | 20 | /** *//** 21 | *22 | * RSA公钥/私钥/签名工具包 23 | *
24 | *25 | * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) 26 | *
27 | *
28 | * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式
29 | * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,
30 | * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全
31 | *
71 | * 生成密钥对(公钥和私钥) 72 | *
73 | * 74 | * @return 75 | * @throws Exception 76 | */ 77 | public static Map91 | * 用私钥对信息生成数字签名 92 | *
93 | * 94 | * @param data 已加密数据 95 | * @param privateKey 私钥(BASE64编码) 96 | * 97 | * @return 98 | * @throws Exception 99 | */ 100 | public static String sign(byte[] data, String privateKey) throws Exception { 101 | byte[] keyBytes = Base64Utils.decode(privateKey); 102 | PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 103 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 104 | PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); 105 | Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 106 | signature.initSign(privateK); 107 | signature.update(data); 108 | return Base64Utils.encode(signature.sign()); 109 | } 110 | 111 | /** *//** 112 | *113 | * 校验数字签名 114 | *
115 | * 116 | * @param data 已加密数据 117 | * @param publicKey 公钥(BASE64编码) 118 | * @param sign 数字签名 119 | * 120 | * @return 121 | * @throws Exception 122 | * 123 | */ 124 | public static boolean verify(byte[] data, String publicKey, String sign) 125 | throws Exception { 126 | byte[] keyBytes = Base64Utils.decode(publicKey); 127 | X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 128 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 129 | PublicKey publicK = keyFactory.generatePublic(keySpec); 130 | Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 131 | signature.initVerify(publicK); 132 | signature.update(data); 133 | return signature.verify(Base64Utils.decode(sign)); 134 | } 135 | 136 | /** *//** 137 | *138 | * 私钥解密 139 | *
140 | * 141 | * @param encryptedData 已加密数据 142 | * @param privateKey 私钥(BASE64编码) 143 | * @return 144 | * @throws Exception 145 | */ 146 | public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) 147 | throws Exception { 148 | byte[] keyBytes = Base64Utils.decode(privateKey); 149 | PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 150 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 151 | Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); 152 | // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 153 | Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 154 | 155 | cipher.init(Cipher.DECRYPT_MODE, privateK); 156 | int inputLen = encryptedData.length; 157 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 158 | int offSet = 0; 159 | byte[] cache; 160 | int i = 0; 161 | // 对数据分段解密 162 | while (inputLen - offSet > 0) { 163 | if (inputLen - offSet > MAX_DECRYPT_BLOCK) { 164 | cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); 165 | } else { 166 | cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); 167 | } 168 | out.write(cache, 0, cache.length); 169 | i++; 170 | offSet = i * MAX_DECRYPT_BLOCK; 171 | } 172 | byte[] decryptedData = out.toByteArray(); 173 | out.close(); 174 | return decryptedData; 175 | } 176 | 177 | /** *//** 178 | *179 | * 公钥解密 180 | *
181 | * 182 | * @param encryptedData 已加密数据 183 | * @param publicKey 公钥(BASE64编码) 184 | * @return 185 | * @throws Exception 186 | */ 187 | public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) 188 | throws Exception { 189 | byte[] keyBytes = Base64Utils.decode(publicKey); 190 | X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); 191 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 192 | Key publicK = keyFactory.generatePublic(x509KeySpec); 193 | // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 194 | Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 195 | cipher.init(Cipher.DECRYPT_MODE, publicK); 196 | int inputLen = encryptedData.length; 197 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 198 | int offSet = 0; 199 | byte[] cache; 200 | int i = 0; 201 | // 对数据分段解密 202 | while (inputLen - offSet > 0) { 203 | if (inputLen - offSet > MAX_DECRYPT_BLOCK) { 204 | cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); 205 | } else { 206 | cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); 207 | } 208 | out.write(cache, 0, cache.length); 209 | i++; 210 | offSet = i * MAX_DECRYPT_BLOCK; 211 | } 212 | byte[] decryptedData = out.toByteArray(); 213 | out.close(); 214 | return decryptedData; 215 | } 216 | 217 | /** *//** 218 | *219 | * 公钥加密 220 | *
221 | * 222 | * @param data 源数据 223 | * @param publicKey 公钥(BASE64编码) 224 | * @return 225 | * @throws Exception 226 | */ 227 | public static byte[] encryptByPublicKey(byte[] data, String publicKey) 228 | throws Exception { 229 | byte[] keyBytes = Base64Utils.decode(publicKey); 230 | X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); 231 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 232 | Key publicK = keyFactory.generatePublic(x509KeySpec); 233 | // 对数据加密 234 | // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 235 | Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 236 | cipher.init(Cipher.ENCRYPT_MODE, publicK); 237 | int inputLen = data.length; 238 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 239 | int offSet = 0; 240 | byte[] cache; 241 | int i = 0; 242 | // 对数据分段加密 243 | while (inputLen - offSet > 0) { 244 | if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { 245 | cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); 246 | } else { 247 | cache = cipher.doFinal(data, offSet, inputLen - offSet); 248 | } 249 | out.write(cache, 0, cache.length); 250 | i++; 251 | offSet = i * MAX_ENCRYPT_BLOCK; 252 | } 253 | byte[] encryptedData = out.toByteArray(); 254 | out.close(); 255 | return encryptedData; 256 | } 257 | 258 | /** *//** 259 | *260 | * 私钥加密 261 | *
262 | * 263 | * @param data 源数据 264 | * @param privateKey 私钥(BASE64编码) 265 | * @return 266 | * @throws Exception 267 | */ 268 | public static byte[] encryptByPrivateKey(byte[] data, String privateKey) 269 | throws Exception { 270 | byte[] keyBytes = Base64Utils.decode(privateKey); 271 | PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 272 | KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 273 | Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); 274 | // Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 275 | Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 276 | cipher.init(Cipher.ENCRYPT_MODE, privateK); 277 | int inputLen = data.length; 278 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 279 | int offSet = 0; 280 | byte[] cache; 281 | int i = 0; 282 | // 对数据分段加密 283 | while (inputLen - offSet > 0) { 284 | if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { 285 | cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); 286 | } else { 287 | cache = cipher.doFinal(data, offSet, inputLen - offSet); 288 | } 289 | out.write(cache, 0, cache.length); 290 | i++; 291 | offSet = i * MAX_ENCRYPT_BLOCK; 292 | } 293 | byte[] encryptedData = out.toByteArray(); 294 | out.close(); 295 | return encryptedData; 296 | } 297 | 298 | /** *//** 299 | *300 | * 获取私钥 301 | *
302 | * 303 | * @param keyMap 密钥对 304 | * @return 305 | * @throws Exception 306 | */ 307 | public static String getPrivateKey(Map315 | * 获取公钥 316 | *
317 | * 318 | * @param keyMap 密钥对 319 | * @return 320 | * @throws Exception 321 | */ 322 | public static String getPublicKey(Map