js加密,java解密

在pom.xml中加入依赖

<dependency>
	    <groupId>org.bouncycastle</groupId>
	    <artifactId>bcprov-jdk15on</artifactId>
	    <version>1.47</version>
	</dependency>

RSA工具类

/**
 * @author lee
 */
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.Cipher;



/**
 * RSA 工具类。提供加密,解密,生成密钥对等方法。
 * 需要到http://www.bouncycastle.org下载bcprov-jdk14-123.jar。
 * 
 */
public class RSAUtil {
	/**
	 * * 生成密钥对 *
	 * 
	 * @return KeyPair *
	 * @throws EncryptException
	 */
	public static KeyPair generateKeyPair() throws Exception {
		try {
			KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			final int KEY_SIZE = 1024;// 没什么好说的了,这个值关系到块加密的大小,可以更改,但是不要太大,否则效率会低
			keyPairGen.initialize(KEY_SIZE, new SecureRandom());
			KeyPair keyPair = keyPairGen.generateKeyPair();
			saveKeyPair(keyPair);
			return keyPair;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}
	
	public static KeyPair getKeyPair()throws Exception{
		FileInputStream fis = new FileInputStream("C:/RSAKey.txt");
		 ObjectInputStream oos = new ObjectInputStream(fis);
		 KeyPair kp= (KeyPair) oos.readObject();
		 oos.close();
		 fis.close();
		 return kp;
	}
	
	public static void saveKeyPair(KeyPair kp)throws Exception{
		
		 FileOutputStream fos = new FileOutputStream("C:/RSAKey.txt");
         ObjectOutputStream oos = new ObjectOutputStream(fos);
         //生成密钥
         oos.writeObject(kp);
         oos.close();
         fos.close();
	}

	/**
	 * * 生成公钥 *
	 * 
	 * @param modulus *
	 * @param publicExponent *
	 * @return RSAPublicKey *
	 * @throws Exception
	 */
	public static RSAPublicKey generateRSAPublicKey(byte[] modulus,
			byte[] publicExponent) throws Exception {
		KeyFactory keyFac = null;
		try {
			keyFac = KeyFactory.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
		} catch (NoSuchAlgorithmException ex) {
			throw new Exception(ex.getMessage());
		}

		RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(
				modulus), new BigInteger(publicExponent));
		try {
			return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
		} catch (InvalidKeySpecException ex) {
			throw new Exception(ex.getMessage());
		}
	}

