您的位置:首页 > 编程语言 > Java开发

js java 密码的rsa加密解密配合

2014-01-15 10:28 471 查看
阿影

JS客户端RSA加密,Java服务端解密

阿影 发布于 2011年06月17日 16时, 15评/7967阅

分享到 新浪微博腾讯微博收藏+41踩顶0

在客户端浏览器,Javascript使用RSA算法,以公钥对密码进行加密,服务端使用相应的私钥进行解密。一般用于注册时或登录时填写的密码。

Java引用到的包:

commons-lang

bouncycastle

slf4j

commons-codec

commons-io

标签: Bouncy Castle RSA JavaScript Java Bouncy Castle

代码片段(3)[全屏查看所有代码]

1. [文件] security.js ~ 19KB 下载(1449)

2. [文件] RSAUtils.java ~ 15KB 下载(943)

001

package my.tools.security;

002

003

import java.io.File;

004

import java.io.FileInputStream;

005

import java.io.FileOutputStream;

006

import java.io.ObjectInputStream;

007

import java.io.ObjectOutputStream;

008

import java.math.BigInteger;

009

import java.security.KeyPair;

010

import java.security.KeyFactory;

011

import java.security.KeyPairGenerator;

012

import java.security.Provider;

013

import java.security.PublicKey;

014

import java.security.PrivateKey;

015

import java.security.SecureRandom;

016

import java.security.NoSuchAlgorithmException;

017

import java.security.InvalidParameterException;

018

import java.security.interfaces.RSAPublicKey;

019

import java.security.interfaces.RSAPrivateKey;

020

import java.security.spec.RSAPublicKeySpec;

021

import java.security.spec.RSAPrivateKeySpec;

022

import java.security.spec.InvalidKeySpecException;

023

024

import javax.crypto.Cipher;

025

026

import org.apache.commons.io.IOUtils;

027

import org.apache.commons.io.FileUtils;

028

import org.apache.commons.codec.DecoderException;

029

import org.apache.commons.codec.binary.Hex;

030

import org.bouncycastle.jce.provider.BouncyCastleProvider;

031

import org.slf4j.Logger;

032

import org.slf4j.LoggerFactory;

033

034

import org.apache.commons.lang.StringUtils;

035

import org.apache.commons.lang.time.DateFormatUtils;

036

037

/**

038

* RSA算法加密/解密工具类。

039

*

040

* @author fuchun

041

* @version 1.0.0, 2010-05-05

042

*/

043

public abstract class RSAUtils {

044

045

private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtils.class);

046

047

/** 算法名称 */

048

private static final String ALGORITHOM = "RSA";

049

/**保存生成的密钥对的文件名称。 */

050

private static final String RSA_PAIR_FILENAME = "/__RSA_PAIR.txt";

051

/** 密钥大小 */

052

private static final int KEY_SIZE = 1024;

053

/** 默认的安全服务提供者 */

054

private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();

055

056

private static KeyPairGenerator keyPairGen = null;

057

private static KeyFactory keyFactory = null;

058

/** 缓存的密钥对。 */

059

private static KeyPair oneKeyPair = null;

060

061

private static File rsaPairFile = null;

062

063

static {

064

try {

065

keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM, DEFAULT_PROVIDER);

066

keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER);

067

} catch (NoSuchAlgorithmException ex) {

068

LOGGER.error(ex.getMessage());

069

}

070

rsaPairFile = new File(getRSAPairFilePath());

071

}

072

073

private RSAUtils() {

074

}

075

076

/**

077

* 生成并返回RSA密钥对。

078

*/

079

