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