Android RSA加密解密

概述

RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困 难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。关于RSA其它需要了解的知识,参考维基百科:http://zh.wikipedia.org/zh-cn/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

在项目开发中对于一些比较敏感的信息需要对其进行加密处理,我们就可以使用RSA这种非对称加密算法来对数据进行加密处理。

 

使用

秘钥对的生成

1、我们可以在代码里随机生成密钥对

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
  * 随机生成RSA密钥对
  *
  * @param keyLength
  *            密钥长度,范围:512~2048
 
  *            一般1024
  * @return
  */
public static KeyPair generateRSAKeyPair( int keyLength)
{
     try
     {
         KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
         kpg.initialize(keyLength);
         return kpg.genKeyPair();
     } catch (NoSuchAlgorithmException e)
     {
         e.printStackTrace();
         return null ;
     }
}

通过这方法我们得到KeyPair后就可以调用 keyPair.getPrivate() 和 pair.getPublic()得到 私钥 和 公钥了。不过实际我们一般是使用2的方法把生成的密钥对保存起来,密钥自己保存,比如服务端,把公钥给客户端(Android)用于加密需要发送的数据,最后服务端根据私钥吧客户端加密的信息解密再处理。

 

2、通过OpenSSl工具生成密钥对

OpenSSl工具下载:OpenSSl工具 (64位的也可使用)使用OpenSSl工具生成密钥对的过程如下:

首先双击打开bin文件夹下的openssl.exe,打开之后是一个命令行窗口:

\

然后通过如下命令生成私钥:

 

?
1
genrsa -out rsa_private_key.pem 1024

 

\

这条命令是让openssl随机生成了一份私钥,加密长度是1024位, 密钥长度,范围:512~2048。执行完命令后就可在bin文件夹下看到rsa_private_key.pem文件了。

 

用文本类工具打开可看到里面的内容:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCfRTdcPIH10gT9f31rQuIInLwe7fl2dtEJ93gTmjE9c2H+kLVE
NWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThraz/L3nYJYlbqjHC3jTjUnZc0l
uumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG9aYqgE7zyTRZYX9byQIDAQAB
AoGAO9+sYRtKC9xJDfcocfMxv+UT/1ic6EDgcqu6Uzwq+Jvwod9KlXqyQJqCr6T7
pjfodc3RAZOTx4gCZJverBvz053RH5GawCdocEgaqbXAAWJOhA+9IEU0NUud7ckF
yDko0QXLoGP9tanrMEt5zMqt8QxDyl6Xcij3mk8rivOgBJECQQDNTO6dZX8xCozc
Ne0gzC53Gv/KQXANBBHMr7WkKUb2i5+tXkEJ5z3abx2ppEQXDr4AgJH8Gtbm6K7t
EHV4ov4FAkEAxppD/iiT1/SVQq20be8CsiHpsjTPiestWQWdm1Qn/Y2nAkGkpCFp
yEdUvVDPtQhRN9EqNggNAnwg5kMvsuwN9QJAfHBhQe4/hk5Kyz+0l+irUW6AFOxN
KtaIo3TtuK98X/yJsOAstAACMeCgLi9vRjqdWFiWJCVwlU38mZ0cVx8UsQJBALzt
M5Er+LiPKw5rQCD0JZRfPnkQU/3XgyQUe4Gv5PsHLcCvwXeBcafcc3hEz9JfPyPi
Dk2oCvg6LPHfKBkFBaECQQCODcKX6DBWiyVxmPaJOOcF63KpCYDPkjeovIUHro1x
ElR2GrQCC/9Q4C4vruOhBQ+vX8NMPnO6NBy5TLGDwMyc
-----END RSA PRIVATE KEY-----

这里面的内容是标准的ASCII字符,中间的一大串字符就是私钥数据了。

 

 

然后通过如下命令生成公钥:

 

?
1
rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

 

\
打开文件看下里面的内容:

 

?
1
2
3
4
5
6
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfRTdcPIH10gT9f31rQuIInLwe
7fl2dtEJ93gTmjE9c2H+kLVENWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThra
z/L3nYJYlbqjHC3jTjUnZc0luumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG
9aYqgE7zyTRZYX9byQIDAQAB
-----END PUBLIC KEY-----