private static synchronized KeyPair generateKeyPair() {

080

try {

081

keyPairGen.initialize(KEY_SIZE, newSecureRandom(DateFormatUtils.format("yyyyMMdd").getBytes()));

082

oneKeyPair = keyPairGen.generateKeyPair();

083

saveKeyPair(oneKeyPair);

084

return oneKeyPair;

085

} catch (InvalidParameterException ex) {

086

LOGGER.error("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".", ex);

087

} catch (NullPointerException ex) {

088

LOGGER.error("RSAUtils#KEY_PAIR_GEN is null, can not generate KeyPairGenerator instance.",

089

ex);

090

}

091

return null;

092

}

093

094

/**

095

* 返回生成/读取的密钥对文件的路径。

096

*/

097

private static String getRSAPairFilePath() {

098

String urlPath = RSAUtils.class.getResource("/").getPath();

099

return (new File(urlPath).getParent() + RSA_PAIR_FILENAME);

100

}

101

102

/**

103

* 若需要创建新的密钥对文件,则返回 {@code true},否则 {@code false}。

104

*/

105

private static boolean isCreateKeyPairFile() {

106

// 是否创建新的密钥对文件

107

boolean createNewKeyPair = false;

108

if (!rsaPairFile.exists() || rsaPairFile.isDirectory()) {

109

createNewKeyPair = true;

110

}

111

return createNewKeyPair;

112

}

113

114

/**

115

* 将指定的RSA密钥对以文件形式保存。

116

*

117

* @param keyPair 要保存的密钥对。

118

*/

119

private static void saveKeyPair(KeyPair keyPair) {

120

FileOutputStream fos = null;

121

ObjectOutputStream oos = null;

122

try {

123

fos = FileUtils.openOutputStream(rsaPairFile);

124

oos = new ObjectOutputStream(fos);

125

oos.writeObject(keyPair);

126

} catch (Exception ex) {

127

ex.printStackTrace();

128

} finally {

129

IOUtils.closeQuietly(oos);

130

IOUtils.closeQuietly(fos);

131

}

132

}

133

134

/**

135

* 返回RSA密钥对。

136

*/

137

public static KeyPair getKeyPair() {

138

// 首先判断是否需要重新生成新的密钥对文件

139

if (isCreateKeyPairFile()) {

140

// 直接强制生成密钥对文件,并存入缓存。

141

return generateKeyPair();

142

}

143

if (oneKeyPair != null) {

144

return oneKeyPair;

145

}

146

return readKeyPair();

147

}

148

149

// 同步读出保存的密钥对

150

private static KeyPair readKeyPair() {

151

FileInputStream fis = null;

152

ObjectInputStream ois = null;

153

try {

154

fis = FileUtils.openInputStream(rsaPairFile);

155

ois = new ObjectInputStream(fis);

156

oneKeyPair = (KeyPair) ois.readObject();

157

return oneKeyPair;

158

} catch (Exception ex) {

159

ex.printStackTrace();

160

} finally {

161

IOUtils.closeQuietly(ois);

162

IOUtils.closeQuietly(fis);

163

}

164

return null;

165

}

166

167

/**

168

* 根据给定的系数和专用指数构造一个RSA专用的公钥对象。

169

*

170

* @param modulus 系数。

171

* @param publicExponent 专用指数。

172

* @return RSA专用公钥对象。

173

*/

174

public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) {

175

RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger(modulus),

176

new BigInteger(publicExponent));

177

try {

178

return (RSAPublicKey) keyFactory.generatePublic(publicKeySpec);

179

} catch (InvalidKeySpecException ex) {

180

LOGGER.error("RSAPublicKeySpec is unavailable.", ex);

181

} catch (NullPointerException ex) {

182

LOGGER.error("RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.", ex);

183

}

184

return null;

185

}

186

187

/**

188

* 根据给定的系数和专用指数构造一个RSA专用的私钥对象。

189

*

190

* @param modulus 系数。

191

* @param privateExponent 专用指数。

192

* @return RSA专用私钥对象。

193

*/

194

public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) {

195

RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(newBigInteger(modulus),

196

new BigInteger(privateExponent));

197

try {

198

return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);

199

} catch (InvalidKeySpecException ex) {

200

LOGGER.error("RSAPrivateKeySpec is unavailable.", ex);

201

} catch (NullPointerException ex) {

202

LOGGER.error("RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.", ex);

203

}

204

return null;

205

}

206

207

/**

208

* 根据给定的16进制系数和专用指数字符串构造一个RSA专用的私钥对象。

209

*

210

* @param modulus 系数。

211

* @param privateExponent 专用指数。

212

* @return RSA专用私钥对象。

213

*/

214

