Java-web中利用RSA进行加密解密操作的方法示例
前言
最近在看,网络安全方面的问题,我们可以使用RSA进行非对称加密防止,获取用户信息。首先我们看下java下操作RSA进行加密解密算法,代码如下:
packagecom.jb.test;
importjava.security.InvalidKeyException;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.NoSuchAlgorithmException;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.SecureRandom;
importjavax.crypto.BadPaddingException;
importjavax.crypto.Cipher;
importjavax.crypto.IllegalBlockSizeException;
importjavax.crypto.NoSuchPaddingException;
importorg.apache.commons.codec.binary.Hex;
publicclassRSAEntry{
/**
*@Title:main
*@Description:RSA加密算法,解密算法
*@paramargs
*void
*@throwsNoSuchAlgorithmException
*@throwsNoSuchPaddingException
*@throwsInvalidKeyException
*@throwsBadPaddingException
*@throwsIllegalBlockSizeException
*
*@throws
*/
publicstaticvoidmain(String[]args)throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException{
//Security.getProviders();//获取所有支持的加密算法
//采用非对称加密解密算法
//生成密钥实例
KeyPairGeneratorkeygen=KeyPairGenerator.getInstance("RSA");
SecureRandomrandom=newSecureRandom();
random.setSeed(System.currentTimeMillis());//设置随机种子
keygen.initialize(512,random);//设置密钥长度,应为64的整数倍
//生成密钥公钥对
KeyPairkeyPair=keygen.generateKeyPair();
//获取公钥
PublicKeypubkey=keyPair.getPublic();
//获取私钥
PrivateKeyprikey=keyPair.getPrivate();
//测试数据
Stringdata="测试数据";
//使用公钥进行加密
//构建加密解密类
Ciphercipher=Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE,pubkey);//设置为加密模式
byte[]jmdata=cipher.doFinal(data.getBytes());
//打印加密后数据
System.out.println(newString(Hex.encodeHex(jmdata)));
//改为解密模式进行解密
cipher.init(Cipher.DECRYPT_MODE,prikey);//会用私钥解密
jmdata=cipher.doFinal(jmdata);
System.out.println(newString(jmdata));
}
}
在web应用中,我们可以通过js进行前端加密,java进行后台解密,已达到我们的目的。这里需要注意的是,要想实现正确的加密解密算法,需要使用bcprov-ext-jdk15on-147.jar。
首先创建系统的密钥提供者:
packagecom.jb.test;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.SecureRandom;
importorg.apache.commons.codec.binary.Hex;
importorg.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*RSA初始化类
*@authornmm
*结合前台的js使用的话,主要需要指定密钥提供者,即引入bcprov-ext-jdk15on-147.jar并使用其中的提供者
*/
publicclassRsaInitUtil{
privatestaticKeyPairkeyPair;
privatestaticRsaInitUtilutil;
privateRsaInitUtil(){
try{
if(keyPair==null){
//如果想要能够解密js的加密文件,使用此提供者是必须的
KeyPairGeneratorkeygen=KeyPairGenerator.getInstance("RSA",newBouncyCastleProvider());
SecureRandomrandom=newSecureRandom();
random.setSeed(System.currentTimeMillis());
keygen.initialize(512,random);//设置512位长度
keyPair=keygen.generateKeyPair();
}
}catch(Exceptione){
e.printStackTrace();
}
}
publicstaticRsaInitUtilgetInstance(){
synchronized("rsa"){
if(util==null){
util=newRsaInitUtil();
}
}
returnutil;
}
/**
*
*功能说明:[获取公钥]
*@return
*创建者:Nmm,Aug19,2013
*/
publicPublicKeygetPublicKey(){
returnkeyPair.getPublic();
}
publicPrivateKeygetPrivateKey(){
returnkeyPair.getPrivate();
}
/**
*
*功能说明:[获取公钥字符串]
*@return
*创建者:Nmm,Aug19,2013
*/
publicStringgetPublicKeyStr(){
//根据我们的提供者,这里获取的是该类型公钥
BCRSAPublicKeypk=(BCRSAPublicKey)getPublicKey();
Stringstr=newString(Hex.encodeHex(pk.getModulus().toByteArray()));
System.out.println(str);
//获取入口10001一般都为这个
Stringss=newString(Hex.encodeHex(pk.getPublicExponent().toByteArray()));
//获取转换字符串
System.out.println(b2Hex(pk.getModulus().toByteArray()));
returnss+str;
}
/**
*
*功能说明:[手动转换]
*@parambyteArray
*@return
*创建者:Nmm,Aug19,2013
*/
privateStringb2Hex(byte[]byteArray){
StringBuildersb=newStringBuilder();
for(inti=0;i
前台引入RSA.js,BigInt.js和Barrett.js并采用如下方法加密:
<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%@pageimport="com.jb.test.RsaInitUtil"%>
<%
RsaInitUtilrsa=RsaInitUtil.getInstance();
Stringmy=rsa.getPublicKeyStr();
Stringexp=my.substring(0,6);
Stringmou=my.substring(6);
%>
RSA测试
varm='<%=mou%>';
vare='<%=exp%>';
varkey='';
setMaxDigits(128);
alert(e);
key=newRSAKeyPair(e,'',m);
varres=encryptedString(key,encodeURIComponent('测试数据'));
window.location.href='rsaDecTry.do?res='+res;
后台解密算法为:
packagecom.jb.test;
importjava.net.URLDecoder;
importjava.security.NoSuchAlgorithmException;
importjavax.crypto.Cipher;
importjavax.crypto.NoSuchPaddingException;
importorg.apache.commons.codec.binary.Hex;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
/**
*Rsa加密的控制层
*@authornmm
*
*/
@Controller("rsaController")
publicclassRsaController{
privateRsaInitUtilrsaUtil=RsaInitUtil.getInstance();
/**
*
*功能说明:[解密方法]
*@paramres
*创建者:Nmm,Aug19,2013
*@throwsNoSuchPaddingException
*@throwsNoSuchAlgorithmException
*/
@RequestMapping("rsaDecTry.do")
publicvoiddecodeTry(Stringres)throwsException{
Ciphercipher=Cipher.getInstance("RSA",newBouncyCastleProvider());//必须指定此提供者
cipher.init(Cipher.DECRYPT_MODE,rsaUtil.getPrivateKey());
System.out.println(res);
byte[]buff=cipher.doFinal(Hex.decodeHex(res.toCharArray()));
//将字符串转为字符
StringBuildersb=newStringBuilder(newString(buff,"UTF-8"));
//解密后的内容是倒叙的
sb.reverse();
//进行URL解密,主要是为了中文乱码问题
Stringresult=URLDecoder.decode(sb.toString(),"UTF-8");
System.out.println(result);
}
}
至此可完成,整个加密解密过程,下面大家可以把rsa相关的内容全部整合到一个工具类中,不用想这里处理。
下面为RSA加密解密工具类:
packagecom.jb.framework.filter;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
importjava.math.BigInteger;
importjava.net.URLDecoder;
importjava.security.KeyFactory;
importjava.security.KeyPair;
importjava.security.KeyPairGenerator;
importjava.security.NoSuchAlgorithmException;
importjava.security.PrivateKey;
importjava.security.PublicKey;
importjava.security.SecureRandom;
importjava.security.spec.RSAPrivateKeySpec;
importjava.security.spec.RSAPublicKeySpec;
importjava.util.Calendar;
importjavax.crypto.Cipher;
importorg.apache.commons.codec.binary.Hex;
importorg.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey;
importorg.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*
*@Package:com.jb.framework.filter
*@ClassName:RSAUtil
*@Description:RSA加密工具类,这里我们是每次系统启动时声称一套公钥,私钥,因此不能将加密串存入数据库中,如果要这么做可以预先生成密钥队写入到文件中
*/
publicclassRSAUtil{
privateRSAUtil(){}
publicstaticfinalStringkeyPubFile="rsaPubKey.bin";
publicstaticfinalStringkeyPriFile="rsaPriKey.bin";
privatestaticRSAUtilrsa;
//密钥生成器
privatePublicKeypublicKey;
//密钥队
privatePrivateKeyprivateKey;
publicstaticRSAUtilgetInstance(){
synchronized("rsa"){
if(rsa==null){
rsa=newRSAUtil();
rsa.init();
}
}
returnrsa;
}
/**
*
*@Title:init
*@Description:初始化方法
*void
*@throws
*/
privatevoidinit(){
//构建RSA算法
try{
KeyPairGeneratorkengen=KeyPairGenerator.getInstance("RSA",newBouncyCastleProvider());
//构建随机种子
SecureRandomrandom=newSecureRandom();
random.setSeed(Calendar.getInstance().getTimeInMillis());
kengen.initialize(512,random);//采用512位加密
KeyPairkeyPair=kengen.generateKeyPair();
publicKey=keyPair.getPublic();
privateKey=keyPair.getPrivate();
}catch(NoSuchAlgorithmExceptione){
e.printStackTrace();
}
}
/**
*
*@Title:getPublicKey
*@Description:获取公钥
*@return
*PublicKey
*@throws
*/
publicPublicKeygetPublicKey(){
returnthis.publicKey;
}
/**
*
*@Title:getPrivateKey
*@Description:获取私钥
*@return
*PrivateKey
*@throws
*/
publicPrivateKeygetPrivateKey(){
returnthis.privateKey;
}
/**
*
*@Title:getPublicKeyStr
*@Description:获取系统公钥字符串,前6位为exponentk,后面为modlus
*@return
*String
*@throws
*/
publicStringgetPublicKeyStr(){
BCRSAPublicKeypk=(BCRSAPublicKey)getPublicKey();
StringpubStr="";
pubStr+=b2hex(pk.getPublicExponent().toByteArray());
pubStr+=b2hex(pk.getModulus().toByteArray());
returnpubStr;
}
/**
*
*@Title:entryText
*@Description:使用默认公钥进行加密
*@paramtext
*@return
*String
*@throws
*/
publicStringencryText(Stringtext){
returnencryText(text,getPublicKey());
}
/**
*
*@Title:entryText
*@Description:使用指定公钥进行加密,解决长字符串加密
*@paramtext
*@parampublicKey2
*@return
*String
*@throws
*/
publicStringencryText(Stringtext,PublicKeypk){
try{
Ciphercipher=Cipher.getInstance("RSA",newBouncyCastleProvider());
cipher.init(Cipher.ENCRYPT_MODE,pk);
intblock=cipher.getBlockSize();//获取最大加密块
intj=0;
StringBuildersb=newStringBuilder();
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++;
}
returnsb.toString();
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
/**
*
*@Title:decryText
*@Description:使用默认的私钥进行解密解密算法
*@paramtext
*@return
*String
*@throws
*/
publicStringdecryText(Stringtext){
returndecryText(text,getPrivateKey());
}
/**
*
*@Title:decryText
*@Description:指定私钥进行解密,增加对于大字符串的解密操作
*@paramtext
*@paramprivateKey2
*@return
*String
*@throws
*/
publicStringdecryText(Stringtext,PrivateKeypk){
try{
Ciphercipher=Cipher.getInstance("RSA",newBouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE,pk);
byte[]targetBuff=Hex.decodeHex(text.replace("","").toCharArray());
intblock=cipher.getBlockSize();
intj=0;
StringBuildersb=newStringBuilder();
while(targetBuff.length-j*block>0){
byte[]jmdata=cipher.doFinal(targetBuff,j*block,block);
sb.append(newString(jmdata,"UTF-8"));
j++;
}
returnsb.toString();
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
/**
*
*@Title:decryTextByUrl
*@Description:解密前台传递的加密串,为防止中文乱码,前台字符串最好使用encodeURIComponent方法进行url编码
*@paramtext
*@return
*String
*@throws
*/
publicStringdecryTextByUrl(Stringtext){
try{
Ciphercipher=Cipher.getInstance("RSA",newBouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE,getPrivateKey());
byte[]targetBuff=Hex.decodeHex(text.replace("","").toCharArray());
intblock=cipher.getBlockSize();
intj=0;
StringBuildersb=newStringBuilder();
while(targetBuff.length-j*block>0){//处理大字符串的加密解密处理
byte[]jmdata=cipher.doFinal(targetBuff,j*block,block);
sb.append(newStringBuilder(newString(jmdata,"UTF-8")).reverse());
j++;
}
Stringres=URLDecoder.decode(sb.toString(),"UTF-8");
returnres;
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
/**
*
*@Title:createPubKey
*@Description:根据指定的幂和模式生成公钥
*@paramexponent
*@parammodules
*@return
*PublicKey
*@throws
*/
publicPublicKeycreatePubKey(byte[]exponent,byte[]modules){
try{
KeyFactorykeyFactory=KeyFactory.getInstance("RSA",newBouncyCastleProvider());
RSAPublicKeySpecrsaKs=newRSAPublicKeySpec(newBigInteger(modules),newBigInteger(exponent));
returnkeyFactory.generatePublic(rsaKs);
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
/**
*
*@Title:createPubKey
*@Description:根据指定的幂和模式生成公钥
*@paramexponent
*@parammodules
*@return
*PublicKey
*@throws
*/
publicPrivateKeycreatePriKey(byte[]exponent,byte[]modules){
try{
KeyFactorykeyFactory=KeyFactory.getInstance("RSA",newBouncyCastleProvider());
RSAPrivateKeySpecrsaKs=newRSAPrivateKeySpec(newBigInteger(modules),newBigInteger(exponent));
returnkeyFactory.generatePrivate(rsaKs);
}catch(Exceptione){
e.printStackTrace();
}
returnnull;
}
/**
*
*@Title:saveKeyToFile
*@Description:保存公钥和私钥到文件中
*void
*@throws
*/
publicvoidsaveKeyToFile(){
PublicKeypk=getPublicKey();
PrivateKeyprik=getPrivateKey();
Stringpath=RSAUtil.class.getClassLoader().getResource("").getPath();
ObjectOutputStreamoutPub=null;
ObjectOutputStreamoutPri=null;
try{
System.out.println(path+keyPubFile);
outPub=newObjectOutputStream(newFileOutputStream(path+keyPubFile));
outPri=newObjectOutputStream(newFileOutputStream(path+keyPriFile));
outPub.writeObject(pk);
outPri.writeObject(prik);
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
outPub.close();
outPri.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
/**
*
*@Title:readKey
*@Description:读取密钥
*@paramisPub
*@return
*Object
*@throws
*/
publicObjectreadKey(booleanisPub){
Stringpath=RSAUtil.class.getClassLoader().getResource("").getPath();
ObjectInputStreamin=null;
try{
if(isPub){
path+=keyPubFile;
in=newObjectInputStream(newFileInputStream(path));
PublicKeypk=(PublicKey)in.readObject();
returnpk;
}else{
path+=keyPriFile;
in=newObjectInputStream(newFileInputStream(path));
PrivateKeypk=(PrivateKey)in.readObject();
returnpk;
}
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
in.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
returnnull;
}
/**
*
*@Title:b2hex
*@Description:将二进制转为16进制字符串
*@parambuff
*@return
*String
*@throws
*/
publicStringb2hex(byte[]buff){
StringBuildersb=newStringBuilder();
for(inti=0;i
下载:http://xiazai.jb51.net/201808/yuanma/rsajar_jb51.rar
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。