	/**
	 * * 生成私钥 *
	 * 
	 * @param modulus *
	 * @param privateExponent *
	 * @return RSAPrivateKey *
	 * @throws Exception
	 */
	public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus,
			byte[] privateExponent) throws Exception {
		KeyFactory keyFac = null;
		try {
			keyFac = KeyFactory.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
		} catch (NoSuchAlgorithmException ex) {
			throw new Exception(ex.getMessage());
		}

		RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(
				modulus), new BigInteger(privateExponent));
		try {
			return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
		} catch (InvalidKeySpecException ex) {
			throw new Exception(ex.getMessage());
		}
	}

	/**
	 * * 加密 *
	 * 
	 * @param key
	 *            加密的密钥 *
	 * @param data
	 *            待加密的明文数据 *
	 * @return 加密后的数据 *
	 * @throws Exception
	 */
	public static byte[] encrypt(PublicKey pk, byte[] data) throws Exception {
		try {
			Cipher cipher = Cipher.getInstance("RSA",
					new org.bouncycastle.jce.provider.BouncyCastleProvider());
			cipher.init(Cipher.ENCRYPT_MODE, pk);
			int blockSize = cipher.getBlockSize();// 获得加密块大小,如:加密前数据为128个byte,而key_size=1024
			// 加密块大小为127
			// byte,加密后为128个byte;因此共有2个加密块,第一个127
			// byte第二个为1个byte
			int outputSize = cipher.getOutputSize(data.length);// 获得加密块加密后块大小
			int leavedSize = data.length % blockSize;
			int blocksSize = leavedSize != 0 ? data.length / blockSize + 1
					: data.length / blockSize;
			byte[] raw = new byte[outputSize * blocksSize];
			int i = 0;
			while (data.length - i * blockSize > 0) {
				if (data.length - i * blockSize > blockSize)
					cipher.doFinal(data, i * blockSize, blockSize, raw, i
							* outputSize);
				else
					cipher.doFinal(data, i * blockSize, data.length - i
							* blockSize, raw, i * outputSize);
				// 这里面doUpdate方法不可用,查看源代码后发现每次doUpdate后并没有什么实际动作除了把byte[]放到
				// ByteArrayOutputStream中,而最后doFinal的时候才将所有的byte[]进行加密,可是到了此时加密块大小很可能已经超出了
				// OutputSize所以只好用dofinal方法。

				i++;
			}
			return raw;
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
	}

	/**
	 * * 解密 *
	 * 
	 * @param key
	 *            解密的密钥 *
	 * @param raw
	 *            已经加密的数据 *
	 * @return 解密后的明文 *
	 * @throws Exception
	 */
	public static byte[] decrypt(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());
		}
	}

	/**
	 * * *
	 * 
	 * @param args *
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		RSAPublicKey rsap = (RSAPublicKey) RSAUtil.generateKeyPair().getPublic();
		
		System.out.println(rsap.getModulus().toString(16));
		System.out.println(rsap.getPublicExponent().toString(16));
		
		//System.out.println(RSAUtil.getKeyPair().getPrivate());
		
		String test = "hello world";
		byte[] en_test = encrypt(getKeyPair().getPublic(),test.getBytes());
		byte[] de_test = decrypt(getKeyPair().getPrivate(),en_test);
		System.out.println(new String(de_test));
	}
}

IndexAction.java

import java.security.interfaces.RSAPublicKey;

import com.leech.util.RSAUtil;
import com.opensymphony.xwork2.ActionContext;


public class IndexAction {
	
	public String execute() throws Exception {
		RSAPublicKey rsap = (RSAPublicKey) RSAUtil.getKeyPair().getPublic();
		String module = rsap.getModulus().toString(16);
		String empoent = rsap.getPublicExponent().toString(16);
		System.out.println("module");
		System.out.println(module);
		System.out.println("empoent");
		System.out.println(empoent);
		
		System.out.println("private");
		System.out.println(RSAUtil.getKeyPair().getPrivate());
		
		ActionContext.getContext().put("m", module);
		ActionContext.getContext().put("e", empoent);
		
		return "success";
	}
}

LoginAction.java

import java.math.BigInteger;

import org.apache.struts2.ServletActionContext;

import com.leech.util.RSAUtil;


public class LoginAction {
	
	public String execute() throws Exception{
		String result = ServletActionContext.getRequest().getParameter("result");
		System.out.println("原文加密后为:");
		System.out.println(result);
		byte[] en_result = new BigInteger(result, 16).toByteArray();
		System.out.println("转成byte[]"+new String(en_result));
		byte[] de_result = RSAUtil.decrypt(RSAUtil.getKeyPair().getPrivate(),en_result);
		System.out.println("还原密文:");
		
		System.out.println(new String(de_result));
		StringBuffer sb = new StringBuffer();
		sb.append(new String(de_result));
		System.out.println(sb.reverse().toString());
		return "success";
	}
}

struts.xml配置

<action name="index" class="com.leech.action.IndexAction">
        	<result>/login_03.jsp</result>
        </action>
        
        <action name="login" class="com.leech.action.LoginAction">
        	<result>/index.jsp</result>
        </action>

login_03.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
		
		<script type="text/javascript" src="${ctx}/js/rsa/RSA.js"></script>
		<script type="text/javascript" src="${ctx}/js/rsa/BigInt.js"></script>
		<script type="text/javascript" src="${ctx}/js/rsa/Barrett.js"></script>
		
		<script type="text/javascript">
			function rsalogin(){
			   bodyRSA();
			   var result = encryptedString(key, document.getElementById("pwd").value);
			   //alert(result);
			   loginForm.action="login.action?result="+result;
			   loginForm.submit();
			}
			var key ;
			function bodyRSA(){
				setMaxDigits(130);
			  	key = new RSAKeyPair('${e}',"",'${m}'); 
			  
			}
		</script>
	</head>
	<body>
		<form action="login.action" method="post" name="loginForm">
	      <table border="0">
	        <tr>
	          <td>Login:</td>
	          <td>
	          	<input type="text" name="username" />
	          </td>
	        </tr>
	        <tr>
	          <td>Password:</td>
	          <td>
	          	<input type="password" name="password" id="pwd" styleId="pwd"/>
	          </td>
	        </tr>
	        <tr>
	          <td colspan="2" align="center">
	          	<input type="button" value="SUBMIT" onclick="rsalogin();"/>
	          </td>
	        </tr>
	      </table>
	    </form>  
	 </body>
</body>
</html>

js文件下载请参考:http://sunxboy.iteye.com/blog/209156 

你可能感兴趣的:(js加密,java解密)