当前位置: 移动技术网 > IT编程>开发语言>Java > Java-web中利用RSA进行加密解密操作的方法示例

Java-web中利用RSA进行加密解密操作的方法示例

2019年07月19日  | 移动技术网IT编程  | 我要评论
前言 最近在看,网络安全方面的问题,我们可以使用rsa进行非对称加密防止,获取用户信息。首先我们看下java下操作rsa进行加密解密算法,代码如下: packa

前言

最近在看,网络安全方面的问题,我们可以使用rsa进行非对称加密防止,获取用户信息。首先我们看下java下操作rsa进行加密解密算法,代码如下:

package com.jb.test;
 
import java.security.invalidkeyexception;
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 javax.crypto.badpaddingexception;
import javax.crypto.cipher;
import javax.crypto.illegalblocksizeexception;
import javax.crypto.nosuchpaddingexception;
 
import org.apache.commons.codec.binary.hex;
 
public class rsaentry {
 
 /**
 * @title: main
 * @description: rsa加密算法,解密算法
 * @param args
 * void
 * @throws nosuchalgorithmexception 
 * @throws nosuchpaddingexception 
 * @throws invalidkeyexception 
 * @throws badpaddingexception 
 * @throws illegalblocksizeexception 
 * 
 * @throws
 */
 public static void main(string[] args) throws nosuchalgorithmexception, nosuchpaddingexception, invalidkeyexception, illegalblocksizeexception, badpaddingexception {
// security.getproviders();//获取所有支持的加密算法
 //采用非对称加密解密算法
 //生成密钥实例
 keypairgenerator keygen = keypairgenerator.getinstance("rsa");
 securerandom random = new securerandom();
 random.setseed(system.currenttimemillis());//设置随机种子
 keygen.initialize(512, random);//设置密钥长度,应为64的整数倍
 //生成密钥公钥对
 keypair keypair = keygen.generatekeypair();
 //获取公钥
 publickey pubkey = keypair.getpublic();
 //获取私钥
 privatekey prikey = keypair.getprivate();
 //测试数据
 string data = "测试数据";
 //使用公钥进行加密
 //构建加密解密类
 cipher cipher = cipher.getinstance("rsa");
 cipher.init(cipher.encrypt_mode, pubkey);//设置为加密模式
 byte[] jmdata = cipher.dofinal(data.getbytes());
 //打印加密后数据
 system.out.println(new string(hex.encodehex(jmdata)));
 //改为解密模式进行解密
 cipher.init(cipher.decrypt_mode, prikey);//会用私钥解密
 jmdata = cipher.dofinal(jmdata);
 system.out.println(new string(jmdata));
 
 }
}

在web应用中,我们可以通过js进行前端加密,java进行后台解密,已达到我们的目的。这里需要注意的是,要想实现正确的加密解密算法,需要使用bcprov-ext-jdk15on-147.jar。

首先创建系统的密钥提供者:

package com.jb.test;
 
import java.security.keypair;
import java.security.keypairgenerator;
import java.security.privatekey;
import java.security.publickey;
import java.security.securerandom;
 
import org.apache.commons.codec.binary.hex;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.bcrsapublickey;
import org.bouncycastle.jce.provider.bouncycastleprovider;
 
/**
 * rsa初始化类
 * @author nmm
 * 结合前台的js使用的话,主要需要指定密钥提供者,即引入bcprov-ext-jdk15on-147.jar并使用其中的提供者
 */
public class rsainitutil {
 
 private static keypair keypair;
 
 private static rsainitutil util;
 
 private rsainitutil(){
 try {
 if(keypair == null) {
 //如果想要能够解密js的加密文件,使用此提供者是必须的
 keypairgenerator keygen = keypairgenerator.getinstance("rsa", new bouncycastleprovider());
 securerandom random = new securerandom();
 random.setseed(system.currenttimemillis());
 keygen.initialize(512, random);//设置512位长度
 keypair = keygen.generatekeypair();
 }
 } catch (exception e) {
 e.printstacktrace();
 }
 }
 
 public static rsainitutil getinstance(){
 synchronized ("rsa") {
 if(util == null) {
 util = new rsainitutil();
 }
 }
 return util;
 }
 
 /**
 * 
 * 功能说明:[获取公钥]
 * @return
 * 创建者:nmm, aug 19, 2013
 */
 public publickey getpublickey(){
 return keypair.getpublic();
 }
 
 public privatekey getprivatekey(){
 return keypair.getprivate();
 }
 