可以看到是跟私钥的文件类似的。

 

 

这样密钥就基本生成了,不过这样密钥对的私钥是无法在代码中直接使用的,要想使用它需要借助RSAPrivateKeyStructure这个类,java是不自带的。所以为了方便使用,我们需要对私钥进行PKCS#8编码,命令如下:

 

?
1
pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt

 

\
这条命令的结果依然是在bin文件夹生成了pkcs8_rsa_private_key.pem文件,打开内容如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ9FN1w8gfXSBP1/
fWtC4gicvB7t+XZ20Qn3eBOaMT1zYf6QtUQ1aAQKIlVDmyidA1/BOgwp07Rvc6V/
imAEp4tOGtrP8vedgliVuqMcLeNONSdlzSW66alcayjHrb4+5IYGV9vzMk7qGLHg
ZX++HJBUKkb1piqATvPJNFlhf1vJAgMBAAECgYA736xhG0oL3EkN9yhx8zG/5RP/
WJzoQOByq7pTPCr4m/Ch30qVerJAmoKvpPumN+h1zdEBk5PHiAJkm96sG/PTndEf
kZrAJ2hwSBqptcABYk6ED70gRTQ1S53tyQXIOSjRBcugY/21qeswS3nMyq3xDEPK
XpdyKPeaTyuK86AEkQJBAM1M7p1lfzEKjNw17SDMLnca/8pBcA0EEcyvtaQpRvaL
n61eQQnnPdpvHamkRBcOvgCAkfwa1uboru0QdXii/gUCQQDGmkP+KJPX9JVCrbRt
7wKyIemyNM+J6y1ZBZ2bVCf9jacCQaSkIWnIR1S9UM+1CFE30So2CA0CfCDmQy+y
7A31AkB8cGFB7j+GTkrLP7SX6KtRboAU7E0q1oijdO24r3xf/Imw4Cy0AAIx4KAu
L29GOp1YWJYkJXCVTfyZnRxXHxSxAkEAvO0zkSv4uI8rDmtAIPQllF8+eRBT/deD
JBR7ga/k+wctwK/Bd4Fxp9xzeETP0l8/I+IOTagK+Dos8d8oGQUFoQJBAI4Nwpfo
MFaLJXGY9ok45wXrcqkJgM+SN6i8hQeujXESVHYatAIL/1DgLi+u46EFD69fw0w+
c7o0HLlMsYPAzJw=
-----END PRIVATE KEY-----

可以看到中间的私钥内容有所变化了,这样的私钥我们在代码里就方便使用了。

 

 

以上的密钥文件使用时需要注意吧头和尾的字符串去掉,我们只取中间的内容。

 

代码中的使用

首先我们需要封装写个RSA的工具类,方便加密解密的操作。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
package com.example.rsa;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
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.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
 
import javax.crypto.Cipher;
 
/**
  * @author Mr.Zheng
  * @date 2014年8月22日 下午1:44:23
  */
public final class RSAUtils
{
     private static String RSA = RSA;
 
     /**
      * 随机生成RSA密钥对(默认密钥长度为1024)
      *
      * @return
      */
     public static KeyPair generateRSAKeyPair()
     {
         return generateRSAKeyPair( 1024 );
     }
 
     /**
      * 随机生成RSA密钥对
      *
      * @param keyLength
      *            密钥长度,范围:512~2048
 
      *            一般1024
      * @return
      */
     public static KeyPair generateRSAKeyPair( int keyLength)
     {
         try
         {
             KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
             kpg.initialize(keyLength);
             return kpg.genKeyPair();
         } catch (NoSuchAlgorithmException e)
         {
             e.printStackTrace();
             return null ;
         }
     }
 
     /**
      * 用公钥加密
 
      * 每次加密的字节数,不能超过密钥的长度值减去11
      *
      * @param data
      *            需加密数据的byte数据
      * @param pubKey
      *            公钥
      * @return 加密后的byte型数据
      */
     public static byte [] encryptData( byte [] data, PublicKey publicKey)
     {
         try
         {
             Cipher cipher = Cipher.getInstance(RSA);
             // 编码前设定编码方式及密钥
             cipher.init(Cipher.ENCRYPT_MODE, publicKey);
             // 传入编码数据并返回编码结果
             return cipher.doFinal(data);
         } catch (Exception e)
         {
             e.printStackTrace();
             return null ;
         }
     }
 
