RSA加解密和AES加解密

一、RSA 非對稱加密 有公鑰和私鑰兩把祕鑰,公鑰加密私鑰解密,私鑰加密公鑰解密,javascript

二、AES 對稱加密 只有一把密碼 AES分爲幾種模式,好比ECB,CBC,CFB等等,這些模式除了ECB因爲沒有使用IV而不太安全,其餘模式差異並無太明顯。 IV稱爲初始向量,不一樣的IV加密後的字符串是不一樣的,加密和解密須要相同的IV。可是因爲塊的長度是16字節,因此通常能夠認爲須要的IV是16字節。html

PADDINGjava

AES塊加密說過,PADDING是用來填充最後一塊使得變成一整塊,因此對於加密解密兩端須要使用同一的PADDING模式,大部分PADDING模式爲PKCS5, PKCS7, NOPADDING。

對於加密端,應該包括:加密內容,祕鑰,IV值,加密模式,PADDING方式。

  對於解密端,應該包括:解密內容,祕鑰,IV值,解密模式,PADDING方式。
  1. 聲明下,貼出來格式有問題,你們按着我借註解直接複製就好node

  2. 本文章實現功能 後臺生成公私祕鑰對,將公鑰返回給頁面(頁面初始化時獲取)。頁面生成隨機16位的祕鑰和iv向量,而後用公鑰進行加密,內容用祕鑰和向量加密。後端用私鑰解密 祕鑰和向量。後臺將私鑰,祕鑰和向量存在session中。頁面將鑰匙存在緩存中。而後用祕鑰和向量解密內容。後續通訊都用祕鑰和向量加密解密。c++

  • RSA加解密先須要導入兩個jar包和RSA.js,BigInt.js,Barrett.js。bcprov-jdk14-124.jar和bcprov-ext-jdk15on-1.54.jar,版本最好14以上的,14如下的沒試過,jar包能夠本身到網上找資源下載。
  • AES須要aes.js
  1. 下面我都把js代碼貼出來
  • RSA.js

// RSA, a suite of routines for performing RSA public-key computations in // JavaScript. // // Requires BigInt.js and Barrett.js. // // Copyright 1998-2005 David Shapiro. // // You may use, re-use, abuse, copy, and modify this code to your liking, but // please keep this header. // // Thanks! // // Dave Shapiro // dave@ohdave.comgit

function RSAKeyPair(encryptionExponent, decryptionExponent, modulus) { this.e = biFromHex(encryptionExponent); this.d = biFromHex(decryptionExponent); this.m = biFromHex(modulus); // We can do two bytes per digit, so // chunkSize = 2 * (number of digits in modulus - 1). // Since biHighIndex returns the high index, not the number of digits, 1 has // already been subtracted. this.chunkSize = 2 * biHighIndex(this.m); this.radix = 16; this.barrett = new BarrettMu(this.m); }web

function twoDigit(n) { return (n < 10 ? "0" : "") + String(n); }ajax

function encryptedString(key, s) // Altered by Rob Saunders (rob@robsaunders.net). New routine pads the // string after it has been converted to an array. This fixes an // incompatibility with Flash MX's ActionScript. { var a = new Array(); var sl = s.length; var i = 0; while (i < sl) { a[i] = s.charCodeAt(i); i++; }算法

while (a.length % key.chunkSize != 0) {
	a[i++] = 0;
}

var al = a.length;
var result = "";
var j, k, block;
for (i = 0; i < al; i += key.chunkSize) {
	block = new BigInt();
	j = 0;
	for (k = i; k < i + key.chunkSize; ++j) {
		block.digits[j] = a[k++];
		block.digits[j] += a[k++] << 8;
	}
	var crypt = key.barrett.powMod(block, key.e);
	var text = key.radix == 16 ? biToHex(crypt) : biToString(crypt, key.radix);
	result += text + " ";
}
return result.substring(0, result.length - 1); // Remove last space.

}spring