 /**
 * 
 * 功能说明:[获取公钥字符串]
 * @return
 * 创建者:nmm, aug 19, 2013
 */
 public string getpublickeystr(){
 //根据我们的提供者,这里获取的是该类型公钥
 bcrsapublickey pk = (bcrsapublickey) getpublickey();
 string str = new string(hex.encodehex(pk.getmodulus().tobytearray()));
 system.out.println(str);
 //获取入口10001一般都为这个
 string ss = new string(hex.encodehex(pk.getpublicexponent().tobytearray()));
 //获取转换字符串
 system.out.println(b2hex(pk.getmodulus().tobytearray()));
 return ss + str;
 }
 /**
 * 
 * 功能说明:[手动转换]
 * @param bytearray
 * @return
 * 创建者:nmm, aug 19, 2013
 */
 private string b2hex(byte[] bytearray) {
 stringbuilder sb = new stringbuilder();
 for(int i = 0; i < bytearray.length; i++ ) {
 int zhz = bytearray[i];
 if(zhz < 0) {
 zhz += 256;
 }
 if(zhz < 16) {
 sb.append("0");
 }
 sb.append(integer.tohexstring(zhz));
 }
 return sb.tostring();
 }
}

前台引入rsa.js,bigint.js和barrett.js并采用如下方法加密:

<%@ page language="java" import="java.util.*" pageencoding="utf-8"%>
<%@page import="com.jb.test.rsainitutil"%>
<%
 
 rsainitutil rsa = rsainitutil.getinstance();
 string my = rsa.getpublickeystr();
 string exp = my.substring(0,6);
 string mou = my.substring(6);
%>
<!doctype html public "-//w3c//dtd html 4.01 transitional//en">
<html>
 <head>
 <title>rsa测试</title>
 <script type="text/javascript" src="rsa.js"></script>
 <script type="text/javascript" src="bigint.js"></script>
 <script type="text/javascript" src="barrett.js"></script>
 </head>
 
 <body>
 </body>
</html>
<script type="text/javascript">
 
 var m = '<%=mou%>';
 var e = '<%=exp%>';
 
 var key = '';
 setmaxdigits(128);
 alert(e);
 key = new rsakeypair(e,'',m);
 var res = encryptedstring(key,encodeuricomponent('测试数据'));
 
 window.location.href = 'rsadectry.do?res=' + res;
 
</script>

后台解密算法为:

package com.jb.test;
 
import java.net.urldecoder;
import java.security.nosuchalgorithmexception;
 
import javax.crypto.cipher;
import javax.crypto.nosuchpaddingexception;
 
import org.apache.commons.codec.binary.hex;
import org.bouncycastle.jce.provider.bouncycastleprovider;
import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;
 
/**
 * rsa加密的控制层
 * @author nmm
 *
 */
@controller("rsacontroller")
public class rsacontroller {
 
 private rsainitutil rsautil = rsainitutil.getinstance();
 
 /**
 * 
 * 功能说明:[解密方法]
 * @param res
 * 创建者:nmm, aug 19, 2013
 * @throws nosuchpaddingexception 
 * @throws nosuchalgorithmexception 
 */
 @requestmapping("rsadectry.do")
 public void decodetry(string res) throws exception {
 cipher cipher = cipher.getinstance("rsa",new bouncycastleprovider());//必须指定此提供者
 cipher.init(cipher.decrypt_mode, rsautil.getprivatekey());
 system.out.println(res);
 byte[] buff = cipher.dofinal(hex.decodehex(res.tochararray()));
 //将字符串转为字符
 stringbuilder sb = new stringbuilder(new string(buff,"utf-8"));
 //解密后的内容是倒叙的
 sb.reverse();
 //进行url解密,主要是为了中文乱码问题
 string result = urldecoder.decode(sb.tostring(), "utf-8");
 system.out.println(result);
 
 }
}

至此可完成,整个加密解密过程,下面大家可以把rsa相关的内容全部整合到一个工具类中,不用想这里处理。

下面为rsa加密解密工具类:

package com.jb.framework.filter;
 
import java.io.fileinputstream;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.io.objectinputstream;
import java.io.objectoutputstream;
import java.math.biginteger;
import java.net.urldecoder;
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.spec.rsaprivatekeyspec;
import java.security.spec.rsapublickeyspec;
import java.util.calendar;
 
import javax.crypto.cipher;
 
import org.apache.commons.codec.binary.hex;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.bcrsapublickey;
import org.bouncycastle.jce.provider.bouncycastleprovider;
 