     /**
      * 用私钥解密
      *
      * @param encryptedData
      *            经过encryptedData()加密返回的byte数据
      * @param privateKey
      *            私钥
      * @return
      */
     public static byte [] decryptData( byte [] encryptedData, PrivateKey privateKey)
     {
         try
         {
             Cipher cipher = Cipher.getInstance(RSA);
             cipher.init(Cipher.DECRYPT_MODE, privateKey);
             return cipher.doFinal(encryptedData);
         } catch (Exception e)
         {
             return null ;
         }
     }
 
     /**
      * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法
      *
      * @param keyBytes
      * @return
      * @throws NoSuchAlgorithmException
      * @throws InvalidKeySpecException
      */
     public static PublicKey getPublicKey( byte [] keyBytes) throws NoSuchAlgorithmException,
             InvalidKeySpecException
     {
         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(RSA);
         PublicKey publicKey = keyFactory.generatePublic(keySpec);
         return publicKey;
     }
 
     /**
      * 通过私钥byte[]将公钥还原,适用于RSA算法
      *
      * @param keyBytes
      * @return
      * @throws NoSuchAlgorithmException
      * @throws InvalidKeySpecException
      */
     public static PrivateKey getPrivateKey( byte [] keyBytes) throws NoSuchAlgorithmException,
             InvalidKeySpecException
     {
         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
         KeyFactory keyFactory = KeyFactory.getInstance(RSA);
         PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
         return privateKey;
     }
 
     /**
      * 使用N、e值还原公钥
      *
      * @param modulus
      * @param publicExponent
      * @return
      * @throws NoSuchAlgorithmException
      * @throws InvalidKeySpecException
      */
     public static PublicKey getPublicKey(String modulus, String publicExponent)
             throws NoSuchAlgorithmException, InvalidKeySpecException
     {
         BigInteger bigIntModulus = new BigInteger(modulus);
         BigInteger bigIntPrivateExponent = new BigInteger(publicExponent);
         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);
         KeyFactory keyFactory = KeyFactory.getInstance(RSA);
         PublicKey publicKey = keyFactory.generatePublic(keySpec);
         return publicKey;
     }
 
     /**
      * 使用N、d值还原私钥
      *
      * @param modulus
      * @param privateExponent
      * @return
      * @throws NoSuchAlgorithmException
      * @throws InvalidKeySpecException
      */
     public static PrivateKey getPrivateKey(String modulus, String privateExponent)
             throws NoSuchAlgorithmException, InvalidKeySpecException
     {
         BigInteger bigIntModulus = new BigInteger(modulus);
         BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);
         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent);
         KeyFactory keyFactory = KeyFactory.getInstance(RSA);
         PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
         return privateKey;
     }
 
     /**
      * 从字符串中加载公钥
      *
      * @param publicKeyStr
      *            公钥数据字符串
      * @throws Exception
      *             加载公钥时产生的异常
      */
     public static PublicKey loadPublicKey(String publicKeyStr) throws Exception
     {
         try
         {
             byte [] buffer = Base64Utils.decode(publicKeyStr);
             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
             X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
             return (RSAPublicKey) keyFactory.generatePublic(keySpec);
         } catch (NoSuchAlgorithmException e)
         {
             throw new Exception(无此算法);
         } catch (InvalidKeySpecException e)
         {
             throw new Exception(公钥非法);
         } catch (NullPointerException e)
         {
             throw new Exception(公钥数据为空);
         }
     }
 
     /**
      * 从字符串中加载私钥
 
      * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。
      *
      * @param privateKeyStr
      * @return
      * @throws Exception
      */
     public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception
     {
         try
         {
             byte [] buffer = Base64Utils.decode(privateKeyStr);
             // X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
             PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
             return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
         } catch (NoSuchAlgorithmException e)
         {
             throw new Exception(无此算法);
         } catch (InvalidKeySpecException e)
         {
             throw new Exception(私钥非法);
         } catch (NullPointerException e)
         {
             throw new Exception(私钥数据为空);
         }
     }
 
     /**
      * 从文件中输入流中加载公钥
      *
      * @param in
      *            公钥输入流
      * @throws Exception
      *             加载公钥时产生的异常
      */
     public static PublicKey loadPublicKey(InputStream in) throws Exception
     {
         try
         {
             return loadPublicKey(readKey(in));
         } catch (IOException e)
         {
             throw new Exception(公钥数据流读取错误);
         } catch (NullPointerException e)
         {
             throw new Exception(公钥输入流为空);
         }
     }
 
     /**
      * 从文件中加载私钥
      *
      * @param keyFileName
      *            私钥文件名
      * @return 是否成功
      * @throws Exception
      */
     public static PrivateKey loadPrivateKey(InputStream in) throws Exception
     {
         try
         {
             return loadPrivateKey(readKey(in));
         } catch (IOException e)
         {
             throw new Exception(私钥数据读取错误);
         } catch (NullPointerException e)
         {
             throw new Exception(私钥输入流为空);
         }
     }
 
     /**
      * 读取密钥信息
      *
      * @param in
      * @return
      * @throws IOException
      */
     private static String readKey(InputStream in) throws IOException
     {
         BufferedReader br = new BufferedReader( new InputStreamReader(in));
         String readLine = null ;
         StringBuilder sb = new StringBuilder();
         while ((readLine = br.readLine()) != null )
         {
             if (readLine.charAt( 0 ) == '-' )
             {
                 continue ;
             } else
             {
                 sb.append(readLine);
                 sb.append('
');
             }
         }
 
         return sb.toString();
     }
 
     /**
      * 打印公钥信息
      *
      * @param publicKey
      */
     public static void printPublicKeyInfo(PublicKey publicKey)
     {
         RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
         System.out.println(----------RSAPublicKey----------);
         System.out.println(Modulus.length= + rsaPublicKey.getModulus().bitLength());
         System.out.println(Modulus= + rsaPublicKey.getModulus().toString());
         System.out.println(PublicExponent.length= + rsaPublicKey.getPublicExponent().bitLength());
         System.out.println(PublicExponent= + rsaPublicKey.getPublicExponent().toString());
     }
 
     public static void printPrivateKeyInfo(PrivateKey privateKey)
     {
         RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey;
         System.out.println(----------RSAPrivateKey ----------);
         System.out.println(Modulus.length= + rsaPrivateKey.getModulus().bitLength());
         System.out.println(Modulus= + rsaPrivateKey.getModulus().toString());
         System.out.println(PrivateExponent.length= + rsaPrivateKey.getPrivateExponent().bitLength());
         System.out.println(PrivatecExponent= + rsaPrivateKey.getPrivateExponent().toString());
 
     }
 
}

 