public static RSAPrivateKey getRSAPrivateKey(String hexModulus, String hexPrivateExponent) {

215

if(StringUtils.isBlank(hexModulus) || StringUtils.isBlank(hexPrivateExponent)) {

216

if(LOGGER.isDebugEnabled()) {

217

LOGGER.debug("hexModulus and hexPrivateExponent cannot be empty. RSAPrivateKey value is null to return.");

218

}

219

return null;

220

}

221

byte[] modulus = null;

222

byte[] privateExponent = null;

223

try {

224

modulus = Hex.decodeHex(hexModulus.toCharArray());

225

privateExponent = Hex.decodeHex(hexPrivateExponent.toCharArray());

226

} catch(DecoderException ex) {

227

LOGGER.error("hexModulus or hexPrivateExponent value is invalid. return null(RSAPrivateKey).");

228

}

229

if(modulus != null && privateExponent != null) {

230

return generateRSAPrivateKey(modulus, privateExponent);

231

}

232

return null;

233

}

234

235

/**

236

* 根据给定的16进制系数和专用指数字符串构造一个RSA专用的公钥对象。

237

*

238

* @param modulus 系数。

239

* @param publicExponent 专用指数。

240

* @return RSA专用公钥对象。

241

*/

242

public static RSAPublicKey getRSAPublidKey(String hexModulus, String hexPublicExponent) {

243

if(StringUtils.isBlank(hexModulus) || StringUtils.isBlank(hexPublicExponent)) {

244

if(LOGGER.isDebugEnabled()) {

245

LOGGER.debug("hexModulus and hexPublicExponent cannot be empty. return null(RSAPublicKey).");

246

}

247

return null;

248

}

249

byte[] modulus = null;

250

byte[] publicExponent = null;

251

try {

252

modulus = Hex.decodeHex(hexModulus.toCharArray());

253

publicExponent = Hex.decodeHex(hexPublicExponent.toCharArray());

254

} catch(DecoderException ex) {

255

LOGGER.error("hexModulus or hexPublicExponent value is invalid. return null(RSAPublicKey).");

256

}

257

if(modulus != null && publicExponent != null) {

258

return generateRSAPublicKey(modulus, publicExponent);

259

}

260

return null;

261

}

262

263

/**

264

* 使用指定的公钥加密数据。

265

*

266

* @param publicKey 给定的公钥。

267

* @param data 要加密的数据。

268

* @return 加密后的数据。

269

*/

270

public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {

271

Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);

272

ci.init(Cipher.ENCRYPT_MODE, publicKey);

273

return ci.doFinal(data);

274

}

275

276

/**

277

* 使用指定的私钥解密数据。

278

*

279

* @param privateKey 给定的私钥。

280

* @param data 要解密的数据。

281

* @return 原数据。

282

*/

283

public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {

284

Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);

285

ci.init(Cipher.DECRYPT_MODE, privateKey);

286

return ci.doFinal(data);

287

}

288

289

/**

290

* 使用给定的公钥加密给定的字符串。

291

* <p />

292

* 若 {@code publicKey} 为 {@code null},或者 {@code plaintext} 为 {@code null} 则返回 {@code

293

* null}。

294

*

295

* @param publicKey 给定的公钥。

296

* @param plaintext 字符串。

297

* @return 给定字符串的密文。

298

*/

299

public static String encryptString(PublicKey publicKey, String plaintext) {

300

if (publicKey == null || plaintext == null) {

301

return null;

302

}

303

byte[] data = plaintext.getBytes();

304

try {

305

byte[] en_data = encrypt(publicKey, data);

306

return new String(Hex.encodeHex(en_data));

307

} catch (Exception ex) {

308

LOGGER.error(ex.getCause().getMessage());

309

}

310

return null;

311

}

312

313

/**

314

* 使用默认的公钥加密给定的字符串。

315

* <p />

316

* 若{@code plaintext} 为 {@code null} 则返回 {@code null}。

317

*

318

* @param plaintext 字符串。

319

* @return 给定字符串的密文。

320

*/

321