/**
 * 
 * @package: com.jb.framework.filter<br>
 * @classname: rsautil<br>
 * @description: rsa加密工具类,这里我们是每次系统启动时声称一套公钥,私钥,因此不能将加密串存入数据库中,如果要这么做可以预先生成密钥队写入到文件中<br>
 */
public class rsautil {
 
 private rsautil(){}
 
 public static final string keypubfile = "rsapubkey.bin";
 public static final string keyprifile = "rsaprikey.bin";
 
 private static rsautil rsa;
 //密钥生成器
 private publickey publickey;
 //密钥队
 private privatekey privatekey; 
 
 
 public static rsautil getinstance(){
 synchronized ("rsa") {
 if(rsa == null) {
 rsa = new rsautil();
 rsa.init();
 }
 }
 return rsa;
 }
 /**
 * 
 * @title: init
 * @description: 初始化方法
 * void
 * @throws
 */
 private void init() {
 //构建rsa算法
 try {
 keypairgenerator kengen = keypairgenerator.getinstance("rsa",new bouncycastleprovider());
 //构建随机种子
 securerandom random = new securerandom();
 random.setseed(calendar.getinstance().gettimeinmillis());
 kengen.initialize(512, random);//采用512位加密
 keypair keypair = kengen.generatekeypair();
 publickey = keypair.getpublic();
 privatekey = keypair.getprivate();
 } catch (nosuchalgorithmexception e) {
 e.printstacktrace();
 }
 }
 /**
 * 
 * @title: getpublickey
 * @description: 获取公钥
 * @return
 * publickey
 * @throws
 */
 public publickey getpublickey(){
 return this.publickey;
 }
 /**
 * 
 * @title: getprivatekey
 * @description: 获取私钥
 * @return
 * privatekey
 * @throws
 */
 public privatekey getprivatekey(){
 return this.privatekey;
 }
 /**
 * 
 * @title: getpublickeystr
 * @description: 获取系统公钥字符串,前6位为exponentk,后面为modlus
 * @return
 * string
 * @throws
 */
 public string getpublickeystr(){
 bcrsapublickey pk = (bcrsapublickey) getpublickey();
 string pubstr = "";
 pubstr += b2hex(pk.getpublicexponent().tobytearray());
 pubstr += b2hex(pk.getmodulus().tobytearray());
 return pubstr;
 }
 /**
 * 
 * @title: entrytext
 * @description: 使用默认公钥进行加密
 * @param text
 * @return
 * string
 * @throws
 */
 public string encrytext(string text) {
 return encrytext(text,getpublickey());
 }
 /**
 * 
 * @title: entrytext
 * @description: 使用指定公钥进行加密,解决长字符串加密
 * @param text
 * @param publickey2
 * @return
 * string
 * @throws
 */
 public string encrytext(string text, publickey pk) {
 try {
 cipher cipher = cipher.getinstance("rsa",new bouncycastleprovider());
 cipher.init(cipher.encrypt_mode, pk);
 int block = cipher.getblocksize();//获取最大加密块
 int j = 0;
 stringbuilder sb = new stringbuilder();
 byte[] targetdata = text.getbytes("utf-8");
 while (targetdata.length - j*block > 0) {
 byte[] jmdata = cipher.dofinal(targetdata,j*block,math.min(targetdata.length - j*block, block));
 sb.append(b2hex(jmdata));
 j++;
 }
 return sb.tostring();
 } catch (exception e) {
 e.printstacktrace();
 }
 return null;
 }
 /**
 * 
 * @title: decrytext
 * @description: 使用默认的私钥进行解密解密算法
 * @param text
 * @return
 * string
 * @throws
 */
 public string decrytext(string text) {
 return decrytext(text,getprivatekey());
 }
 /**
 * 
 * @title: decrytext
 * @description: 指定私钥进行解密,增加对于大字符串的解密操作
 * @param text
 * @param privatekey2
 * @return
 * string
 * @throws
 */
 public string decrytext(string text, privatekey pk) {
 try {
 cipher cipher = cipher.getinstance("rsa", new bouncycastleprovider());
 cipher.init(cipher.decrypt_mode, pk);
 byte[] targetbuff = hex.decodehex(text.replace(" ", "").tochararray());
 int block = cipher.getblocksize();
 int j = 0;
 stringbuilder sb = new stringbuilder();
 while (targetbuff.length - j * block > 0) {
 byte[] jmdata = cipher.dofinal(targetbuff,j*block,block);
 sb.append(new string(jmdata,"utf-8"));
 j++;
 }
 return sb.tostring();
 
 } catch (exception e) {
 e.printstacktrace();
 }
 return null;
 }
 /**
 * 
 * @title: decrytextbyurl
 * @description: 解密前台传递的加密串,为防止中文乱码,前台字符串最好使用encodeuricomponent方法进行url编码
 * @param text
 * @return
 * string
 * @throws
 */
 public string decrytextbyurl(string text) {
 try {
 cipher cipher = cipher.getinstance("rsa", new bouncycastleprovider());
 cipher.init(cipher.decrypt_mode, getprivatekey());
 byte[] targetbuff = hex.decodehex(text.replace(" ", "").tochararray());
 int block = cipher.getblocksize();
 int j = 0;
 stringbuilder sb = new stringbuilder();
 while (targetbuff.length - j * block > 0) {//处理大字符串的加密解密处理
 byte[] jmdata = cipher.dofinal(targetbuff,j*block,block);
 sb.append(new stringbuilder(new string(jmdata,"utf-8")).reverse());
 j++;
 }
 string res = urldecoder.decode(sb.tostring(), "utf-8");
 return res;
 
 } catch (exception e) {
 e.printstacktrace();
 }
 return null;
 }
 /**
 * 
 * @title: createpubkey
 * @description: 根据指定的幂和模式生成公钥
 * @param exponent
 * @param modules
 * @return
 * publickey
 * @throws
 */
 public publickey createpubkey(byte[] exponent,byte[]modules) {
 try {
 keyfactory keyfactory = keyfactory.getinstance("rsa", new bouncycastleprovider());
 rsapublickeyspec rsaks = new rsapublickeyspec(new biginteger(modules),new biginteger(exponent));
 return keyfactory.generatepublic(rsaks);
 
 } catch (exception e) {
 e.printstacktrace();
 }
 
 return null;
 }
 /**
 * 
 * @title: createpubkey
 * @description: 根据指定的幂和模式生成公钥
 * @param exponent
 * @param modules
 * @return
 * publickey
 * @throws
 */
 public privatekey createprikey(byte[] exponent,byte[]modules) {
 try {
 keyfactory keyfactory = keyfactory.getinstance("rsa", new bouncycastleprovider());
 rsaprivatekeyspec rsaks = new rsaprivatekeyspec(new biginteger(modules),new biginteger(exponent));
 return keyfactory.generateprivate(rsaks);
 
 } catch (exception e) {
 e.printstacktrace();
 }
 return null;
 }
 /**
 * 
 * @title: savekeytofile
 * @description: 保存公钥和私钥到文件中
 * void
 * @throws
 */
 public void savekeytofile() {
 publickey pk = getpublickey();
 privatekey prik = getprivatekey();
 
 string path = rsautil.class.getclassloader().getresource("").getpath();
 objectoutputstream outpub = null;
 objectoutputstream outpri = null;
 try {
 system.out.println(path + keypubfile);
 outpub = new objectoutputstream(new fileoutputstream(path + keypubfile));
 outpri = new objectoutputstream(new fileoutputstream(path + keyprifile));
 outpub.writeobject(pk);
 outpri.writeobject(prik);
 } catch (exception e) {
 e.printstacktrace();
 }finally {
 try {
 outpub.close();
 outpri.close();
 } catch (ioexception e) {
 e.printstacktrace();
 }
 
 }
 }
 /**
 * 
 * @title: readkey
 * @description: 读取密钥
 * @param ispub
 * @return
 * object
 * @throws
 */
 public object readkey(boolean ispub) {
 string path = rsautil.class.getclassloader().getresource("").getpath();
 objectinputstream in = null;
 try {
 if(ispub) {
 path += keypubfile;
 in = new objectinputstream(new fileinputstream(path));
 publickey pk = (publickey) in.readobject();
 return pk;
 }else {
 path += keyprifile;
 in = new objectinputstream(new fileinputstream(path));
 privatekey pk = (privatekey) in.readobject();
 return pk;
 }
 } catch (exception e) {
 e.printstacktrace();
 }finally {
 try {
 in.close();
 } catch (ioexception e) {
 e.printstacktrace();
 }
 }
 return null;
 }
 
 
 /**
 * 
 * @title: b2hex
 * @description: 将二进制转为16进制字符串
 * @param buff
 * @return
 * string
 * @throws
 */
 public string b2hex(byte[] buff) {
 stringbuilder sb = new stringbuilder();
 for(int i = 0; i < buff.length; i++) {
 int z = buff[i];
 if(z < 0) {
 z+= 256;
 }
 if(z < 16) {
 sb.append("0");
 }
 sb.append(integer.tohexstring(z));
 }
 return sb.tostring();
 }
}

下载:

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网