上面需要注意的就是加密是有长度限制的,过长的话会抛异常!!!


代码中有些需要使用Base64再转换的,而java中不自带,Android中自带,所以自己写出一个来,方便Java后台使用

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package com.example.rsa;
 
import java.io.UnsupportedEncodingException;
 
/**
  * @author Mr.Zheng
  * @date 2014年8月22日 下午9:50:28
  */
public class Base64Utils
{
     private static char [] base64EncodeChars = new char []
     { 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' , 'S' , 'T' ,
             'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' ,
             'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' , '0' , '1' , '2' , '3' , '4' , '5' ,
             '6' , '7' , '8' , '9' , '+' , '/' };
     private static byte [] base64DecodeChars = new byte []
     { - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 ,
             - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 62 , - 1 , - 1 , - 1 , 63 , 52 , 53 ,
             54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 ,
             12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , - 1 , - 1 , - 1 , - 1 , - 1 , - 1 , 26 , 27 , 28 , 29 ,
             30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , - 1 , - 1 ,
             - 1 , - 1 , - 1 };
 
     /**
      * 加密
      *
      * @param data
      * @return
      */
     public static String encode( byte [] data)
     {
         StringBuffer sb = new StringBuffer();
         int len = data.length;
         int i = 0 ;
         int b1, b2, b3;
         while (i < len)
         {
             b1 = data[i++] & 0xff ;
             if (i == len)
             {
                 sb.append(base64EncodeChars[b1 >>> 2 ]);
                 sb.append(base64EncodeChars[(b1 & 0x3 ) << 4 ]);
                 sb.append(==);
                 break ;
             }
             b2 = data[i++] & 0xff ;
             if (i == len)
             {
                 sb.append(base64EncodeChars[b1 >>> 2 ]);
                 sb.append(base64EncodeChars[((b1 & 0x03 ) << 4 ) | ((b2 & 0xf0 ) >>> 4 )]);
                 sb.append(base64EncodeChars[(b2 & 0x0f ) << 2 ]);
                 sb.append(=);
                 break ;
             }
             b3 = data[i++] & 0xff ;
             sb.append(base64EncodeChars[b1 >>> 2 ]);
             sb.append(base64EncodeChars[((b1 & 0x03 ) << 4 ) | ((b2 & 0xf0 ) >>> 4 )]);
             sb.append(base64EncodeChars[((b2 & 0x0f ) << 2 ) | ((b3 & 0xc0 ) >>> 6 )]);
             sb.append(base64EncodeChars[b3 & 0x3f ]);
         }
         return sb.toString();
     }
 
