Java-web中利用RSA进行加密解密操作的方法示例
程序员文章站
2024-02-20 21:41:46
前言
最近在看,网络安全方面的问题,我们可以使用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(); } }
下载:
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。