function decryptedString(key, s) { var blocks = s.split(" "); var result = ""; var i, j, block; for (i = 0; i < blocks.length; ++i) { var bi; if (key.radix == 16) { bi = biFromHex(blocks[i]); } else { bi = biFromString(blocks[i], key.radix); } block = key.barrett.powMod(bi, key.d); for (j = 0; j <= biHighIndex(block); ++j) { result += String.fromCharCode(block.digits[j] & 255, block.digits[j] >> 8); } } // Remove trailing null, if any. if (result.charCodeAt(result.length - 1) == 0) { result = result.substring(0, result.length - 1); } return result; }

BigInt.js

// BigInt, a suite of routines for performing multiple-precision arithmetic in // JavaScript. // // Copyright 1998-2005 David Shapiro. // // You may use, re-use, abuse, // copy, and modify this code to your liking, but please keep this header. // Thanks! // // Dave Shapiro // dave@ohdave.com

// IMPORTANT THING: Be sure to set maxDigits according to your precision // needs. Use the setMaxDigits() function to do this. See comments below. // // Tweaked by Ian Bunning // Alterations: // Fix bug in function biFromHex(s) to allow // parsing of strings of length != 0 (mod 4)

// Changes made by Dave Shapiro as of 12/30/2004: // // The BigInt() constructor doesn't take a string anymore. If you want to // create a BigInt from a string, use biFromDecimal() for base-10 // representations, biFromHex() for base-16 representations, or // biFromString() for base-2-to-36 representations. // // biFromArray() has been removed. Use biCopy() instead, passing a BigInt // instead of an array. // // The BigInt() constructor now only constructs a zeroed-out array. // Alternatively, if you pass <true>, it won't construct any array. See the // biCopy() method for an example of this. // // Be sure to set maxDigits depending on your precision needs. The default // zeroed-out array ZERO_ARRAY is constructed inside the setMaxDigits() // function. So use this function to set the variable. DON'T JUST SET THE // VALUE. USE THE FUNCTION. // // ZERO_ARRAY exists to hopefully speed up construction of BigInts(). By // precalculating the zero array, we can just use slice(0) to make copies of // it. Presumably this calls faster native code, as opposed to setting the // elements one at a time. I have not done any timing tests to verify this // claim.

// Max number = 10^16 - 2 = 9999999999999998; // 2^53 = 9007199254740992;

var biRadixBase = 2; var biRadixBits = 16; var bitsPerDigit = biRadixBits; var biRadix = 1 << 16; // = 2^16 = 65536 var biHalfRadix = biRadix >>> 1; var biRadixSquared = biRadix * biRadix; var maxDigitVal = biRadix - 1; var maxInteger = 9999999999999998;

// maxDigits: // Change this to accommodate your largest number size. Use setMaxDigits() // to change it! // // In general, if you're working with numbers of size N bits, you'll need 2*N // bits of storage. Each digit holds 16 bits. So, a 1024-bit key will need // // 1024 * 2 / 16 = 128 digits of storage. //

var maxDigits; var ZERO_ARRAY; var bigZero, bigOne;

function setMaxDigits(value) { maxDigits = value; ZERO_ARRAY = new Array(maxDigits); for (var iza = 0; iza < ZERO_ARRAY.length; iza++) ZERO_ARRAY[iza] = 0; bigZero = new BigInt(); bigOne = new BigInt(); bigOne.digits[0] = 1; }

setMaxDigits(20);

// The maximum number of digits in base 10 you can convert to an // integer without JavaScript throwing up on you. var dpl10 = 15; // lr10 = 10 ^ dpl10 var lr10 = biFromNumber(1000000000000000);

function BigInt(flag) { if (typeof flag == "boolean" && flag == true) { this.digits = null; } else { this.digits = ZERO_ARRAY.slice(0); } this.isNeg = false; }

function biFromDecimal(s) { var isNeg = s.charAt(0) == '-'; var i = isNeg ? 1 : 0; var result; // Skip leading zeros. while (i < s.length && s.charAt(i) == '0') ++i; if (i == s.length) { result = new BigInt(); } else { var digitCount = s.length - i; var fgl = digitCount % dpl10; if (fgl == 0) fgl = dpl10; result = biFromNumber(Number(s.substr(i, fgl))); i += fgl; while (i < s.length) { result = biAdd(biMultiply(result, lr10), biFromNumber(Number(s.substr(i, dpl10)))); i += dpl10; } result.isNeg = isNeg; } return result; }

function biCopy(bi) { var result = new BigInt(true); result.digits = bi.digits.slice(0); result.isNeg = bi.isNeg; return result; }

function biFromNumber(i) { var result = new BigInt(); result.isNeg = i < 0; i = Math.abs(i); var j = 0; while (i > 0) { result.digits[j++] = i & maxDigitVal; i = Math.floor(i / biRadix); } return result; }

function reverseStr(s) { var result = ""; for (var i = s.length - 1; i > -1; --i) { result += s.charAt(i); } return result; }

var hexatrigesimalToChar = new Array( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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' );

function biToString(x, radix) // 2 <= radix <= 36 { var b = new BigInt(); b.digits[0] = radix; var qr = biDivideModulo(x, b); var result = hexatrigesimalToChar[qr[1].digits[0]]; while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); digit = qr[1].digits[0]; result += hexatrigesimalToChar[qr[1].digits[0]]; } return (x.isNeg ? "-" : "") + reverseStr(result); }

function biToDecimal(x) { var b = new BigInt(); b.digits[0] = 10; var qr = biDivideModulo(x, b); var result = String(qr[1].digits[0]); while (biCompare(qr[0], bigZero) == 1) { qr = biDivideModulo(qr[0], b); result += String(qr[1].digits[0]); } return (x.isNeg ? "-" : "") + reverseStr(result); }

var hexToChar = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');

function digitToHex(n) { var mask = 0xf; var result = ""; for (i = 0; i < 4; ++i) { result += hexToChar[n & mask]; n >>>= 4; } return reverseStr(result); }

function biToHex(x) { var result = ""; var n = biHighIndex(x); for (var i = biHighIndex(x); i > -1; --i) { result += digitToHex(x.digits[i]); } return result; }

function charToHex(c) { var ZERO = 48; var NINE = ZERO + 9; var littleA = 97; var littleZ = littleA + 25; var bigA = 65; var bigZ = 65 + 25; var result;

if (c >= ZERO && c <= NINE) {
	result = c - ZERO;
} else if (c >= bigA && c <= bigZ) {
	result = 10 + c - bigA;
} else if (c >= littleA && c <= littleZ) {
	result = 10 + c - littleA;
} else {
	result = 0;
}
return result;

}

function hexToDigit(s) { var result = 0; var sl = Math.min(s.length, 4); for (var i = 0; i < sl; ++i) { result <<= 4; result |= charToHex(s.charCodeAt(i)) } return result; }

function biFromHex(s) { var result = new BigInt(); var sl = s.length; for (var i = sl, j = 0; i > 0; i -= 4, ++j) { result.digits[j] = hexToDigit(s.substr(Math.max(i - 4, 0), Math.min(i, 4))); } return result; }

function biFromString(s, radix) { var isNeg = s.charAt(0) == '-'; var istop = isNeg ? 1 : 0; var result = new BigInt(); var place = new BigInt(); place.digits[0] = 1; // radix^0 for (var i = s.length - 1; i >= istop; i--) { var c = s.charCodeAt(i); var digit = charToHex(c); var biDigit = biMultiplyDigit(place, digit); result = biAdd(result, biDigit); place = biMultiplyDigit(place, radix); } result.isNeg = isNeg; return result; }

function biDump(b) { return (b.isNeg ? "-" : "") + b.digits.join(" "); }

function biAdd(x, y) { var result;

if (x.isNeg != y.isNeg) {
	y.isNeg = !y.isNeg;
	result = biSubtract(x, y);
	y.isNeg = !y.isNeg;
}
else {
	result = new BigInt();
	var c = 0;
	var n;
	for (var i = 0; i < x.digits.length; ++i) {
		n = x.digits[i] + y.digits[i] + c;
		result.digits[i] = n % biRadix;
		c = Number(n >= biRadix);
	}
	result.isNeg = x.isNeg;
}
return result;

}

function biSubtract(x, y) { var result; if (x.isNeg != y.isNeg) { y.isNeg = !y.isNeg; result = biAdd(x, y); y.isNeg = !y.isNeg; } else { result = new BigInt(); var n, c; c = 0; for (var i = 0; i < x.digits.length; ++i) { n = x.digits[i] - y.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation. if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Fix up the negative sign, if any. if (c == -1) { c = 0; for (var i = 0; i < x.digits.length; ++i) { n = 0 - result.digits[i] + c; result.digits[i] = n % biRadix; // Stupid non-conforming modulus operation. if (result.digits[i] < 0) result.digits[i] += biRadix; c = 0 - Number(n < 0); } // Result is opposite sign of arguments. result.isNeg = !x.isNeg; } else { // Result is same sign. result.isNeg = x.isNeg; } } return result; }

function biHighIndex(x) { var result = x.digits.length - 1; while (result > 0 && x.digits[result] == 0) --result; return result; }

function biNumBits(x) { var n = biHighIndex(x); var d = x.digits[n]; var m = (n + 1) * bitsPerDigit; var result; for (result = m; result > m - bitsPerDigit; --result) { if ((d & 0x8000) != 0) break; d <<= 1; } return result; }

function biMultiply(x, y) { var result = new BigInt(); var c; var n = biHighIndex(x); var t = biHighIndex(y); var u, uv, k;

for (var i = 0; i <= t; ++i) {
	c = 0;
	k = i;
	for (j = 0; j <= n; ++j, ++k) {
		uv = result.digits[k] + x.digits[j] * y.digits[i] + c;
		result.digits[k] = uv & maxDigitVal;
		c = uv >>> biRadixBits;
		//c = Math.floor(uv / biRadix);
	}
	result.digits[i + n + 1] = c;
}
// Someone give me a logical xor, please.
result.isNeg = x.isNeg != y.isNeg;
return result;

}

function biMultiplyDigit(x, y) { var n, c, uv;

result = new BigInt();
n = biHighIndex(x);
c = 0;
for (var j = 0; j <= n; ++j) {
	uv = result.digits[j] + x.digits[j] * y + c;
	result.digits[j] = uv & maxDigitVal;
	c = uv >>> biRadixBits;
	//c = Math.floor(uv / biRadix);
}
result.digits[1 + n] = c;
return result;

}

function arrayCopy(src, srcStart, dest, destStart, n) { var m = Math.min(srcStart + n, src.length); for (var i = srcStart, j = destStart; i < m; ++i, ++j) { dest[j] = src[i]; } }

var highBitMasks = new Array(0x0000, 0x8000, 0xC000, 0xE000, 0xF000, 0xF800, 0xFC00, 0xFE00, 0xFF00, 0xFF80, 0xFFC0, 0xFFE0, 0xFFF0, 0xFFF8, 0xFFFC, 0xFFFE, 0xFFFF);

function biShiftLeft(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, digitCount, result.digits.length - digitCount); var bits = n % bitsPerDigit; var rightBits = bitsPerDigit - bits; for (var i = result.digits.length - 1, i1 = i - 1; i > 0; --i, --i1) { result.digits[i] = ((result.digits[i] << bits) & maxDigitVal) | ((result.digits[i1] & highBitMasks[bits]) >>> (rightBits)); } result.digits[0] = ((result.digits[i] << bits) & maxDigitVal); result.isNeg = x.isNeg; return result; }

var lowBitMasks = new Array(0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF);

function biShiftRight(x, n) { var digitCount = Math.floor(n / bitsPerDigit); var result = new BigInt(); arrayCopy(x.digits, digitCount, result.digits, 0, x.digits.length - digitCount); var bits = n % bitsPerDigit; var leftBits = bitsPerDigit - bits; for (var i = 0, i1 = i + 1; i < result.digits.length - 1; ++i, ++i1) { result.digits[i] = (result.digits[i] >>> bits) | ((result.digits[i1] & lowBitMasks[bits]) << leftBits); } result.digits[result.digits.length - 1] >>>= bits; result.isNeg = x.isNeg; return result; }

function biMultiplyByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, n, result.digits.length - n); return result; }

function biDivideByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, n, result.digits, 0, result.digits.length - n); return result; }

function biModuloByRadixPower(x, n) { var result = new BigInt(); arrayCopy(x.digits, 0, result.digits, 0, n); return result; }

function biCompare(x, y) { if (x.isNeg != y.isNeg) { return 1 - 2 * Number(x.isNeg); } for (var i = x.digits.length - 1; i >= 0; --i) { if (x.digits[i] != y.digits[i]) { if (x.isNeg) { return 1 - 2 * Number(x.digits[i] > y.digits[i]); } else { return 1 - 2 * Number(x.digits[i] < y.digits[i]); } } } return 0; }

function biDivideModulo(x, y) { var nb = biNumBits(x); var tb = biNumBits(y); var origYIsNeg = y.isNeg; var q, r; if (nb < tb) { // |x| < |y| if (x.isNeg) { q = biCopy(bigOne); q.isNeg = !y.isNeg; x.isNeg = false; y.isNeg = false; r = biSubtract(y, x); // Restore signs, 'cause they're references. x.isNeg = true; y.isNeg = origYIsNeg; } else { q = new BigInt(); r = biCopy(x); } return new Array(q, r); }

q = new BigInt();
r = x;

// Normalize Y.
var t = Math.ceil(tb / bitsPerDigit) - 1;
var lambda = 0;
while (y.digits[t] < biHalfRadix) {
	y = biShiftLeft(y, 1);
	++lambda;
	++tb;
	t = Math.ceil(tb / bitsPerDigit) - 1;
}
// Shift r over to keep the quotient constant. We'll shift the
// remainder back at the end.
r = biShiftLeft(r, lambda);
nb += lambda; // Update the bit count for x.
var n = Math.ceil(nb / bitsPerDigit) - 1;

var b = biMultiplyByRadixPower(y, n - t);
while (biCompare(r, b) != -1) {
	++q.digits[n - t];
	r = biSubtract(r, b);
}
for (var i = n; i > t; --i) {
var ri = (i >= r.digits.length) ? 0 : r.digits[i];
var ri1 = (i - 1 >= r.digits.length) ? 0 : r.digits[i - 1];
var ri2 = (i - 2 >= r.digits.length) ? 0 : r.digits[i - 2];
var yt = (t >= y.digits.length) ? 0 : y.digits[t];
var yt1 = (t - 1 >= y.digits.length) ? 0 : y.digits[t - 1];
	if (ri == yt) {
		q.digits[i - t - 1] = maxDigitVal;
	} else {
		q.digits[i - t - 1] = Math.floor((ri * biRadix + ri1) / yt);
	}

	var c1 = q.digits[i - t - 1] * ((yt * biRadix) + yt1);
	var c2 = (ri * biRadixSquared) + ((ri1 * biRadix) + ri2);
	while (c1 > c2) {
		--q.digits[i - t - 1];
		c1 = q.digits[i - t - 1] * ((yt * biRadix) | yt1);
		c2 = (ri * biRadix * biRadix) + ((ri1 * biRadix) + ri2);
	}

	b = biMultiplyByRadixPower(y, i - t - 1);
	r = biSubtract(r, biMultiplyDigit(b, q.digits[i - t - 1]));
	if (r.isNeg) {
		r = biAdd(r, b);
		--q.digits[i - t - 1];
	}
}
r = biShiftRight(r, lambda);
// Fiddle with the signs and stuff to make sure that 0 <= r < y.
q.isNeg = x.isNeg != origYIsNeg;
if (x.isNeg) {
	if (origYIsNeg) {
		q = biAdd(q, bigOne);
	} else {
		q = biSubtract(q, bigOne);
	}
	y = biShiftRight(y, lambda);
	r = biSubtract(y, r);
}
// Check for the unbelievably stupid degenerate case of r == -0.
if (r.digits[0] == 0 && biHighIndex(r) == 0) r.isNeg = false;

return new Array(q, r);

}

function biDivide(x, y) { return biDivideModulo(x, y)[0]; }

function biModulo(x, y) { return biDivideModulo(x, y)[1]; }

function biMultiplyMod(x, y, m) { return biModulo(biMultiply(x, y), m); }

function biPow(x, y) { var result = bigOne; var a = x; while (true) { if ((y & 1) != 0) result = biMultiply(result, a); y >>= 1; if (y == 0) break; a = biMultiply(a, a); } return result; }

function biPowMod(x, y, m) { var result = bigOne; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = biMultiplyMod(result, a, m); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = biMultiplyMod(a, a, m); } return result; }

Barrett.js

// BarrettMu, a class for performing Barrett modular reduction computations in // JavaScript. // // Requires BigInt.js. // // Copyright 2004-2005 David Shapiro. // // You may use, re-use, abuse, copy, and modify this code to your liking, but // please keep this header. // // Thanks! // // Dave Shapiro // dave@ohdave.com

function BarrettMu(m) { this.modulus = biCopy(m); this.k = biHighIndex(this.modulus) + 1; var b2k = new BigInt(); b2k.digits[2 * this.k] = 1; // b2k = b^(2k) this.mu = biDivide(b2k, this.modulus); this.bkplus1 = new BigInt(); this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1) this.modulo = BarrettMu_modulo; this.multiplyMod = BarrettMu_multiplyMod; this.powMod = BarrettMu_powMod; }

function BarrettMu_modulo(x) { var q1 = biDivideByRadixPower(x, this.k - 1); var q2 = biMultiply(q1, this.mu); var q3 = biDivideByRadixPower(q2, this.k + 1); var r1 = biModuloByRadixPower(x, this.k + 1); var r2term = biMultiply(q3, this.modulus); var r2 = biModuloByRadixPower(r2term, this.k + 1); var r = biSubtract(r1, r2); if (r.isNeg) { r = biAdd(r, this.bkplus1); } var rgtem = biCompare(r, this.modulus) >= 0; while (rgtem) { r = biSubtract(r, this.modulus); rgtem = biCompare(r, this.modulus) >= 0; } return r; }

function BarrettMu_multiplyMod(x, y) { /* x = this.modulo(x); y = this.modulo(y); */ var xy = biMultiply(x, y); return this.modulo(xy); }

function BarrettMu_powMod(x, y) { var result = new BigInt(); result.digits[0] = 1; var a = x; var k = y; while (true) { if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a); k = biShiftRight(k, 1); if (k.digits[0] == 0 && biHighIndex(k) == 0) break; a = this.multiplyMod(a, a); } return result; }

aes.js

/* CryptoJS v3.1.2 code.google.com/p/crypto-js (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License / var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k<a;k++)c[j+k>>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535<e.length)for(k=0;k<a;k+=4)c[j+k>>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< 32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e<a;e+=4)c.push(4294967296u.random()|0);return new r.init(c,a)}}),w=d.enc={},v=w.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++){var k=c[j>>>2]>>>24-8(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j+=2)e[j>>>3]|=parseInt(a.substr(j, 2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j<a;j++)e.push(String.fromCharCode(c[j>>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j<c;j++)e[j>>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}}, q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=bk;j=u.min(4a,j);if(a){for(var q=0;q<a;q+=k)this._doProcessBlock(e,q);q=e.splice(0,a);c.sigBytes-=j}return new r.init(q,j)},clone:function(){var a=t.clone.call(this); a._data=this._data.clone();return a},_minBufferSize:0});l.Hasher=q.extend({cfg:t.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){q.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(b,e){return(new a.init(e)).finalize(b)}},_createHmacHelper:function(a){return function(b,e){return(new n.HMAC.init(a, e)).finalize(b)}}});var n=d.algo={};return d}(Math); (function(){var u=CryptoJS,p=u.lib.WordArray;u.enc.Base64={stringify:function(d){var l=d.words,p=d.sigBytes,t=this._map;d.clamp();d=[];for(var r=0;r<p;r+=3)for(var w=(l[r>>>2]>>>24-8(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75v<p;v++)d.push(t.charAt(w>>>6(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w< l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); (function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<<j|b>>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<<j|b>>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<<j|b>>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<<j|b>>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])}, _doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]), f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f, m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m, E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8this._nDataBytes,c=8b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/ 4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math); (function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length<q;){n&&s.update(n);var n=s.update(d).finalize(r);s.reset();for(var a=1;a<p;a++)n=s.finalize(n),s.reset();b.concat(n)}b.sigBytes=4q;return b}});u.EvpKDF=function(d,l,p){return s.create(p).compute(d, l)}})(); CryptoJS.lib.Cipher||function(u){var p=CryptoJS,d=p.lib,l=d.Base,s=d.WordArray,t=d.BufferedBlockAlgorithm,r=p.enc.Base64,w=p.algo.EvpKDF,v=d.Cipher=t.extend({cfg:l.extend(),createEncryptor:function(e,a){return this.create(this._ENC_XFORM_MODE,e,a)},createDecryptor:function(e,a){return this.create(this._DEC_XFORM_MODE,e,a)},init:function(e,a,b){this.cfg=this.cfg.extend(b);this._xformMode=e;this._key=a;this.reset()},reset:function(){t.reset.call(this);this._doReset()},process:function(e){this._append(e);return this._process()}, finalize:function(e){e&&this._append(e);return this._doFinalize()},keySize:4,ivSize:4,_ENC_XFORM_MODE:1,_DEC_XFORM_MODE:2,_createHelper:function(e){return{encrypt:function(b,k,d){return("string"==typeof k?c:a).encrypt(e,b,k,d)},decrypt:function(b,k,d){return("string"==typeof k?c:a).decrypt(e,b,k,d)}}}});d.StreamCipher=v.extend({_doFinalize:function(){return this._process(!0)},blockSize:1});var b=p.mode={},x=function(e,a,b){var c=this._iv;c?this._iv=u:c=this._prevBlock;for(var d=0;d<b;d++)e[a+d]^= c[d]},q=(d.BlockCipherMode=l.extend({createEncryptor:function(e,a){return this.Encryptor.create(e,a)},createDecryptor:function(e,a){return this.Decryptor.create(e,a)},init:function(e,a){this._cipher=e;this._iv=a}})).extend();q.Encryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize;x.call(this,e,a,c);b.encryptBlock(e,a);this._prevBlock=e.slice(a,a+c)}});q.Decryptor=q.extend({processBlock:function(e,a){var b=this._cipher,c=b.blockSize,d=e.slice(a,a+c);b.decryptBlock(e,a);x.call(this, e,a,c);this._prevBlock=d}});b=b.CBC=q;q=(p.pad={}).Pkcs7={pad:function(a,b){for(var c=4b,c=c-a.sigBytes%c,d=c<<24|c<<16|c<<8|c,l=[],n=0;n<c;n+=4)l.push(d);c=s.create(l,c);a.concat(c)},unpad:function(a){a.sigBytes-=a.words[a.sigBytes-1>>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a, this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684, 1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})}, decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4c);a.sigBytes=4b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d, b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}(); (function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257a[k]^16843008k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009G^65537F^257z^16843008e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8, 16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j<a;j++)if(j<d)e[j]=c[j];else{var k=e[j-1];j%d?6<d&&4==j%d&&(k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;d<a;d++)j=a-d,k=d%4?e[j]:e[j-4],c[d]=4>d||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>> 8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r<m;r++)var q=d[g>>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t= d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})();

二、**下面是java controller類 **

import java.security.Key;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.json.JSONArray;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.topcheer.service.GenreateKeyService;
import com.topcheer.utils.ResultJsonUtil;
[@Controller](https://my.oschina.net/u/1774615)
@RequestMapping("/generateKey")
public class GenerateKeyContoller {
	
    //得到公鑰
    @RequestMapping("getPublicKey")
    @ResponseBody
    public  Map<String,Object> getPublicKey(HttpServletRequest request)  {
    	Map<String,Object> publickey=null;
    
		Map<String, Object> resultMap = new HashMap<String, Object>();
		try {
			Map<String, Object> mapkey = GenreateKeyService.initKey(request.getSession());
			publickey = GenreateKeyService.getPublicKey(mapkey);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			e.getMessage();
			 resultMap  = ResultJsonUtil.getResultErrorMap();
			resultMap.put(ResultJsonUtil.ERROR_MSG, "獲取公鑰失敗!");
			return resultMap;
		}
		 resultMap = ResultJsonUtil.getResultMap();
		 resultMap.put("publicKey", publickey);
        return resultMap;
    }
    //客戶請求
    @RequestMapping("appRequest")
    @ResponseBody
    public  Map<String,Object> appRequest(String encodeRules,String context,String IV,HttpServletRequest request) {
    	System.out.println("接收到的加密祕鑰:"+encodeRules);
    	System.out.println("接收到的IV:"+IV);
		System.out.println("接收到的加密內容:"+context);
		Map<String,Object>  resualt = null;
		try {
			
			resualt = GenreateKeyService.appRequest(encodeRules,IV, context,request);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
        return resualt;
    }
}



實現類



import java.io.ByteArrayOutputStream;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.interfaces.RSAKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import javax.crypto.Cipher;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import com.topcheer.model.genreatekey.Genreatekey;
import com.topcheer.service.genreatekey.Impl.GenreatekeyServiceImpl;
import com.topcheer.utils.PropertiesUtil;
import com.topcheer.utils.ResultJsonUtil;

import java.util.Scanner;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class GenreateKeyService {
	   /** *//** 
     * 加密算法RSA 
     */  
    public static final String KEY_ALGORITHM = "RSA";  
   
  
    /** *//** 
     * 獲取公鑰的key 
     */  
    private static final String PUBLIC_KEY = "RSAPublicKey";  
      
    /** *//** 
     * 獲取私鑰的key 
     */  
    private static final String PRIVATE_KEY = "RSAPrivateKey";  
      
    /** *//** 
     * RSA最大加密明文大小 
     */  
    private static final int MAX_ENCRYPT_BLOCK = 117;  
      
    /** *//** 
     * RSA最大解密密文大小 
     */  
    private static final int MAX_DECRYPT_BLOCK = 128;  
    //對稱加密 祕鑰

 //map對象中存放公私鑰
    public static Map<String, Object> initKey(HttpSession session){
     
        //公私鑰對象存入map中
        Map<String, Object> keyMap = new HashMap<String, Object>(2);
		try {
			   //得到對象 KeyPairGenerator 參數 RSA 1024個字節
	        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
	        keyPairGen.initialize(1024, new SecureRandom());  
	        //經過對象 KeyPairGenerator 獲取對象KeyPair
	        KeyPair keyPair = keyPairGen.generateKeyPair();
	        
	        //經過對象 KeyPair 獲取RSA公私鑰對象RSAPublicKey RSAPrivateKey
	        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
	        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
	        session.setAttribute("Keyprivate", privateKey);
	
			  keyMap.put(PUBLIC_KEY, publicKey);
		      keyMap.put(PRIVATE_KEY, privateKey);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("公鑰:"+keyMap.get(PUBLIC_KEY));
        System.out.println(session.getAttribute("privateKey"));
        return keyMap;
    }
    
    
    //客戶請求
    public static Map<String,Object>  appRequest(String encodeRules,String IV, String context,HttpServletRequest request) {
			Map<String, Object> resultMap = new HashMap<String, Object>();
			try {
			//一、經過私鑰解密獲得對稱祕鑰和向量
			//、經過對稱祕鑰解密獲得解密內容
			//獲得私鑰
			PrivateKey privateKey =(PrivateKey)request.getSession().getAttribute("Keyprivate");
			String deContext=null;//解密內容
			String symmKey = (String) request.getSession().getAttribute("encodeRules");//解密祕鑰
			String iv = (String) request.getSession().getAttribute("IV");//向量IV
			if(symmKey==null||symmKey.equals("")){
				if(encodeRules==null){
					resultMap = ResultJsonUtil.getResultErrorMap();
					resultMap.put(ResultJsonUtil.ERROR_MSG, "祕鑰得到失敗");
					return resultMap;
				}
				try {
//					
			        byte[] en_result =hexStringToBytes(encodeRules);
					byte [] data_byte = 	RSAdecrypt(privateKey,en_result);
					//還原祕鑰
					StringBuffer sb = new StringBuffer();
					sb.append(new String(data_byte));
					symmKey = sb.reverse().toString();
					System.out.println("=================================");
					symmKey = URLDecoder.decode(symmKey,"UTF-8");//
					System.out.println("解密後祕鑰爲:"+symmKey);
					request.getSession().setAttribute("encodeRules", symmKey);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					resultMap = ResultJsonUtil.getResultErrorMap();
					resultMap.put(ResultJsonUtil.ERROR_MSG, "祕鑰解密出錯!");
					return resultMap;
				}
			}
			if(iv==null||iv.equals("")){
				if(IV==null){
					resultMap = ResultJsonUtil.getResultErrorMap();
					resultMap.put(ResultJsonUtil.ERROR_MSG, "向量得到失敗");
					return resultMap;
				}
				try {
//					
			        byte[] en_result =hexStringToBytes(IV);
					byte [] data_byte = 	RSAdecrypt(privateKey,en_result);
					//還原向量
					StringBuffer sb = new StringBuffer();
					sb.append(new String(data_byte));
					iv = sb.reverse().toString();
					System.out.println("=================================");
					iv = URLDecoder.decode(iv,"UTF-8");//
					System.out.println("解密後向量爲:"+iv);
					request.getSession().setAttribute("IV", iv);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					resultMap = ResultJsonUtil.getResultErrorMap();
					resultMap.put(ResultJsonUtil.ERROR_MSG, "向量解密出錯!");
					return resultMap;
				}
			}
			try {
				
				//經過對稱祕鑰解密獲得解密內容
				deContext = AESDecrypt(symmKey,iv,context);
				if(deContext==null){
					resultMap = ResultJsonUtil.getResultErrorMap();
					resultMap.put(ResultJsonUtil.ERROR_MSG, "內容解密出錯!");
					return resultMap;
				}
				System.out.println("解密後內容爲:"+deContext);
			String encontext = AESEncrypt(symmKey,iv,"傻了吧");
				
				 if(encontext==null){
					 resultMap = ResultJsonUtil.getResultErrorMap();
						resultMap.put(ResultJsonUtil.ERROR_MSG, "內容加密出錯!");
						return resultMap;
				 }
				
				resultMap.put("encodeText", encontext);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				resultMap = ResultJsonUtil.getResultErrorMap();
				resultMap.put(ResultJsonUtil.ERROR_MSG, "內容解密出錯!");
				return resultMap;
			}
			resultMap.put("result", "ok");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return resultMap;
		}
  

  
    /** *//** 
     * <p> 
     * 獲取公鑰 
     * </p> 
     *  
     * @param keyMap 密鑰對 
     * @return 
     * @throws Exception 
     */  
    public static Map<String,Object> getPublicKey(Map<String, Object> keyMap)  
            throws Exception {  
    	RSAPublicKey publickey = (RSAPublicKey) keyMap.get(PUBLIC_KEY);  
    	String Modulus= publickey.getModulus().toString(16);
    	String pkExponent=publickey.getPublicExponent().toString(16);
    	
    	 	Map<String,Object> resultMap = new HashMap<String, Object>();
    	 	resultMap.put("publicKey", pkExponent);
    	 	resultMap.put("modulus", Modulus);
        return resultMap; 
    }  
/**
 *     AES解密
 * @param AESKey 祕鑰
 * @param IV 向量
 * @param contexts 內容
 * @return
 * @throws Exception
 */
  //AES解密
    public static String AESDecrypt(String AESKey,String IV,String contexts) throws Exception { 
         
        // 判斷Key是否正確   
        if (AESKey == null) {   
            System.out.print("Key爲空null");   
            return null;   
        }   
        // 判斷Key是否爲16位   
        if (AESKey.length() != 16) {   
            System.out.print("Key長度不是16位");   
            return null;   
        }   
        // 判斷IV是否正確   
        if (IV == null) {   
            System.out.print("IV爲空null");   
            return null;           
        }   
        // 判斷Iv是否爲16位   
        if (IV.length() != 16) {   
            System.out.print("IV長度不是16位");   
            return null;   
        } 
        byte[] raw = AESKey.getBytes("utf-8");
        //1.構造密鑰生成器,指定爲AES算法,不區分大小寫
        KeyGenerator keygen=KeyGenerator.getInstance("AES");
        //2.根據ecnodeRules規則初始化密鑰生成器
        //生成一個128位的隨機源,根據傳入的字節數組
        keygen.init(128);
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");   
         
        //根據字節數組生成AES密鑰
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
        cipher.init(Cipher.DECRYPT_MODE, skeySpec,iv);   
        byte[] contextbyte = new BASE64Decoder().decodeBuffer(contexts);//先用bAES64解密  
        try {   
            byte[] originalContext = cipher.doFinal(contextbyte);   
            String originalString = new String(originalContext,"UTF-8");   
            return originalString;   
        } catch (Exception e) {   
            return null;   
        }   
    }
    /**
     * 
     * @param AEScontext 加密內容
     * @param AESKey  祕鑰
     * @return IV   向量
     * @throws Exception
     */
    //AES加密
    public static String  AESEncrypt(String AESKey,String IV,String contexts){
 
    	// 判斷Key是否正確   
        if (AESKey == null) {   
            System.out.print("Key爲空null");   
            return null;   
        }   
        // 判斷Key是否爲16位   
        if (AESKey.length() != 16) {   
            System.out.print("Key長度不是16位");   
            return null;   
        }   
        // 判斷IV是否正確   
        if (IV == null) {   
            System.out.print("IV爲空null");   
            return null;   
        }   
        // 判斷Iv是否爲16位   
        if (IV.length() != 16) {   
            System.out.print("IV長度不是16位");   
            return null;   
        } 
        byte[] raw = AESKey.getBytes();
         
       
		try {
			 //1.構造密鑰生成器,指定爲AES算法,不區分大小寫
			KeyGenerator	keygen = KeyGenerator.getInstance("AES");
			  //2.根據ecnodeRules規則初始化密鑰生成器
	        //生成一個128位的隨機源,根據傳入的字節數組
	        keygen.init(128);
	         
	        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
			  IvParameterSpec iv = new IvParameterSpec(IV.getBytes());  
		        //根據字節數組生成AES密鑰
		       SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
		       cipher.init(Cipher.ENCRYPT_MODE, skeySpec,iv);
		       byte[] encrypted = cipher.doFinal(contexts.getBytes("utf-8"));
				String encrypttext = new String(new BASE64Encoder().encode(encrypted));
		        return encrypttext;
			} catch (IllegalBlockSizeException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return  null;
			} catch (BadPaddingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return  null;
			} 
			catch (NoSuchPaddingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return  null;
			}  catch (InvalidKeyException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return  null;
			} catch (InvalidAlgorithmParameterException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return  null;
			}  catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return  null;
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return  null;
		}
      
    }
  /**
   * RSA私鑰解密
   * @param pk 私鑰匙
   * @param raw 內容
   * @return
   * @throws Exception
   */
     
      public static byte[] RSAdecrypt(PrivateKey pk, byte[] raw) throws Exception {  
          try {  
              Cipher cipher = Cipher.getInstance("RSA",  
                      new org.bouncycastle.jce.provider.BouncyCastleProvider());  
              cipher.init(cipher.DECRYPT_MODE, pk);  
              int blockSize = cipher.getBlockSize();  
              ByteArrayOutputStream bout = new ByteArrayOutputStream(64);  
              int j = 0;  
    
              while (raw.length - j * blockSize > 0) {  
                  bout.write(cipher.doFinal(raw, j * blockSize, blockSize));  
                  j++;  
              }  
              return bout.toByteArray();  
          } catch (Exception e) {  
              throw new Exception(e.getMessage());  
          }  
      }  
    //
      public static byte[] hexStringToBytes(String hexString) {
             if (hexString== null || hexString.equals(""))
                   {
                     return null;
                    }
             hexString  = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[]hexChars = hexString.toCharArray();
            byte[] d = new byte[length];
             for (int i = 0;i < length; i++) {
                    int pos = i * 2;
                    d[i]= (byte)(charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
                    
                        	        }
             return d;
       }
      private static byte charToByte(char c)
      {
     	        return (byte) "0123456789ABCDEF".indexOf(c);
     	    }
}




最後頁面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
   <title>角色管理</title>
  <jsp:include page="/module/common/comm.jsp"></jsp:include>
  <script  type="text/javascript" src="<%=request.getContextPath() %>/js/aes.js"></script>
  
    <script type="text/javascript" src="<%=request.getContextPath() %>/js/RSA.js"></script>
	<script type="text/javascript" src="<%=request.getContextPath() %>/js/BigInt.js"></script>
	<script type="text/javascript" src="<%=request.getContextPath() %>/js/Barrett.js"></script>
   <script type="text/javascript"  charset="UTF-8">
    var storage = window.localStorage;
   $(function(){
   storage.clear();
  	 var publickey = storage.getItem("publicKey");
  	 if(publickey==null||publickey==""){
   			$.ajax({
   			url:"<%=request.getContextPath()%>/generateKey/getPublicKey.do",
	 		async :false,
			dataType : "json",
			cache:false,
			type : "post",
			success : function(e){
				var publickeyMap = e.publicKey;
			storage.setItem("publicKey",publickeyMap.publicKey);
			storage.setItem("modulus",publickeyMap.modulus);
		//	alert(publickeyMap.publicKey);
		//	alert(publickeyMap.modulus);
			
				$("#publickey").val(publickeyMap.publicKey);
			},
			error:function(e){
				alert("異常"+e);
			}
   		});
   }
		
			
   });
  function submitContext(){
  	//公鑰
  		var publickey = storage.getItem("publicKey");
  		//公共的摸
  		var modulu =  storage.getItem("modulus");
  		var key ;
  		setMaxDigits(130);
  		key= new RSAKeyPair(publickey,"",modulu); 
 		 
  		var encodekey =null;//加密後的祕鑰
  
  		//祕鑰
  		var endcoderules = storage.getItem("encodeRules");
  		//向量
  		var iv = storage.getItem("IV");
  		//加密後向量
  		var encodeIV = null;
        
          if(endcoderules==null){
           endcoderules="";
          	  //生成祕鑰
          	for(var i=0;i<16;i++)
			{
				endcoderules+=Math.floor(Math.random()*10).toString();
			} 
			//將祕鑰存入緩存
			storage.setItem("encodeRules",endcoderules);
					//加密祕鑰
			
			encodekey =	encryptedString(key,endcoderules);
          }
         if(iv==null){
         	iv="";
         	//生成向量iv
				for(var j=0;j<16;j++)
			{
				iv+=Math.floor(Math.random()*10).toString();
			} 
			//將向量存入緩存
			storage.setItem("IV",iv);
			//加密向量
			encodeIV = encryptedString(key,iv);
         }
        
          var data = $("#contextdata").val();
          //對內容對稱加密
                     
            var enkey  = CryptoJS.enc.Utf8.parse(endcoderules);  
          var encodedata = CryptoJS.enc.Utf8.parse(data);  
           	var iv   = CryptoJS.enc.Utf8.parse(iv);  
         var ysmmcontext =  CryptoJS.AES.encrypt(encodedata,enkey,{
         iv:iv,
         mode:CryptoJS.mode.CBC,
         padding: CryptoJS.pad.Pkcs7});
         ysmmcontext=ysmmcontext.toString();
         alert(encodekey);
         alert(ysmmcontext);
   		$.ajax({
   			url:"<%=request.getContextPath()%>/generateKey/appRequest.do",
	 		async :false,
			dataType : "json",
			cache:false,
			data:{"encodeRules":encodekey,"IV":encodeIV,"context":ysmmcontext},
			type : "post",
			success : function(e){
				
				if(e.result=="ok"){
						showBox("提示信息", "提交成功", 'info');
				}else if(e.result=="fail"){
					alert("異常"+e.errorMsg);
				}
				var contxt = e.encodeText;
				getDecryptAes(contxt);
			},
			error:function(e){
				alert("異常"+e.errorMsg);
			}
   		})
   }
   //AES解密  
     function getDecryptAes(data){
            var key  = storage.getItem("encodeRules");  
            var iv   = storage.getItem("IV"); 
          	 key  = CryptoJS.enc.Utf8.parse(key);  
             iv   = CryptoJS.enc.Utf8.parse(iv);  
           var  decontext =CryptoJS.AES.decrypt(data,key,  
                    {  
                        iv:iv,  
                        mode:CryptoJS.mode.CBC,  
                       padding:CryptoJS.pad.Pkcs7  
                    });  
               data= decontext.toString(CryptoJS.enc.Utf8);
           document.getElementById("decrypted").innerHTML = data;  
        }  
	</script>
	
  </head>

  <body>
    
    <textarea id="contextdata" name="contextdata" type="text" rows=4 cols=70>This is a test!</textarea><br/>
  	 
    <input id="testme" type="button" value="提交" onclick="submitContext()"/><br/>
      	解密後的數據:  
    <p id="decrypted"></p>  
    <input id="publickey" name ="publickey" value="" type="hidden"/>
  </body>
</html>
相關文章
相關標籤/搜索