     /**
      * 解密
      *
      * @param str
      * @return
      */
     public static byte [] decode(String str)
     {
         try
         {
             return decodePrivate(str);
         } catch (UnsupportedEncodingException e)
         {
             e.printStackTrace();
         }
         return new byte []
         {};
     }
 
     private static byte [] decodePrivate(String str) throws UnsupportedEncodingException
     {
         StringBuffer sb = new StringBuffer();
         byte [] data = null ;
         data = str.getBytes(US-ASCII);
         int len = data.length;
         int i = 0 ;
         int b1, b2, b3, b4;
         while (i < len)
         {
 
             do
             {
                 b1 = base64DecodeChars[data[i++]];
             } while (i < len && b1 == - 1 );
             if (b1 == - 1 )
                 break ;
 
             do
             {
                 b2 = base64DecodeChars[data[i++]];
             } while (i < len && b2 == - 1 );
             if (b2 == - 1 )
                 break ;
             sb.append(( char ) ((b1 << 2 ) | ((b2 & 0x30 ) >>> 4 )));
 
             do
             {
                 b3 = data[i++];
                 if (b3 == 61 )
                     return sb.toString().getBytes(iso8859- 1 );
                 b3 = base64DecodeChars[b3];
             } while (i < len && b3 == - 1 );
             if (b3 == - 1 )
                 break ;
             sb.append(( char ) (((b2 & 0x0f ) << 4 ) | ((b3 & 0x3c ) >>> 2 )));
 
             do
             {
                 b4 = data[i++];
                 if (b4 == 61 )
                     return sb.toString().getBytes(iso8859- 1 );
                 b4 = base64DecodeChars[b4];
             } while (i < len && b4 == - 1 );
             if (b4 == - 1 )
                 break ;
             sb.append(( char ) (((b3 & 0x03 ) << 6 ) | b4));
         }
         return sb.toString().getBytes(iso8859- 1 );
     }
 
}

最后就是真正使用它们了:

 

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.example.rsa;
 
import java.io.InputStream;
import java.security.PrivateKey;
import java.security.PublicKey;
 
import android.app.Activity;
import android.os.Bundle;
import android.util.Base64;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
 
public class MainActivity extends Activity implements OnClickListener
{
     private Button btn1, btn2; // 加密,解密
     private EditText et1, et2, et3; // 需加密的内容,加密后的内容,解密后的内容
 
     /* 密钥内容 base64 code */
     private static String PUCLIC_KEY = MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfRTdcPIH10gT9f31rQuIInLwe
             +
  + 7fl2dtEJ93gTmjE9c2H+kLVENWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThra +
 
             + z/L3nYJYlbqjHC3jTjUnZc0luumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG +
 
             + 9aYqgE7zyTRZYX9byQIDAQAB +
;
     private static String PRIVATE_KEY = MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ9FN1w8gfXSBP1/
             +
  + fWtC4gicvB7t+XZ20Qn3eBOaMT1zYf6QtUQ1aAQKIlVDmyidA1/BOgwp07Rvc6V/ +
 
             + imAEp4tOGtrP8vedgliVuqMcLeNONSdlzSW66alcayjHrb4+5IYGV9vzMk7qGLHg +
 
             + ZX++HJBUKkb1piqATvPJNFlhf1vJAgMBAAECgYA736xhG0oL3EkN9yhx8zG/5RP/ +
 
             + WJzoQOByq7pTPCr4m/Ch30qVerJAmoKvpPumN+h1zdEBk5PHiAJkm96sG/PTndEf +
 
             + kZrAJ2hwSBqptcABYk6ED70gRTQ1S53tyQXIOSjRBcugY/21qeswS3nMyq3xDEPK +
 
             + XpdyKPeaTyuK86AEkQJBAM1M7p1lfzEKjNw17SDMLnca/8pBcA0EEcyvtaQpRvaL +
 
             + n61eQQnnPdpvHamkRBcOvgCAkfwa1uboru0QdXii/gUCQQDGmkP+KJPX9JVCrbRt +
 
             + 7wKyIemyNM+J6y1ZBZ2bVCf9jacCQaSkIWnIR1S9UM+1CFE30So2CA0CfCDmQy+y +
 
             + 7A31AkB8cGFB7j+GTkrLP7SX6KtRboAU7E0q1oijdO24r3xf/Imw4Cy0AAIx4KAu +
 
             + L29GOp1YWJYkJXCVTfyZnRxXHxSxAkEAvO0zkSv4uI8rDmtAIPQllF8+eRBT/deD +
 
             + JBR7ga/k+wctwK/Bd4Fxp9xzeETP0l8/I+IOTagK+Dos8d8oGQUFoQJBAI4Nwpfo +
 
             + MFaLJXGY9ok45wXrcqkJgM+SN6i8hQeujXESVHYatAIL/1DgLi+u46EFD69fw0w+ +
  + c7o0HLlMsYPAzJw=
             +
;
 
     @Override
     protected void onCreate(Bundle savedInstanceState)
     {
         super .onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         initView();
     }
 
     private void initView()
     {
         btn1 = (Button) findViewById(R.id.btn1);
         btn2 = (Button) findViewById(R.id.btn2);
         btn1.setOnClickListener( this );
         btn2.setOnClickListener( this );
 
         et1 = (EditText) findViewById(R.id.et1);
         et2 = (EditText) findViewById(R.id.et2);
         et3 = (EditText) findViewById(R.id.et3);
     }
 
     @Override
     public void onClick(View v)
     {
         switch (v.getId())
         {
         // 加密
         case R.id.btn1:
             String source = et1.getText().toString().trim();
             try
             {
                 // 从字符串中得到公钥
                 // PublicKey publicKey = RSAUtils.loadPublicKey(PUCLIC_KEY);
                 // 从文件中得到公钥
                 InputStream inPublic = getResources().getAssets().open(rsa_public_key.pem);
                 PublicKey publicKey = RSAUtils.loadPublicKey(inPublic);
                 // 加密
                 byte [] encryptByte = RSAUtils.encryptData(source.getBytes(), publicKey);
                 // 为了方便观察吧加密后的数据用base64加密转一下,要不然看起来是乱码,所以解密是也是要用Base64先转换
                 String afterencrypt = Base64Utils.encode(encryptByte);
                 et2.setText(afterencrypt);
             } catch (Exception e)
             {
                 e.printStackTrace();
             }
             break ;
         // 解密
         case R.id.btn2:
             String encryptContent = et2.getText().toString().trim();
             try
             {
                 // 从字符串中得到私钥
                 // PrivateKey privateKey = RSAUtils.loadPrivateKey(PRIVATE_KEY);
                 // 从文件中得到私钥
                 InputStream inPrivate = getResources().getAssets().open(pkcs8_rsa_private_key.pem);
                 PrivateKey privateKey = RSAUtils.loadPrivateKey(inPrivate);
                 // 因为RSA加密后的内容经Base64再加密转换了一下,所以先Base64解密回来再给RSA解密
                 byte [] decryptByte = RSAUtils.decryptData(Base64Utils.decode(encryptContent), privateKey);
                 String decryptStr = new String(decryptByte);
                 et3.setText(decryptStr);
             } catch (Exception e)
             {
                 e.printStackTrace();
             }
             break ;
         default :
             break ;
         }
     }
 
}

我把密钥放到assest资源文件夹里了,也可以直接使用字符串得到,上面注释掉了。

 

最后我们来看下效果吧:

\

 

源码下载地址:http://download.csdn.net/detail/bbld_/7806673

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值