
因为Rsa加密的代码都是比较通用的,所以没有特意去整合,这里参照着两位大神的代码重新写了一遍,做了一些简单的修改,符合本地运行环境服务端代参照:客户端代码参照:JS加密依赖:地址:,只是Base64加......
因为Rsa加密的代码都是比较通用的,所以没有特意去整合,这里参照着两位大神的代码重新写了一遍,做了一些简单的修改,符合本地运行环境
服务端代参照:
客户端代码参照:
JS加密依赖:地址:,只是Base64加密的时候额外依赖了apache的工具类
服务端工RSA工具类
;;;;;*;;;;;;;/***RSA加密解密工具类*额外依赖,日志用的log4j,如果是其他的日志框架可以更改*@authorwzh*@version2018-12-1618:20*@see[相关类/方法](可选)**/publicclassRsaUtils{privatestaticLoggerlog=();/***块加密大小*/privatestaticfinalintCACHE_SIZE=1024;/***加密算法RSA*/publicstaticfinalStringKEY_ALGORITHM="RSA";/***签名算法*/publicstaticfinalStringSIGNATURE_ALGORITHM="MD5withRSA";/***获取公钥的key*/privatestaticfinalStringPUBLIC_KEY="RsaPublicKey";/***获取私钥的key*/privatestaticfinalStringPRIVATE_KEY="RsaPrivateKey";/***RSA最大加密明文大小*/privatestaticfinalintMAX_ENCRYPT_BLOCK=117;/***RSA最大解密密文大小*/privatestaticfinalintMAX_DECRYPT_BLOCK=128;/***Base64字符串解码为二进制数据*@parambase64*@return二进制数据*@throwsException*/publicstaticbyte[]decodeBase64(Stringbase64)throwsException{(());}/***二进制数据编码为Base64字符串*@parambytes*@returnBase64字符串*@throwsException*/publicstaticStringencodeBase64(byte[]bytes)throwsException{returnnewString((bytes));}/***生成秘钥对*@return返回公钥和私钥的Map集合*@throwsException*/publicstaticMapString,ObjectinitKeyPair()throwsException{KeyPairGeneratorkeyPairGen=(KEY_ALGORITHM);(CACHE_SIZE);KeyPairkeyPair=();RSAPublicKeypublicKey=(RSAPublicKey)();RSAPrivateKeyprivateKey=(RSAPrivateKey)();MapString,ObjectkeyMap=newHashMapString,Object(2);//公钥(PUBLIC_KEY,publicKey);//私钥(PRIVATE_KEY,privateKey);returnkeyMap;}/***获取私钥*@paramkeyMap秘钥对Map*@return私钥字符串*@throwsException*/publicstaticStringgetPrivateKey(MapString,ObjectkeyMap)throwsException{Keykey=(Key)(PRIVATE_KEY);returnencodeBase64(());}/***获取公钥字符串*@paramkeyMap秘钥对Map*@return公钥字符串*@throwsException*/publicstaticStringgetPublicKey(MapString,ObjectkeyMap)throwsException{Keykey=(Key)(PUBLIC_KEY);returnencodeBase64(());}/***使用私钥生成数字签名*@paramdata使用私钥加密的数据*@paramprivateKey是哟啊字符串*@return数字签名*@throwsException*/publicstaticStringsign(byte[]data,StringprivateKey)throwsException{//获取byte数组byte[]keyBytes=decodeBase64(privateKey);//构造PKCS8EncodedKeySpec对象PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);//指定的加密算法KeyFactorykeyFactory=(KEY_ALGORITHM);//取私钥匙对象PrivateKeyprivateK=(pkcs8KeySpec);//用私钥对信息生成数字签名Signaturesignature=(SIGNATURE_ALGORITHM);(privateK);(data);returnencodeBase64(());}/***校验数字签名*@paramdata私钥加密的数据*@parampublicKey公钥字符串*@paramsign私钥生成的签名*@return校验成功返回true失败返回false*@throwsException*/publicstaticbooleanverify(byte[]data,StringpublicKey,Stringsign)throwsException{//获取byte数组byte[]keyBytes=decodeBase64(publicKey);X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes);//构造X509EncodedKeySpec对象KeyFactorykeyFactory=(KEY_ALGORITHM);//指定的加密算法Signaturesignature=(SIGNATURE_ALGORITHM);//取公钥匙对象PublicKeypublicK=(keySpec);(publicK);(data);//验证签名是否正常(decodeBase64(sign));}/***私钥加密*@paramdata需要加密的数据*@paramprivateKey私钥*@return加密后的数据*@throwsException*/publicstaticbyte[]encryptByPrivateKey(byte[]data,StringprivateKey)throwsException{byte[]keyBytes=decodeBase64(privateKey);PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);KeyFactorykeyFactory=(KEY_ALGORITHM);KeyprivateK=(pkcs8KeySpec);Ciphercipher=(());(_MODE,privateK);intinputLen=;ByteArrayOutputStreamout=newByteArrayOutputStream();intoffSet=0;byte[]cache;inti=0;//对数据分段加密while(inputLen-offSet0){if(inputLen-offSetMAX_ENCRYPT_BLOCK){cache=(data,offSet,MAX_ENCRYPT_BLOCK);}else{cache=(data,offSet,inputLen-offSet);}(cache,0,);i++;offSet=i*MAX_ENCRYPT_BLOCK;}byte[]encryptedData=();();returnencryptedData;}/***公钥加密*@paramdata需要加密的数据*@parampublicKey公钥字符串*@return加密后的数据*@throwsException*/publicstaticbyte[]encryptByPublicKey(byte[]data,StringpublicKey)throwsException{byte[]keyBytes=decodeBase64(publicKey);X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);KeyFactorykeyFactory=(KEY_ALGORITHM);KeypublicK=(x509KeySpec);//对数据加密Ciphercipher=(());(_MODE,publicK);intinputLen=;ByteArrayOutputStreamout=newByteArrayOutputStream();intoffSet=0;byte[]cache;inti=0;//对数据分段加密while(inputLen-offSet0){if(inputLen-offSetMAX_ENCRYPT_BLOCK){cache=(data,offSet,MAX_ENCRYPT_BLOCK);}else{cache=(data,offSet,inputLen-offSet);}(cache,0,);i++;offSet=i*MAX_ENCRYPT_BLOCK;}byte[]encryptedData=();();returnencryptedData;}/***私钥解密*@paramencryptedData公钥加密的数据*@paramprivateKey私钥字符串*@return私钥解密的数据*@throwsException*/publicstaticbyte[]decryptByPrivateKey(byte[]encryptedData,StringprivateKey)throwsException{byte[]keyBytes=decodeBase64(privateKey);PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes);KeyFactorykeyFactory=(KEY_ALGORITHM);KeyprivateK=(pkcs8KeySpec);Ciphercipher=(());(_MODE,privateK);intinputLen=;ByteArrayOutputStreamout=newByteArrayOutputStream();intoffSet=0;byte[]cache;inti=0;//对数据分段解密while(inputLen-offSet0){if(inputLen-offSetMAX_DECRYPT_BLOCK){cache=(encryptedData,offSet,MAX_DECRYPT_BLOCK);}else{cache=(encryptedData,offSet,inputLen-offSet);}(cache,0,);i++;offSet=i*MAX_DECRYPT_BLOCK;}byte[]decryptedData=();();returndecryptedData;}/***公钥解密*@paramencryptedData私钥加密的数据*@parampublicKey公钥字符串*@return公钥解密的数据*@throwsException*/publicstaticbyte[]decryptByPublicKey(byte[]encryptedData,StringpublicKey)throwsException{byte[]keyBytes=decodeBase64(publicKey);X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);KeyFactorykeyFactory=(KEY_ALGORITHM);KeypublicK=(x509KeySpec);Ciphercipher=(());(_MODE,publicK);intinputLen=;ByteArrayOutputStreamout=newByteArrayOutputStream();intoffSet=0;byte[]cache;inti=0;//对数据分段解密while(inputLen-offSet0){if(inputLen-offSetMAX_DECRYPT_BLOCK){cache=(encryptedData,offSet,MAX_DECRYPT_BLOCK);}else{cache=(encryptedData,offSet,inputLen-offSet);}(cache,0,);i++;offSet=i*MAX_DECRYPT_BLOCK;}byte[]decryptedData=();();returndecryptedData;}/***公钥加密方法*@paramdata需加密的字符串*@paramPUBLICKEY公钥字符串*@return加密后的字符串*/publicstaticStringencryptedDataByPublic(Stringdata,StringPUBLICKEY){try{data=encodeBase64(encryptByPublicKey((),PUBLICKEY));}catch(Exceptione){();((),e);}returndata;}/***私钥解密方法*@paramdata公钥加密的字符串*@paramPRIVATEKEY私钥字符串*@return私钥解密的字符串*/publicstaticStringdecryptDataByPrivate(Stringdata,StringPRIVATEKEY){Stringtemp="";try{byte[]rs=decodeBase64(data);//以utf-8的方式生成字符串temp=newString(decryptByPrivateKey(rs,PRIVATEKEY),"UTF-8");}catch(Exceptione){();}returntemp;}publicstaticvoidmain(String[]args){try{MapString,ObjectkeyMap=();StringpublicKey=(keyMap);StringprivateKey=(keyMap);("公钥:"+publicKey);("私钥:"+privateKey);Stringsource="我是需要私钥加密的字符串!";("签名验证逻辑,私钥加密--公钥解密,需要加密的字符串:"+source);byte[]data=();byte[]encodedData=(data,privateKey);("私钥加密后:"+newString(encodedData));Stringsign=(encodedData,privateKey);("签名:"+sign);booleanstatus=(encodedData,publicKey,sign);("验证结果:"+status);byte[]decodedData=(encodedData,publicKey);Stringtarget=newString(decodedData);("公钥解密私钥加密的数据:"+target);("---------公钥加密----私钥解密----------");//这里尽量长一点,复制了一段歌词Stringmsg="月溅星河,长路漫漫,风烟残尽,独影阑珊;谁叫我身手不凡,谁让我爱恨两难,到后来,"+"肝肠寸断。幻世当空,恩怨休怀,舍悟离迷,六尘不改;且怒且悲且狂哉,是人是鬼是妖怪,不过是,"+"心有魔债。叫一声佛祖,回头无岸,跪一人为师,生死无关;善恶浮世真假界,尘缘散聚不分明,难断!"+"我要这铁棒有何用,我有这变化又如何;还是不安,还是氐惆,金箍当头,欲说还休。我要这铁棒醉舞魔,"+"我有这变化乱迷浊;踏碎灵霄,放肆桀骜,世恶道险,终究难逃。";StringecodeMsg=(msg,publicKey);("加密后的歌词:"+ecodeMsg);StringdecodeMsg=(ecodeMsg,privateKey);("解密后的歌词:"+decodeMsg);}catch(Exceptione){();}}}首先测试一下工具类,main函数跑一下,成功验证签名,加密,解密

客户端JS代码,需要JSEncrypt库,前文有给出github地址,这里对这个库做一个简单的扩展,因为RSA长文本超过秘钥长度要报错,所以需要扩展修改下
/***---------------------------*此JS需加载JSEncrypt库的后面,加密解密调用着两个方法*---------------------------*//***长文本加密*@param{string}string待加密长文本*@returns{string}加密后的base64编码**/=function(string){vark=();try{varct="";//RSA每次加密117bytes,需要辅助方法判断字符串截取位置//1.获取字符串截取点varbytes=newArray();(0);varbyteNo=0;varlen,c;len=;vartemp=0;for(vari=0;ilen;i++){c=(i);if(c=0x010000c=0x10FFFF){//特殊字符,如Ř,ŢbyteNo+=4;}elseif(c=0x000800c=0x00FFFF){//中文以及标点符号byteNo+=3;}elseif(c=0x000080c=0x0007FF){//特殊字符,如È,ÒbyteNo+=2;}else{//英文以及标点符号byteNo+=1;}if((byteNo%117)=114||(byteNo%117)==0){if(byteNo-temp=114){(i);temp=byteNo;}}}//2.截取字符串并分段加密if(){for(vari=0;;i++){varstr;if(i==0){str=(0,bytes[i+1]+1);}else{str=(bytes[i]+1,bytes[i+1]+1);}vart1=(str);ct+=t1;};if(bytes[]!=){varlastStr=(bytes[]+1);ct+=(lastStr);}returnhex2b64(ct);}vart=(string);vary=hex2b64(t);returny;}catch(ex){(ex);returnfalse;}};/***长文本解密*@param{string}string加密后的base64编码*@returns{string}解密后的原文**/=function(string){vark=();varmaxLength=128;try{varstring=b64tohex(string);varct="";if(*2){varlt=(/.{1,256}/g);//128位解密。取256位(function(entry){vart1=(entry);ct+=t1;});returnct;}vary=(string);returny;}catch(ex){returnfalse;}};functionhex2b64(h){varb64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";varb64padchar="=";vari;varc;varret="";for(i=0;i+3=;i+=3){c=parseInt((i,i+3),16);ret+=(c6)+(c63);}if(i+1==){c=parseInt((i,i+1),16);ret+=(c2);}elseif(i+2==){c=parseInt((i,i+2),16);ret+=(c2)+((c3)4);}while(()0)ret+=b64padchar;returnret;}一个简单的测试页面,就不做前后台衔接了,只是在前提用后台生成的公钥进行加密,然后后台main方法解密一下。
!/titlemetaname="keywords"content="keyword1,keyword2,keyword3"metaname="description"content="thisismypage"metaname="content-type"content="text/html;charset=UTF-8"scriptsrc="${}/js/"/scriptscriptsrc="${}/js/?v=123"/scriptscriptsrc="${}/js/?v=321123"/scriptscripttype="text/javascript"$(function(){$('msg').val();//公钥varpublickey=$('ecodeMsg').val(ecodeMsg);});});/script/headbody需要加密的内容:/brtextareaid="msg"name="msg"rows="10"cols="60"/textarea/br公钥:/brtextareaid="publickey"rows="10"cols="60"/textarea/br密文:/brtextareaid="ecodeMsg"rows="10"cols="60"/textareabr/br/inputid="submit"type="button"value="加密"//body/body/html简单的测试,页面获取密文

后台main解密一下
;/***一句话功能描述*功能详细描述*@authorwzh*@version2018-12-1623:31*@see[相关类/方法](可选)**/publicclassRsaManTest{publicstaticvoidmain(String[]args){Stringmsg=("XsM6CYaNhdx2pJXebCgl3g3pF7FX9KrPY+gtwgbQs0Q1mqJL4VHqQytxOJfUwXHLP/hLck80AWSctJ29/dB4IQ2mSbcO4OInAJMkPwqWsnh1E9bFlFP2KjQ5RBVngb//IiSgBSFo8NR00y1/h47CrNch6ljW1nCLG82Qk2olhfI=","MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIlXVcewyLHiE9aidGpcR7hMT5opgXTGUfWX2idJnr2b++Edzg8Id6FOFgmzAWBkoSfAZodkTgZcOUjc/F/ZDQbuSDSBiakVb6T+WK53oVKb8a9Y9Ouq63Bwqihq9kqp9+aLSRcRqyLkF/tGg87dGMEMGeHq2djOI8rrbXGlyQNhAgMBAAECgYAHMCD3MJNwa+qp4xrArk+6n5PS97UkzXRgrC/ounuqZM2L/KlaNBE+yf1xSIMb7mhY0kMLdv52asE8xQQYaB28WVJHxExgcMDDdhtOp+4++WEe2xPWrJSUWSvLQWxrJ01yw9smezt1N0qrA4psJ+eq3JP366wZ3GLFhq0BOW8wGQJBANZyo2Dm1aP4aBHfLSa51YQJ+izFJyC53Hn43CPhXNDT08GO6tuZ9KiIJkk7rNdDrkAFnR4cDwEZT0C6Fk/VWA8CQQCj8+/fGGV+z3D0VCFkPf+VlZdNuITFD+wzlaalJZq5mYtzdHAZ3AGxpNs+Qbykq4TSb5XhfQoZuBeMD3brCv2PAkEA1Wuby4mP3zMOJ5MrtVnG9DSVxU6kxT4T/VO9ivvzSmU2XnDkrY7H3Z46NDHurwHNfivYFSopiJdut2U7ZVJW4wJAc/FsLq7IB9eXH5HnU0Zs2lHBgBr++YT7Gre3844WTy6AaZNsOz1UjVXyHaLLTwBkm5SBv8Z3QBzpugitpiZNjQJAR9SqcarmoE7xNxOJ0gqj2Pht26rAfcQogpoVvbvJTgGlpvEnnV2wEX47mzLFewzQ2nxjwAJPdzr+rOKXKnDCFA==");(msg);}}前台加密,后台解密成功
