欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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();
 }
}

下载:

总结

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