public static String encryptString(String plaintext) {

322

if(plaintext == null) {

323

return null;

324

}

325

byte[] data = plaintext.getBytes();

326

KeyPair keyPair = getKeyPair();

327

try {

328

byte[] en_data = encrypt((RSAPublicKey)keyPair.getPublic(), data);

329

return new String(Hex.encodeHex(en_data));

330

} catch(NullPointerException ex) {

331

LOGGER.error("keyPair cannot be null.");

332

} catch(Exception ex) {

333

LOGGER.error(ex.getCause().getMessage());

334

}

335

return null;

336

}

337

338

/**

339

* 使用给定的私钥解密给定的字符串。

340

* <p />

341

* 若私钥为 {@code null},或者 {@code encrypttext} 为 {@code null}或空字符串则返回 {@code null}。

342

* 私钥不匹配时,返回 {@code null}。

343

*

344

* @param privateKey 给定的私钥。

345

* @param encrypttext 密文。

346

* @return 原文字符串。

347

*/

348

public static String decryptString(PrivateKey privateKey, String encrypttext) {

349

if (privateKey == null || StringUtils.isBlank(encrypttext)) {

350

return null;

351

}

352

try {

353

byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());

354

byte[] data = decrypt(privateKey, en_data);

355

return new String(data);

356

} catch (Exception ex) {

357

LOGGER.error(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getCause().getMessage()));

358

}

359

return null;

360

}

361

362

/**

363

* 使用默认的私钥解密给定的字符串。

364

* <p />

365

* 若{@code encrypttext} 为 {@code null}或空字符串则返回 {@code null}。

366

* 私钥不匹配时,返回 {@code null}。

367

*

368

* @param encrypttext 密文。

369

* @return 原文字符串。

370

*/

371

public static String decryptString(String encrypttext) {

372

if(StringUtils.isBlank(encrypttext)) {

373

return null;

374

}

375

KeyPair keyPair = getKeyPair();

376

try {

377

byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());

378

byte[] data = decrypt((RSAPrivateKey)keyPair.getPrivate(), en_data);

379

return new String(data);

380

} catch(NullPointerException ex) {

381

LOGGER.error("keyPair cannot be null.");

382

} catch (Exception ex) {

383

LOGGER.error(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getMessage()));

384

}

385

return null;

386

}

387

388

/**

389

* 使用默认的私钥解密由JS加密(使用此类提供的公钥加密)的字符串。

390

*

391

* @param encrypttext 密文。

392

* @return {@code encrypttext} 的原文字符串。

393

*/

394

public static String decryptStringByJs(String encrypttext) {

395

String text = decryptString(encrypttext);

396

if(text == null) {

397

return null;

398

}

399

return StringUtils.reverse(text);

400

}

401

402

/** 返回已初始化的默认的公钥。*/

403

public static RSAPublicKey getDefaultPublicKey() {

404

KeyPair keyPair = getKeyPair();

405

if(keyPair != null) {

406

return (RSAPublicKey)keyPair.getPublic();

407

}

408

return null;

409

}

410

411

/** 返回已初始化的默认的私钥。*/

412

public static RSAPrivateKey getDefaultPrivateKey() {

413

KeyPair keyPair = getKeyPair();

414

if(keyPair != null) {

415

return (RSAPrivateKey)keyPair.getPrivate();

416

}

417

return null;

418

}

419

}

3. [代码][Java]代码

01

// Struts2 Action方法中:

02

// 将公钥的 modulus 和 exponent 传给页面。

03

// Hex -> apache commons-codec

04

RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();

05

ActionContext.getContext().put("modulus", newString(Hex.encodeHex(publicKey.getModulus().toByteArray())));

06

ActionContext.getContext().put("exponent", newString(Hex.encodeHex(publicKey.getPublicExponent().toByteArray())));

07

08

// 页面里,Javascript对明文进行加密:

09

var modulus = $('#hid_modulus').val(), exponent = $('#hid_exponent').val();

10

var key = RSAUtils.getKeyPair(exponent, '', modulus);

11

pwd1 = RSAUtils.encryptedString(key, pwd1);

12

pwd2 = RSAUtils.encryptedString(key, pwd2);

13

14

// 服务器端,使用RSAUtils工具类对密文进行解密

15

RSAUtils.decryptStringByJs(password1);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: