├── README.md
└── rsa_encrypt_decrypt_demo
├── .classpath
├── .gitignore
├── .project
├── .settings
├── .jsdtscope
├── org.eclipse.core.resources.prefs
├── org.eclipse.jdt.core.prefs
├── org.eclipse.m2e.core.prefs
├── org.eclipse.wst.common.component
├── org.eclipse.wst.common.project.facet.core.xml
├── org.eclipse.wst.jsdt.ui.superType.container
└── org.eclipse.wst.jsdt.ui.superType.name
├── WebContent
├── META-INF
│ └── MANIFEST.MF
├── WEB-INF
│ ├── ftl
│ │ └── rsa.ftl
│ ├── spring-context.xml
│ └── web.xml
└── js
│ ├── Barrett.js
│ ├── BigInt.js
│ └── RSA.js
├── pom.xml
└── src
└── seamonster
└── demo
├── InitializeService.java
├── MyDemo.java
└── RSAUtils.java
/README.md:
--------------------------------------------------------------------------------
1 | # rsa_javaweb_javascript
2 |
3 | 很简单的前端+后端,使用RSA加密解密,找了网上很多文章,居然没有一个完整的能跑通的例子,只好自己动手写一个。
4 |
5 | RSA加密的内容长度有限,所以要么是只加密敏感内容,要么是结合其他对称加密例如AES使用(使用对称加密方式来加解密内容,用RSA来加解密对称加密的密钥)
6 |
7 | 参考
8 | http://www.justabug.net/door-1-rsa/ 这个已经说得挺详细了,也解决了其中遇到的一些问题,但竟然也有部分是错的
9 |
10 |
11 | http://sunxboy.iteye.com/blog/209156 本demo使用到的js就是这里提供的
12 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.classpath:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build/
2 | /target/
3 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | rsa_encrypt_decrypt_demo
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.wst.jsdt.core.javascriptValidator
10 |
11 |
12 |
13 |
14 | org.eclipse.jdt.core.javabuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.wst.common.project.facet.core.builder
20 |
21 |
22 |
23 |
24 | org.eclipse.wst.validation.validationbuilder
25 |
26 |
27 |
28 |
29 | org.eclipse.m2e.core.maven2Builder
30 |
31 |
32 |
33 |
34 |
35 | org.eclipse.m2e.core.maven2Nature
36 | org.eclipse.jem.workbench.JavaEMFNature
37 | org.eclipse.wst.common.modulecore.ModuleCoreNature
38 | org.eclipse.wst.common.project.facet.core.nature
39 | org.eclipse.jdt.core.javanature
40 | org.eclipse.wst.jsdt.core.jsNature
41 |
42 |
43 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/.jsdtscope:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding/=UTF-8
3 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
4 | org.eclipse.jdt.core.compiler.compliance=1.6
5 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
6 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
7 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
8 | org.eclipse.jdt.core.compiler.source=1.6
9 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.wst.common.component:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.wst.common.project.facet.core.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.wst.jsdt.ui.superType.container:
--------------------------------------------------------------------------------
1 | org.eclipse.wst.jsdt.launching.baseBrowserLibrary
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/.settings/org.eclipse.wst.jsdt.ui.superType.name:
--------------------------------------------------------------------------------
1 | Window
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/WEB-INF/ftl/rsa.ftl:
--------------------------------------------------------------------------------
1 | <#import "spring.ftl" as spring />
2 |
3 |
4 |
5 |
6 |
7 | RSA Demo
8 |
9 |
10 |
11 | 请输入要加密的内容:
12 |
13 |
14 | 服务端返回的内容
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
65 |
66 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/WEB-INF/spring-context.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | application/json;charset=UTF-8
22 | text/plain;charset=UTF-8
23 |
24 |
25 |
26 |
27 |
28 |
29 | application/json;charset=UTF8
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | rsa_encrypt_decrypt_demo
4 |
5 | index.html
6 | index.htm
7 | index.jsp
8 | default.html
9 | default.htm
10 | default.jsp
11 |
12 |
13 |
14 | contextConfigLocation
15 |
16 | /WEB-INF/spring-context.xml
17 |
18 |
19 |
20 |
21 | org.springframework.web.context.ContextLoaderListener
22 |
23 |
24 |
25 | action
26 | org.springframework.web.servlet.DispatcherServlet
27 |
28 | contextConfigLocation
29 | /WEB-INF/spring-context.xml
30 |
31 | 1
32 |
33 |
34 | action
35 | /s/*
36 |
37 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/js/Barrett.js:
--------------------------------------------------------------------------------
1 | // BarrettMu, a class for performing Barrett modular reduction computations in
2 | // JavaScript.
3 | //
4 | // Requires BigInt.js.
5 | //
6 | // Copyright 2004-2005 David Shapiro.
7 | //
8 | // You may use, re-use, abuse, copy, and modify this code to your liking, but
9 | // please keep this header.
10 | //
11 | // Thanks!
12 | //
13 | // Dave Shapiro
14 | // dave@ohdave.com
15 |
16 | function BarrettMu(m)
17 | {
18 | this.modulus = biCopy(m);
19 | this.k = biHighIndex(this.modulus) + 1;
20 | var b2k = new BigInt();
21 | b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
22 | this.mu = biDivide(b2k, this.modulus);
23 | this.bkplus1 = new BigInt();
24 | this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
25 | this.modulo = BarrettMu_modulo;
26 | this.multiplyMod = BarrettMu_multiplyMod;
27 | this.powMod = BarrettMu_powMod;
28 | }
29 |
30 | function BarrettMu_modulo(x)
31 | {
32 | var q1 = biDivideByRadixPower(x, this.k - 1);
33 | var q2 = biMultiply(q1, this.mu);
34 | var q3 = biDivideByRadixPower(q2, this.k + 1);
35 | var r1 = biModuloByRadixPower(x, this.k + 1);
36 | var r2term = biMultiply(q3, this.modulus);
37 | var r2 = biModuloByRadixPower(r2term, this.k + 1);
38 | var r = biSubtract(r1, r2);
39 | if (r.isNeg) {
40 | r = biAdd(r, this.bkplus1);
41 | }
42 | var rgtem = biCompare(r, this.modulus) >= 0;
43 | while (rgtem) {
44 | r = biSubtract(r, this.modulus);
45 | rgtem = biCompare(r, this.modulus) >= 0;
46 | }
47 | return r;
48 | }
49 |
50 | function BarrettMu_multiplyMod(x, y)
51 | {
52 | /*
53 | x = this.modulo(x);
54 | y = this.modulo(y);
55 | */
56 | var xy = biMultiply(x, y);
57 | return this.modulo(xy);
58 | }
59 |
60 | function BarrettMu_powMod(x, y)
61 | {
62 | var result = new BigInt();
63 | result.digits[0] = 1;
64 | var a = x;
65 | var k = y;
66 | while (true) {
67 | if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
68 | k = biShiftRight(k, 1);
69 | if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
70 | a = this.multiplyMod(a, a);
71 | }
72 | return result;
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/js/BigInt.js:
--------------------------------------------------------------------------------
1 | // BigInt, a suite of routines for performing multiple-precision arithmetic in
2 | // JavaScript.
3 | //
4 | // Copyright 1998-2005 David Shapiro.
5 | //
6 | // You may use, re-use, abuse,
7 | // copy, and modify this code to your liking, but please keep this header.
8 | // Thanks!
9 | //
10 | // Dave Shapiro
11 | // dave@ohdave.com
12 |
13 | // IMPORTANT THING: Be sure to set maxDigits according to your precision
14 | // needs. Use the setMaxDigits() function to do this. See comments below.
15 | //
16 | // Tweaked by Ian Bunning
17 | // Alterations:
18 | // Fix bug in function biFromHex(s) to allow
19 | // parsing of strings of length != 0 (mod 4)
20 |
21 | // Changes made by Dave Shapiro as of 12/30/2004:
22 | //
23 | // The BigInt() constructor doesn't take a string anymore. If you want to
24 | // create a BigInt from a string, use biFromDecimal() for base-10
25 | // representations, biFromHex() for base-16 representations, or
26 | // biFromString() for base-2-to-36 representations.
27 | //
28 | // biFromArray() has been removed. Use biCopy() instead, passing a BigInt
29 | // instead of an array.
30 | //
31 | // The BigInt() constructor now only constructs a zeroed-out array.
32 | // Alternatively, if you pass , it won't construct any array. See the
33 | // biCopy() method for an example of this.
34 | //
35 | // Be sure to set maxDigits depending on your precision needs. The default
36 | // zeroed-out array ZERO_ARRAY is constructed inside the setMaxDigits()
37 | // function. So use this function to set the variable. DON'T JUST SET THE
38 | // VALUE. USE THE FUNCTION.
39 | //
40 | // ZERO_ARRAY exists to hopefully speed up construction of BigInts(). By
41 | // precalculating the zero array, we can just use slice(0) to make copies of
42 | // it. Presumably this calls faster native code, as opposed to setting the
43 | // elements one at a time. I have not done any timing tests to verify this
44 | // claim.
45 |
46 | // Max number = 10^16 - 2 = 9999999999999998;
47 | // 2^53 = 9007199254740992;
48 |
49 | var biRadixBase = 2;
50 | var biRadixBits = 16;
51 | var bitsPerDigit = biRadixBits;
52 | var biRadix = 1 << 16; // = 2^16 = 65536
53 | var biHalfRadix = biRadix >>> 1;
54 | var biRadixSquared = biRadix * biRadix;
55 | var maxDigitVal = biRadix - 1;
56 | var maxInteger = 9999999999999998;
57 |
58 | // maxDigits:
59 | // Change this to accommodate your largest number size. Use setMaxDigits()
60 | // to change it!
61 | //
62 | // In general, if you're working with numbers of size N bits, you'll need 2*N
63 | // bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need
64 | //
65 | // 1024 * 2 / 16 = 128 digits of storage.
66 | //
67 |
68 | var maxDigits;
69 | var ZERO_ARRAY;
70 | var bigZero, bigOne;
71 |
72 | function setMaxDigits(value)
73 | {
74 | maxDigits = value;
75 | ZERO_ARRAY = new Array(maxDigits);
76 | for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0;
77 | bigZero = new BigInt();
78 | bigOne = new BigInt();
79 | bigOne.digits[0] = 1;
80 | }
81 |
82 | setMaxDigits(20);
83 |
84 | // The maximum number of digits in base 10 you can convert to an
85 | // integer without JavaScript throwing up on you.
86 | var dpl10 = 15;
87 | // lr10 = 10 ^ dpl10
88 | var lr10 = biFromNumber(1000000000000000);
89 |
90 | function BigInt(flag)
91 | {
92 | if (typeof flag == "boolean" && flag == true) {
93 | this.digits = null;
94 | }
95 | else {
96 | this.digits = ZERO_ARRAY.slice(0);
97 | }
98 | this.isNeg = false;
99 | }
100 |
101 | function biFromDecimal(s)
102 | {
103 | var isNeg = s.charAt(0) == '-';
104 | var i = isNeg ? 1 : 0;
105 | var result;
106 | // Skip leading zeros.
107 | while (i < s.length && s.charAt(i) == '0') ++i;
108 | if (i == s.length) {
109 | result = new BigInt();
110 | }
111 | else {
112 | var digitCount = s.length - i;
113 | var fgl = digitCount % dpl10;
114 | if (fgl == 0) fgl = dpl10;
115 | result = biFromNumber(Number(s.substr(i, fgl)));
116 | i += fgl;
117 | while (i < s.length) {
118 | result = biAdd(biMultiply(result, lr10),
119 | biFromNumber(Number(s.substr(i, dpl10))));
120 | i += dpl10;
121 | }
122 | result.isNeg = isNeg;
123 | }
124 | return result;
125 | }
126 |
127 | function biCopy(bi)
128 | {
129 | var result = new BigInt(true);
130 | result.digits = bi.digits.slice(0);
131 | result.isNeg = bi.isNeg;
132 | return result;
133 | }
134 |
135 | function biFromNumber(i)
136 | {
137 | var result = new BigInt();
138 | result.isNeg = i < 0;
139 | i = Math.abs(i);
140 | var j = 0;
141 | while (i > 0) {
142 | result.digits[j++] = i & maxDigitVal;
143 | i = Math.floor(i / biRadix);
144 | }
145 | return result;
146 | }
147 |
148 | function reverseStr(s)
149 | {
150 | var result = "";
151 | for (var i = s.length - 1; i > -1; --i) {
152 | result += s.charAt(i);
153 | }
154 | return result;
155 | }
156 |
157 | var hexatrigesimalToChar = new Array(
158 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
159 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
160 | 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
161 | 'u', 'v', 'w', 'x', 'y', 'z'
162 | );
163 |
164 | function biToString(x, radix)
165 | // 2 <= radix <= 36
166 | {
167 | var b = new BigInt();
168 | b.digits[0] = radix;
169 | var qr = biDivideModulo(x, b);
170 | var result = hexatrigesimalToChar[qr[1].digits[0]];
171 | while (biCompare(qr[0], bigZero) == 1) {
172 | qr = biDivideModulo(qr[0], b);
173 | digit = qr[1].digits[0];
174 | result += hexatrigesimalToChar[qr[1].digits[0]];
175 | }
176 | return (x.isNeg ? "-" : "") + reverseStr(result);
177 | }
178 |
179 | function biToDecimal(x)
180 | {
181 | var b = new BigInt();
182 | b.digits[0] = 10;
183 | var qr = biDivideModulo(x, b);
184 | var result = String(qr[1].digits[0]);
185 | while (biCompare(qr[0], bigZero) == 1) {
186 | qr = biDivideModulo(qr[0], b);
187 | result += String(qr[1].digits[0]);
188 | }
189 | return (x.isNeg ? "-" : "") + reverseStr(result);
190 | }
191 |
192 | var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
193 | 'a', 'b', 'c', 'd', 'e', 'f');
194 |
195 | function digitToHex(n)
196 | {
197 | var mask = 0xf;
198 | var result = "";
199 | for (i = 0; i < 4; ++i) {
200 | result += hexToChar[n & mask];
201 | n >>>= 4;
202 | }
203 | return reverseStr(result);
204 | }
205 |
206 | function biToHex(x)
207 | {
208 | var result = "";
209 | var n = biHighIndex(x);
210 | for (var i = biHighIndex(x); i > -1; --i) {
211 | result += digitToHex(x.digits[i]);
212 | }
213 | return result;
214 | }
215 |
216 | function charToHex(c)
217 | {
218 | var ZERO = 48;
219 | var NINE = ZERO + 9;
220 | var littleA = 97;
221 | var littleZ = littleA + 25;
222 | var bigA = 65;
223 | var bigZ = 65 + 25;
224 | var result;
225 |
226 | if (c >= ZERO && c <= NINE) {
227 | result = c - ZERO;
228 | } else if (c >= bigA && c <= bigZ) {
229 | result = 10 + c - bigA;
230 | } else if (c >= littleA && c <= littleZ) {
231 | result = 10 + c - littleA;
232 | } else {
233 | result = 0;
234 | }
235 | return result;
236 | }
237 |
238 | function hexToDigit(s)
239 | {
240 | var result = 0;
241 | var sl = Math.min(s.length, 4);
242 | for (var i = 0; i < sl; ++i) {
243 | result <<= 4;
244 | result |= charToHex(s.charCodeAt(i))
245 | }
246 | return result;
247 | }
248 |
249 | function biFromHex(s)
250 | {
251 | var result = new BigInt();
252 | var sl = s.length;
253 | for (var i = sl, j = 0; i > 0; i -= 4, ++j) {
254 | result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4)));
255 | }
256 | return result;
257 | }
258 |
259 | function biFromString(s, radix)
260 | {
261 | var isNeg = s.charAt(0) == '-';
262 | var istop = isNeg ? 1 : 0;
263 | var result = new BigInt();
264 | var place = new BigInt();
265 | place.digits[0] = 1; // radix^0
266 | for (var i = s.length - 1; i >= istop; i--) {
267 | var c = s.charCodeAt(i);
268 | var digit = charToHex(c);
269 | var biDigit = biMultiplyDigit(place, digit);
270 | result = biAdd(result, biDigit);
271 | place = biMultiplyDigit(place, radix);
272 | }
273 | result.isNeg = isNeg;
274 | return result;
275 | }
276 |
277 | function biDump(b)
278 | {
279 | return (b.isNeg ? "-" : "") + b.digits.join(" ");
280 | }
281 |
282 | function biAdd(x, y)
283 | {
284 | var result;
285 |
286 | if (x.isNeg != y.isNeg) {
287 | y.isNeg = !y.isNeg;
288 | result = biSubtract(x, y);
289 | y.isNeg = !y.isNeg;
290 | }
291 | else {
292 | result = new BigInt();
293 | var c = 0;
294 | var n;
295 | for (var i = 0; i < x.digits.length; ++i) {
296 | n = x.digits[i] + y.digits[i] + c;
297 | result.digits[i] = n % biRadix;
298 | c = Number(n >= biRadix);
299 | }
300 | result.isNeg = x.isNeg;
301 | }
302 | return result;
303 | }
304 |
305 | function biSubtract(x, y)
306 | {
307 | var result;
308 | if (x.isNeg != y.isNeg) {
309 | y.isNeg = !y.isNeg;
310 | result = biAdd(x, y);
311 | y.isNeg = !y.isNeg;
312 | } else {
313 | result = new BigInt();
314 | var n, c;
315 | c = 0;
316 | for (var i = 0; i < x.digits.length; ++i) {
317 | n = x.digits[i] - y.digits[i] + c;
318 | result.digits[i] = n % biRadix;
319 | // Stupid non-conforming modulus operation.
320 | if (result.digits[i] < 0) result.digits[i] += biRadix;
321 | c = 0 - Number(n < 0);
322 | }
323 | // Fix up the negative sign, if any.
324 | if (c == -1) {
325 | c = 0;
326 | for (var i = 0; i < x.digits.length; ++i) {
327 | n = 0 - result.digits[i] + c;
328 | result.digits[i] = n % biRadix;
329 | // Stupid non-conforming modulus operation.
330 | if (result.digits[i] < 0) result.digits[i] += biRadix;
331 | c = 0 - Number(n < 0);
332 | }
333 | // Result is opposite sign of arguments.
334 | result.isNeg = !x.isNeg;
335 | } else {
336 | // Result is same sign.
337 | result.isNeg = x.isNeg;
338 | }
339 | }
340 | return result;
341 | }
342 |
343 |
344 | function biHighIndex(x)
345 | {
346 | var result = x.digits.length - 1;
347 | while (result > 0 && x.digits[result] == 0) --result;
348 | return result;
349 | }
350 |
351 | function biNumBits(x)
352 | {
353 | var n = biHighIndex(x);
354 | var d = x.digits[n];
355 | var m = (n + 1) * bitsPerDigit;
356 | var result;
357 | for (result = m; result > m - bitsPerDigit; --result) {
358 | if ((d & 0x8000) != 0) break;
359 | d <<= 1;
360 | }
361 | return result;
362 | }
363 |
364 | function biMultiply(x, y)
365 | {
366 | var result = new BigInt();
367 | var c;
368 | var n = biHighIndex(x);
369 | var t = biHighIndex(y);
370 | var u, uv, k;
371 |
372 | for (var i = 0; i <= t; ++i) {
373 | c = 0;
374 | k = i;
375 | for (j = 0; j <= n; ++j, ++k) {
376 | uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
377 | result.digits[k] = uv & maxDigitVal;
378 | c = uv >>> biRadixBits;
379 | //c = Math.floor(uv / biRadix);
380 | }
381 | result.digits[i + n + 1] = c;
382 | }
383 | // Someone give me a logical xor, please.
384 | result.isNeg = x.isNeg != y.isNeg;
385 | return result;
386 | }
387 |
388 | function biMultiplyDigit(x, y)
389 | {
390 | var n, c, uv;
391 |
392 | result = new BigInt();
393 | n = biHighIndex(x);
394 | c = 0;
395 | for (var j = 0; j <= n; ++j) {
396 | uv = result.digits[j] + x.digits[j] * y + c;
397 | result.digits[j] = uv & maxDigitVal;
398 | c = uv >>> biRadixBits;
399 | //c = Math.floor(uv / biRadix);
400 | }
401 | result.digits[1 + n] = c;
402 | return result;
403 | }
404 |
405 | function arrayCopy(src, srcStart, dest, destStart, n)
406 | {
407 | var m = Math.min(srcStart + n, src.length);
408 | for (var i = srcStart, j = destStart; i < m; ++i, ++j) {
409 | dest[j] = src[i];
410 | }
411 | }
412 |
413 | var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800,
414 | 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0,
415 | 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF);
416 |
417 | function biShiftLeft(x, n)
418 | {
419 | var digitCount = Math.floor(n / bitsPerDigit);
420 | var result = new BigInt();
421 | arrayCopy(x.digits, 0, result.digits, digitCount,
422 | result.digits.length - digitCount);
423 | var bits = n % bitsPerDigit;
424 | var rightBits = bitsPerDigit - bits;
425 | for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) {
426 | result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) |
427 | ((result.digits[i1] & highBitMasks[bits]) >>>
428 | (rightBits));
429 | }
430 | result.digits[0] = ((result.digits[i] << bits) & maxDigitVal);
431 | result.isNeg = x.isNeg;
432 | return result;
433 | }
434 |
435 | var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
436 | 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,
437 | 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF);
438 |
439 | function biShiftRight(x, n)
440 | {
441 | var digitCount = Math.floor(n / bitsPerDigit);
442 | var result = new BigInt();
443 | arrayCopy(x.digits, digitCount, result.digits, 0,
444 | x.digits.length - digitCount);
445 | var bits = n % bitsPerDigit;
446 | var leftBits = bitsPerDigit - bits;
447 | for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) {
448 | result.digits[i] = (result.digits[i] >>> bits) |
449 | ((result.digits[i1] & lowBitMasks[bits]) << leftBits);
450 | }
451 | result.digits[result.digits.length - 1] >>>= bits;
452 | result.isNeg = x.isNeg;
453 | return result;
454 | }
455 |
456 | function biMultiplyByRadixPower(x, n)
457 | {
458 | var result = new BigInt();
459 | arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n);
460 | return result;
461 | }
462 |
463 | function biDivideByRadixPower(x, n)
464 | {
465 | var result = new BigInt();
466 | arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n);
467 | return result;
468 | }
469 |
470 | function biModuloByRadixPower(x, n)
471 | {
472 | var result = new BigInt();
473 | arrayCopy(x.digits, 0, result.digits, 0, n);
474 | return result;
475 | }
476 |
477 | function biCompare(x, y)
478 | {
479 | if (x.isNeg != y.isNeg) {
480 | return 1 - 2 * Number(x.isNeg);
481 | }
482 | for (var i = x.digits.length - 1; i >= 0; --i) {
483 | if (x.digits[i] != y.digits[i]) {
484 | if (x.isNeg) {
485 | return 1 - 2 * Number(x.digits[i] > y.digits[i]);
486 | } else {
487 | return 1 - 2 * Number(x.digits[i] < y.digits[i]);
488 | }
489 | }
490 | }
491 | return 0;
492 | }
493 |
494 | function biDivideModulo(x, y)
495 | {
496 | var nb = biNumBits(x);
497 | var tb = biNumBits(y);
498 | var origYIsNeg = y.isNeg;
499 | var q, r;
500 | if (nb < tb) {
501 | // |x| < |y|
502 | if (x.isNeg) {
503 | q = biCopy(bigOne);
504 | q.isNeg = !y.isNeg;
505 | x.isNeg = false;
506 | y.isNeg = false;
507 | r = biSubtract(y, x);
508 | // Restore signs, 'cause they're references.
509 | x.isNeg = true;
510 | y.isNeg = origYIsNeg;
511 | } else {
512 | q = new BigInt();
513 | r = biCopy(x);
514 | }
515 | return new Array(q, r);
516 | }
517 |
518 | q = new BigInt();
519 | r = x;
520 |
521 | // Normalize Y.
522 | var t = Math.ceil(tb / bitsPerDigit) - 1;
523 | var lambda = 0;
524 | while (y.digits[t] < biHalfRadix) {
525 | y = biShiftLeft(y, 1);
526 | ++lambda;
527 | ++tb;
528 | t = Math.ceil(tb / bitsPerDigit) - 1;
529 | }
530 | // Shift r over to keep the quotient constant. We'll shift the
531 | // remainder back at the end.
532 | r = biShiftLeft(r, lambda);
533 | nb += lambda; // Update the bit count for x.
534 | var n = Math.ceil(nb / bitsPerDigit) - 1;
535 |
536 | var b = biMultiplyByRadixPower(y, n - t);
537 | while (biCompare(r, b) != -1) {
538 | ++q.digits[n - t];
539 | r = biSubtract(r, b);
540 | }
541 | for (var i = n; i > t; --i) {
542 | var ri = (i >= r.digits.length) ? 0 : r.digits[i];
543 | var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
544 | var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
545 | var yt = (t >= y.digits.length) ? 0 : y.digits[t];
546 | var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
547 | if (ri == yt) {
548 | q.digits[i - t - 1] = maxDigitVal;
549 | } else {
550 | q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
551 | }
552 |
553 | var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
554 | var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
555 | while (c1 > c2) {
556 | --q.digits[i - t - 1];
557 | c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
558 | c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
559 | }
560 |
561 | b = biMultiplyByRadixPower(y, i - t - 1);
562 | r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
563 | if (r.isNeg) {
564 | r = biAdd(r, b);
565 | --q.digits[i - t - 1];
566 | }
567 | }
568 | r = biShiftRight(r, lambda);
569 | // Fiddle with the signs and stuff to make sure that 0 <= r < y.
570 | q.isNeg = x.isNeg != origYIsNeg;
571 | if (x.isNeg) {
572 | if (origYIsNeg) {
573 | q = biAdd(q, bigOne);
574 | } else {
575 | q = biSubtract(q, bigOne);
576 | }
577 | y = biShiftRight(y, lambda);
578 | r = biSubtract(y, r);
579 | }
580 | // Check for the unbelievably stupid degenerate case of r == -0.
581 | if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false;
582 |
583 | return new Array(q, r);
584 | }
585 |
586 | function biDivide(x, y)
587 | {
588 | return biDivideModulo(x, y)[0];
589 | }
590 |
591 | function biModulo(x, y)
592 | {
593 | return biDivideModulo(x, y)[1];
594 | }
595 |
596 | function biMultiplyMod(x, y, m)
597 | {
598 | return biModulo(biMultiply(x, y), m);
599 | }
600 |
601 | function biPow(x, y)
602 | {
603 | var result = bigOne;
604 | var a = x;
605 | while (true) {
606 | if ((y & 1) != 0) result = biMultiply(result, a);
607 | y >>= 1;
608 | if (y == 0) break;
609 | a = biMultiply(a, a);
610 | }
611 | return result;
612 | }
613 |
614 | function biPowMod(x, y, m)
615 | {
616 | var result = bigOne;
617 | var a = x;
618 | var k = y;
619 | while (true) {
620 | if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m);
621 | k = biShiftRight(k, 1);
622 | if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
623 | a = biMultiplyMod(a, a, m);
624 | }
625 | return result;
626 | }
627 |
628 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/WebContent/js/RSA.js:
--------------------------------------------------------------------------------
1 | // RSA, a suite of routines for performing RSA public-key computations in
2 | // JavaScript.
3 | //
4 | // Requires BigInt.js and Barrett.js.
5 | //
6 | // Copyright 1998-2005 David Shapiro.
7 | //
8 | // You may use, re-use, abuse, copy, and modify this code to your liking, but
9 | // please keep this header.
10 | //
11 | // Thanks!
12 | //
13 | // Dave Shapiro
14 | // dave@ohdave.com
15 |
16 | function RSAKeyPair(encryptionExponent, decryptionExponent, modulus)
17 | {
18 | this.e = biFromHex(encryptionExponent);
19 | this.d = biFromHex(decryptionExponent);
20 | this.m = biFromHex(modulus);
21 | // We can do two bytes per digit, so
22 | // chunkSize = 2 * (number of digits in modulus - 1).
23 | // Since biHighIndex returns the high index, not the number of digits, 1 has
24 | // already been subtracted.
25 | this.chunkSize = 2 * biHighIndex(this.m);
26 | this.radix = 16;
27 | this.barrett = new BarrettMu(this.m);
28 | }
29 |
30 | function twoDigit(n)
31 | {
32 | return (n < 10 ? "0" : "") + String(n);
33 | }
34 |
35 | function encryptedString(key, s)
36 | // Altered by Rob Saunders (rob@robsaunders.net). New routine pads the
37 | // string after it has been converted to an array. This fixes an
38 | // incompatibility with Flash MX's ActionScript.
39 | {
40 | var a = new Array();
41 | var sl = s.length;
42 | var i = 0;
43 | while (i < sl) {
44 | a[i] = s.charCodeAt(i);
45 | i++;
46 | }
47 |
48 | while (a.length % key.chunkSize != 0) {
49 | a[i++] = 0;
50 | }
51 |
52 | var al = a.length;
53 | var result = "";
54 | var j, k, block;
55 | for (i = 0; i < al; i += key.chunkSize) {
56 | block = new BigInt();
57 | j = 0;
58 | for (k = i; k < i + key.chunkSize; ++j) {
59 | block.digits[j] = a[k++];
60 | block.digits[j] += a[k++] << 8;
61 | }
62 | var crypt = key.barrett.powMod(block, key.e);
63 | var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix);
64 | result += text + " ";
65 | }
66 | return result.substring(0, result.length - 1); // Remove last space.
67 | }
68 |
69 | function decryptedString(key, s)
70 | {
71 | var blocks = s.split(" ");
72 | var result = "";
73 | var i, j, block;
74 | for (i = 0; i < blocks.length; ++i) {
75 | var bi;
76 | if (key.radix == 16) {
77 | bi = biFromHex(blocks[i]);
78 | }
79 | else {
80 | bi = biFromString(blocks[i], key.radix);
81 | }
82 | block = key.barrett.powMod(bi, key.d);
83 | for (j = 0; j <= biHighIndex(block); ++j) {
84 | result += String.fromCharCode(block.digits[j] & 255,
85 | block.digits[j] >> 8);
86 | }
87 | }
88 | // Remove trailing null, if any.
89 | if (result.charCodeAt(result.length - 1) == 0) {
90 | result = result.substring(0, result.length - 1);
91 | }
92 | return result;
93 | }
94 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 | 4.0.0
3 | rsa_encrypt_decrypt_demo
4 | rsa_encrypt_decrypt_demo
5 | 0.0.1-SNAPSHOT
6 |
7 | src
8 |
9 |
10 | maven-compiler-plugin
11 | 3.1
12 |
13 | 1.6
14 | 1.6
15 |
16 |
17 |
18 |
19 |
20 |
21 | org.bouncycastle
22 | bcprov-jdk16
23 | 1.46
24 |
25 |
26 | org.freemarker
27 | freemarker
28 | 2.3.23
29 |
30 |
31 | org.springframework
32 | spring-webmvc
33 | 4.1.3.RELEASE
34 |
35 |
36 | org.springframework
37 | spring-context-support
38 | 4.1.3.RELEASE
39 |
40 |
41 | com.fasterxml.jackson.core
42 | jackson-databind
43 | 2.9.9.3
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/src/seamonster/demo/InitializeService.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package seamonster.demo;
5 |
6 | import org.springframework.beans.factory.InitializingBean;
7 | import org.springframework.stereotype.Service;
8 |
9 | /**
10 | * @author Dovahkiin
11 | *
12 | */
13 | @Service
14 | public class InitializeService implements InitializingBean {
15 |
16 | /* (non-Javadoc)
17 | * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
18 | */
19 | @Override
20 | public void afterPropertiesSet() throws Exception {
21 | //服务初始化时生成公钥密钥对
22 | RSAUtils.generateKeyPair(); //生成公钥密钥对
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/src/seamonster/demo/MyDemo.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package seamonster.demo;
5 |
6 | import java.util.HashMap;
7 | import java.util.Map;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 |
11 | import org.springframework.stereotype.Controller;
12 | import org.springframework.ui.Model;
13 | import org.springframework.web.bind.annotation.RequestMapping;
14 | import org.springframework.web.bind.annotation.RequestMethod;
15 | import org.springframework.web.bind.annotation.ResponseBody;
16 | import org.springframework.web.context.request.WebRequest;
17 |
18 |
19 | /**
20 | * @author Dovahkiin
21 | *
22 | */
23 | @Controller
24 | @RequestMapping(value = "/rsa")
25 | public class MyDemo {
26 |
27 | @RequestMapping(method=RequestMethod.GET)
28 | public String doGet(HttpServletRequest req, Model model){
29 | try{
30 |
31 |
32 | //返回n和e到页面上,有这两个值就能得出公钥
33 | model.addAttribute("n", RSAUtils.getModulus());
34 | model.addAttribute("e", RSAUtils.getPublicExponent());
35 |
36 | }catch(Exception e){
37 | e.printStackTrace();
38 | }
39 |
40 | return "rsa";// rsa.ftl
41 |
42 | }
43 |
44 | @RequestMapping(params = "action=test")
45 | @ResponseBody
46 | public Map test(WebRequest req) {
47 | try{
48 | Map resultMap = new HashMap();
49 | String str = req.getParameter("data");
50 | String decryptResult = RSAUtils.decryptPrivate(str);
51 |
52 | //以上是前端js加密,后端java解密
53 |
54 | //以下是后端java加密,前端js解密
55 | String encryptResult = RSAUtils.encryptPrivate(decryptResult);
56 | resultMap.put("encryptResult", encryptResult);
57 | return resultMap;
58 | }catch(Exception e){
59 | e.printStackTrace();
60 | return null;
61 | }
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/rsa_encrypt_decrypt_demo/src/seamonster/demo/RSAUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | */
4 | package seamonster.demo;
5 |
6 | import java.io.ByteArrayOutputStream;
7 | import java.math.BigInteger;
8 | import java.net.URLDecoder;
9 | import java.net.URLEncoder;
10 | import java.security.Key;
11 | import java.security.KeyPair;
12 | import java.security.KeyPairGenerator;
13 | import java.security.SecureRandom;
14 |
15 | import javax.crypto.Cipher;
16 |
17 | import org.bouncycastle.jce.provider.BouncyCastleProvider;
18 | import org.bouncycastle.jce.provider.JCERSAPrivateKey;
19 | import org.bouncycastle.jce.provider.JCERSAPublicKey;
20 |
21 |
22 | /**
23 | * @author Dovahkiin
24 | *
25 | */
26 | public class RSAUtils {
27 | public static KeyPair KEY_PAIR = null;
28 | private static BouncyCastleProvider bouncyCastleProvider = new BouncyCastleProvider();
29 |
30 | /**
31 | * 生成公钥私钥
32 | */
33 | public static KeyPair generateKeyPair() throws Exception {
34 | try {
35 | KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA", bouncyCastleProvider);
36 | final int KEY_SIZE = 1024;// 没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
37 | // final int KEY_SIZE = 4096;
38 | keyPairGen.initialize(KEY_SIZE, new SecureRandom());
39 | KeyPair keyPair = keyPairGen.generateKeyPair();
40 |
41 | System.out.println(keyPair.getPrivate());
42 | System.out.println(keyPair.getPublic());
43 | KEY_PAIR = keyPair;
44 | return keyPair;
45 | } catch (Exception e) {
46 | throw new Exception(e.getMessage());
47 | }
48 | }
49 |
50 | /**
51 | * 用私钥加密
52 | */
53 | public static String encryptPrivate(String data) throws Exception {
54 | return encrypt(KEY_PAIR.getPrivate(), data);
55 | }
56 |
57 | /**
58 | * 用私钥解密
59 | */
60 | public static String decryptPrivate(String data) throws Exception {
61 | return decrypt(KEY_PAIR.getPrivate(), data);
62 | }
63 |
64 | private static String encrypt(Key pk, String data) throws Exception {
65 |
66 | System.out.println("需要加密的:" + data);
67 | String encodeStr = URLEncoder.encode(data, "UTF-8");
68 | System.out.println("Encode后的:" + encodeStr);
69 | String encodeStr2 = encodeStr.replace("+", "%20");
70 | System.out.println("+替换为%20:" + encodeStr2);
71 | byte[] b1 = encodeStr2.getBytes();
72 | byte[] b2 = encrypt(pk, b1);
73 | String encryptedString = byteToString(b2);
74 | System.out.println("加密后的:" + encryptedString);
75 | return encryptedString;
76 | }
77 |
78 | private static String decrypt(Key pk, String data) throws Exception {
79 | System.out.println("需要解密的:" + data);
80 | byte[] b1 = hexStringToBytes(data);
81 | byte[] b2 = decrypt(pk, b1);
82 | String decryptedString = new String(b2);
83 | System.out.println("解密后的:" + decryptedString);
84 | String reverseDecryptedString = new StringBuffer(decryptedString).reverse().toString();
85 | System.out.println("解密后再倒序:" + reverseDecryptedString);
86 | String resultString = URLDecoder.decode(reverseDecryptedString, "UTF-8");
87 | System.out.println("最后URLDecoder一下:" + resultString);
88 | return resultString;
89 | }
90 |
91 | /**
92 | * 返回公钥指数e
93 | */
94 | public static String getPublicExponent() {
95 | BigInteger b = ((JCERSAPublicKey) KEY_PAIR.getPublic()).getPublicExponent();
96 | return b.toString(16);
97 | }
98 |
99 | /**
100 | * 返回模值n
101 | */
102 | public static String getModulus() {
103 | BigInteger b = ((JCERSAPublicKey) KEY_PAIR.getPublic()).getModulus();
104 | return b.toString(16);
105 | }
106 |
107 | /**
108 | * 返回私钥指数d
109 | *
110 | * @return
111 | */
112 | public static String getPrivateExponent() {
113 | BigInteger b = ((JCERSAPrivateKey) KEY_PAIR.getPrivate()).getPrivateExponent();
114 | return b.toString(16);
115 | }
116 |
117 | /**
118 | * 加密
119 | *
120 | * @param key
121 | * 加密的密钥 (也可以是公钥)
122 | * @param data
123 | * 待加密的明文数据
124 | * @return 加密后的数据
125 | */
126 | private static byte[] encrypt(Key pk, byte[] data) throws Exception {
127 | try {
128 | Cipher cipher = Cipher.getInstance("RSA", bouncyCastleProvider);
129 | cipher.init(Cipher.ENCRYPT_MODE, pk);
130 | int blockSize = cipher.getBlockSize();// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024
131 | // 加密块大小为127
132 | // byte,加密后为128个byte;因此共有2个加密块,第一个127
133 | // byte第二个为1个byte
134 | int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
135 | int leavedSize = data.length % blockSize;
136 | int blocksSize = leavedSize != 0 ? data.length / blockSize + 1 : data.length / blockSize;
137 | byte[] raw = new byte[outputSize * blocksSize];
138 | int i = 0;
139 | while (data.length - i * blockSize > 0) {
140 | if (data.length - i * blockSize > blockSize)
141 | cipher.doFinal(data, i * blockSize, blockSize, raw, i * outputSize);
142 | else
143 | cipher.doFinal(data, i * blockSize, data.length - i * blockSize, raw, i * outputSize);
144 | // 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到
145 | // ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了
146 | // OutputSize所以只好用dofinal方法。
147 | i++;
148 | }
149 | return raw;
150 | } catch (Exception e) {
151 | throw new Exception(e.getMessage());
152 | }
153 | }
154 |
155 | /**
156 | * 解密
157 | *
158 | * @param key
159 | * 解密的密钥 (也可以是公钥)
160 | * @param raw
161 | * 已经加密的数据
162 | * @return 解密后的明文
163 | */
164 | private static byte[] decrypt(Key pk, byte[] raw) throws Exception {
165 | try {
166 | Cipher cipher = Cipher.getInstance("RSA", bouncyCastleProvider);
167 | cipher.init(Cipher.DECRYPT_MODE, pk);
168 | int blockSize = cipher.getBlockSize();
169 | ByteArrayOutputStream bout = new ByteArrayOutputStream(64);
170 | int j = 0;
171 | while (raw.length - j * blockSize > 0) {
172 | bout.write(cipher.doFinal(raw, j * blockSize, blockSize));
173 | j++;
174 | }
175 | return bout.toByteArray();
176 | } catch (Exception e) {
177 | throw new Exception(e.getMessage());
178 | }
179 | }
180 |
181 | private static byte[] hexStringToBytes(String hexString) {
182 | if (hexString == null || hexString.equals("")) {
183 | return null;
184 | }
185 | hexString = hexString.toUpperCase();
186 | int length = hexString.length() / 2;
187 | char[] hexChars = hexString.toCharArray();
188 | byte[] d = new byte[length];
189 | for (int i = 0; i < length; i++) {
190 | int pos = i * 2;
191 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
192 | }
193 | return d;
194 | }
195 |
196 | /** * Convert char to byte * @param c char * @return byte */
197 | private static byte charToByte(char c) {
198 | return (byte) "0123456789ABCDEF".indexOf(c);
199 | }
200 |
201 | /**
202 | * 把byte数组变换为16進数的字符串。
203 | *
204 | * @param bytes
205 | * byte数组
206 | * @return 16進数的字符串
207 | */
208 | private static String byteToString(byte[] bytes) {
209 | StringBuffer buf = new StringBuffer();
210 | for (int i = 0; i < bytes.length; i++) {
211 | int d = bytes[i];
212 | if (d < 0) {
213 | d += 256;
214 | }
215 | if (d < 16) {
216 | buf.append("0");
217 | }
218 | buf.append(Integer.toString(d, 16));
219 | }
220 | return buf.toString();
221 | }
222 |
223 | /**
224 | * 用公钥加密
225 | */
226 | public static String encryptPublic(String data) throws Exception {
227 | return encrypt(KEY_PAIR.getPublic(), data);
228 | }
229 |
230 | /**
231 | * 用公钥解密
232 | */
233 | public static String decryptPublic(String data) throws Exception {
234 | return decrypt(KEY_PAIR.getPublic(), data);
235 | }
236 |
237 |
238 | }
239 |
--------------------------------------------------------------------------------