欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
  java使用RSA与AES加密解密
 
  首先了解下,什么是堆成加密,什么是非对称加密?
 
  对称加密:加密与解密的密钥是相同的,加解密速度很快,比如AES
 
  非对称加密:加密与解密的秘钥是不同的,速度较慢,比如RSA
 
  先看代码(先会用在研究)
 
  相关依赖:
 
  <dependency>
 
  <groupId>org.bouncycastle</groupId>
 
  <artifactId>bcprov-jdk15on</artifactId>
 
  <version>1.58</version>
 
  </dependency>
 
  1,RSA工具类:
 
  packagecn.wangtao.utils;
 
  importorg.bouncycastle.jce.provider.BouncyCastleProvider;
 
  importorg.slf4j.Logger;
 
  importorg.slf4j.LoggerFactory;
 
  importjavax.crypto.Cipher;
 
  importjava.io.ByteArrayOutputStream;
 
  importjava.io.FileOutputStream;
 
  importjava.io.IOException;
 
  importjava.io.ObjectOutputStream;
 
  importjava.security.*;
 
  importjava.security.interfaces.RSAPrivateKey;
 
  importjava.security.interfaces.RSAPublicKey;
 
  /**
 
  *@ClassNameRSAUtils
 
  *@Auth桃子
 
  *@Date2019-6-2515:15
 
  *@Version1.0
 
  *@Description
 
  **/
 
  publicclassRSAUtils{
 
  privatestaticfinalStringRSA="RSA";//加密方式
 
  privatestaticfinalLoggerlogger=LoggerFactory.getLogger(RSAUtils.class);
 
  //获取密钥
 
  publicstaticKeyPairgetKey()throwsException{
 
  try{
 
  KeyPairGeneratorkeyPairGenerator=KeyPairGenerator.getInstance(RSA,newBouncyCastleProvider());
 
  keyPairGenerator.initialize(2048);//初始化密钥长度
 
  KeyPairkeyPair=keyPairGenerator.generateKeyPair();//生成密钥对
 
  returnkeyPair;
 
  }catch(Exceptione){
 
  logger.error("获取RSA秘钥对异常",e);
 
  thrownewException("获取RSA秘钥对异常",e);
 
  }
 
  }
 
  //利用公钥进行加密
 
  publicstaticStringencryptStr(RSAPublicKeypublicKey,Stringstr)throwsException{
 
  try{
 
  Ciphercipher=Cipher.getInstance(RSA,newBouncyCastleProvider());
 
  cipher.init(Cipher.ENCRYPT_MODE,publicKey);
 
  //加密
 
  byte[]bytes=getBytes(str.getBytes(),cipher);
 
  //2进行转换成16进制
 
  Stringresult=CommonUtils.parseByte2HexStr(bytes);
 
  returnresult;
 
  }catch(Exceptione){
 
  logger.error("使用RSA公钥进行加密异常",e);
 
  thrownewException("使用RSA公钥进行加密异常",e);
 
  }
 
  }
 
  //利用私钥进行解密
 
  publicstaticStringdecryptStr(RSAPrivateKeyprivateKey,Stringstr)throwsException{
 
  try{
 
  Ciphercipher=Cipher.getInstance(RSA,newBouncyCastleProvider());
 
  cipher.init(Cipher.DECRYPT_MODE,privateKey);//用密钥初始化此Cipher对象
 
  //16进制转换成2进制
 
  byte[]bytes=CommonUtils.parseHexStr2Byte(str);
 
  //解密
 
  byte[]bs=getBytes(bytes,cipher);
 
  Stringcontent=newString(bs,"utf-8");
 
  returncontent;
 
  }catch(Exceptione){
 
  logger.error("使用RSA私钥进行解密异常",e);
 
  thrownewException("使用RSA私钥进行解密异常",e);
 
  }
 
  }
 
  //通过cipher获取字节数组
 
  publicstaticbyte[]getBytes(byte[]bytes,Ciphercipher)throwsException{
 
  intblockSize=cipher.getBlockSize();//返回块的大小
 
  intj=0;
 
  ByteArrayOutputStreambaos=newByteArrayOutputStream();
 
  while(bytes.length-j*blockSize>0){//将二进制数据分块写入ByteArrayOutputStream中
 
  if(bytes.length-j*blockSize>blockSize){
 
  baos.write(cipher.doFinal(bytes,j*blockSize,blockSize));
 
  }else{
 
  baos.write(cipher.doFinal(bytes,j*blockSize,bytes.length-j*blockSize));
 
  }
 
  j++;
 
  }
 
  baos.close();
 
  byte[]byteArray=baos.toByteArray();
 
  returnbyteArray;
 
  }
 
  //保存秘钥对到文件
 
  publicvoidsaveRSAKey(StringfileName)throwsException{
 
  FileOutputStreamfos=null;
 
  ObjectOutputStreamoos=null;
 
  try{
 
  KeyPairkeyPair=getKey();
 
  fos=newFileOutputStream(fileName);
 
  oos=newObjectOutputStream(fos);//对象序列号
 
  oos.writeObject(keyPair);
 
  }catch(Exceptione){
 
  logger.error("RSA秘钥对保存到文件异常[{}]",fileName,e);
 
  thrownewException("RSA秘钥对保存到文件异常",e);
 
  }finally{
 
  if(oos!=null){
 
  try{
 
  oos.close();
 
  }catch(IOExceptione1){
 
  e1.printStackTrace();
 
  }
 
  }
 
  if(fos!=null){
 
  try{
 
  fos.close();
 
  }catch(IOExceptione1){
 
  e1.printStackTrace();
 
  }
 
  }
 
  }
 
  }
 
  }
 
  /**
 
  *@ClassNameRSAUtils
 
  *@Version1.0
 
  *@DescriptionRSA工具类
 
  **/
 
  publicclassRSAUtils{
 
  
 
   privatestaticfinalStringRSA="RSA";
 
  publicstaticfinalStringMD5WITHRSA="MD5withRSA";
 
  publicstaticfinalStringSHA1WITHRSA="SHA1withRSA";
 
  privatestaticLoggerlogger=LoggerFactory.getLogger(RSAUtils.class);
 
  /**
 
  *@desc读取秘钥文本内容
 
  *@createTime2019年7月2日下午5:20:38
 
  *@paramkeyFile秘钥文件
 
  *@return秘钥文本内容
 
  *@throwsException
 
  */
 
  privatestaticStringinitKeyByFile(FilekeyFile)throwsException{
 
   if(keyFile.exists()&&keyFile.isFile()){
 
   BufferedReaderbufferedReader=null;
 
   try{
 
  bufferedReader=newBufferedReader(newFileReader(keyFile));
 
  StringBuilderstringBuilder=newStringBuilder();
 
  Stringline=null;
 
  while((line=bufferedReader.readLine())!=null){
 
  if(line.length()==0||line.charAt(0)=='-'){
 
  continue;
 
  }
 
  stringBuilder.append(line).append(System.getProperty("line.separator"));
 
  }
 
  returnstringBuilder.toString();
 
   }catch(Exceptione){
 
   logger.error("读取秘钥文本内容异常",e);
 
   thrownewException("读取秘钥文本内容异常",e);
 
   }finally{
 
   CommonUtils.closeReaderandWriter(bufferedReader,null);
 
   }
 
   }
 
   returnnull;
 
  }
 
  /**
 
  *@desc获取公钥
 
  *@authorLiuweian
 
  *@createTime2019年7月2日下午5:19:34
 
  *@parampubKeyFileName公钥文件地址
 
  *@returnPublicKey
 
  *@throwsException
 
  */
 
  publicstaticPublicKeygetPublicKeyByFile(FilepubKeyFile)throwsException{
 
   StringkeyContent=initKeyByFile(pubKeyFile);
 
  byte[]keyByte=Base64.decode(keyContent);
 
  KeyFactorykf=KeyFactory.getInstance(RSA);
 
  X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyByte);
 
  returnkf.generatePublic(keySpec);
 
  }
 
  /**
 
  *@desc获取私钥
 
  *@createTime2019年7月2日下午5:19:16
 
  *@parampriKeyFileName私钥文件地址
 
  *@returnPrivateKey
 
  *@throwsException
 
  */
 
  publicstaticPrivateKeygetPrivateKeyByFile(FilepriKeyFile)throwsException{
 
   StringkeyContent=initKeyByFile(priKeyFile);
 
  byte[]keyByte=Base64.decode(keyContent);
 
  KeyFactorykf=KeyFactory.getInstance(RSA);
 
  PKCS8EncodedKeySpeckeySpec=newPKCS8EncodedKeySpec(keyByte);
 
  returnkf.generatePrivate(keySpec);
 
  }
 
  /**
 
  *@desc使用RSA中的私钥对数据签名
 
  *@createTime2019年7月2日下午5:24:30
 
  *@paramprivateKey秘钥对中的私钥
 
  *@paramdata待加签字节数组
 
  *@paramsignType加签类型
 
  *@return加签后的签名
 
  *@throwsException
 
  */
 
  publicstaticStringsign(byte[]data,PrivateKeyprivateKey,StringsignType)throwsException{
 
   Signaturesignature=Signature.getInstance(signType);
 
   signature.initSign(privateKey);
 
   signature.update(data);
 
   byte[]signByte=signature.sign();
 
   //Base64加密
 
   returnnewString(Base64.encode(signByte));
 
  }
 
  /**
 
  *@desc使用RSA中的公钥对签名验签
 
  *@createTime2019年7月2日下午5:24:30
 
  *@paramdata待验签字节数组
 
  *@paramsign签名
 
  *@parampublicKey秘钥对中的公钥
 
  *@paramsignType加签类型
 
  *@return验签是否成功
 
  *@throwsException
 
  */
 
  publicstaticbooleanverify(byte[]data,byte[]sign,PublicKeypublicKey,StringsignType){
 
  try{
 
  Signaturesignature=Signature.getInstance(signType);
 
  signature.initVerify(publicKey);
 
  signature.update(data);
 
  //Base64解密
 
  byte[]keyByte=Base64.decode(sign);
 
  returnsignature.verify(keyByte);
 
  }catch(Exceptione){
 
  logger.error("验签出现异常",e);
 
  returnfalse;
 
  }
 
  }
 
  /**
 
  *@desc使用RSA中的私钥对数据签名加签方式MD5withRSA
 
  *@createTime2019年7月2日下午5:24:30
 
  *@paramprivateKey秘钥对中的私钥
 
  *@paramdata待加签字节数组
 
  *@return加签后的签名
 
  *@throwsException
 
  */
 
  publicstaticStringsignMD5withRSA(byte[]data,PrivateKeyprivateKey)throwsException{
 
   returnsign(data,privateKey,MD5WITHRSA);
 
  }
 
  /**
 
  *@desc使用RSA中的公钥对签名验签验签方式MD5withRSA
 
  *@createTime2019年7月2日下午5:24:30
 
  *@paramsign签名
 
  *@parampublicKey秘钥对中的公钥
 
  *@paramsignType加签类型
 
  *@return验签是否成功,失败则异常抛出
 
  *@throwsException
 
  */
 
  publicstaticvoidverifyMD5withRSA(byte[]data,byte[]sign,PublicKeypublicKey)throwsException{
 
   if(!verify(data,sign,publicKey,MD5WITHRSA)){
 
   thrownewException("验签失败");
 
   }
 
  }
 
  /**
 
  *@desc通过cipher获取字节数组分块
 
  *@createTime2019年7月2日下午5:21:33
 
  *@paramdata待加密的字节数组
 
  *@paramcipher
 
  *@return
 
  *@throwsException
 
  */
 
  publicstaticbyte[]getBytes(byte[]data,Ciphercipher)throwsException{
 
  intblockSize=cipher.getBlockSize();//返回块的大小
 
  intj=0;
 
  ByteArrayOutputStreambaos=newByteArrayOutputStream();
 
  while(data.length-j*blockSize>0){//将二进制数据分块写入ByteArrayOutputStream中
 
  if(data.length-j*blockSize>blockSize){
 
  baos.write(cipher.doFinal(data,j*blockSize,blockSize));
 
  }else{
 
  baos.write(cipher.doFinal(data,j*blockSize,data.length-j*blockSize));
 
  }
 
  j++;
 
  }
 
  baos.close();
 
  byte[]byteArray=baos.toByteArray();
 
  returnbyteArray;
 
  }
 
  /**
 
  *@desc利用公钥进行加密
 
  *@createTime2019年7月2日下午5:24:30
 
  *@paramkey密钥对的一个
 
  *@paramdata待加密字节数组
 
  *@return密文
 
  *@throwsException
 
  */
 
  publicstaticStringencrypt(Keykey,byte[]data)throwsException{
 
  try{
 
  Ciphercipher=Cipher.getInstance(RSA,newBouncyCastleProvider());
 
  cipher.init(Cipher.ENCRYPT_MODE,key);
 
  //加密
 
  byte[]bytes=getBytes(data,cipher);
 
  //2进行转换成16进制
 
  Stringresult=CommonUtils.parseByte2HexStr(bytes);
 
  returnnewString(Base64.encode(result.getBytes(CommonUtils.CODE_TYPE)));
 
  }catch(Exceptione){
 
  logger.error("使用RSA公钥进行加密异常",e);
 
  thrownewException("使用RSA公钥进行加密异常",e);
 
  }
 
  }
 
  /**
 
  *@desc利用私钥进行解密
 
  *@createTime2019年7月2日下午5:23:10
 
  *@paramkey密钥对的一个
 
  *@paramdata待解密的字节数组
 
  *@return明文
 
  *@throwsException
 
  */
 
  publicstaticStringdecrypt(Keykey,byte[]data)throwsException{
 
  try{
 
  Ciphercipher=Cipher.getInstance(RSA,newBouncyCastleProvider());
 
  cipher.init(Cipher.DECRYPT_MODE,key);//用密钥初始化此Cipher对象
 
  //16进制转换成2进制
 
  byte[]bytes=CommonUtils.parseHexStr2Byte(Base64.decode(data));
 
  //解密
 
  byte[]bs=getBytes(bytes,cipher);
 
  Stringcontent=newString(bs,CommonUtils.CODE_TYPE);
 
  returncontent;
 
  }catch(Exceptione){
 
  logger.error("使用RSA私钥进行解密异常",e);
 
  thrownewException("使用RSA私钥进行解密异常",e);
 
  }
 
  }
 
  }
 
  2,CommonUtils通用工具类:
 
  packagecn.wangtao.utils;
 
  importorg.slf4j.Logger;
 
  importorg.slf4j.LoggerFactory;
 
  importjava.io.IOException;
 
  importjava.io.Reader;
 
  importjava.io.Writer;
 
  /**
 
  *@ClassNameCommonUtils
 
  *@Auth桃子
 
  *@Date2019-6-2712:51
 
  *@Version1.0
 
  *@Description
 
  **/
 
  publicclassCommonUtils{
 
  privatestaticfinalLoggerlogger=LoggerFactory.getLogger(CommonUtils.class);
 
  //编码方式
 
  publicstaticfinalStringCODE_TYPE="UTF-8";
 
  //字符补全
 
  privatestaticfinalString[]consult=newString[]{"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G"};
 
  //关流
 
  publicstaticvoidcloseReaderandWriter(Readerreader,Writerwriter){
 
  if(writer!=null){
 
  try{
 
  writer.close();
 
  }catch(IOExceptione){
 
  logger.error("关闭输出流失败",e);
 
  }
 
  }
 
  if(reader!=null){
 
  try{
 
  reader.close();
 
  }catch(IOExceptione){
 
  logger.error("关闭输出流失败",e);
 
  }
 
  }
 
  }
 
  //将16进制转换为二进制
 
  publicstaticbyte[]parseHexStr2Byte(StringhexStr){
 
  if(hexStr.length()<1)
 
  returnnull;
 
  byte[]result=newbyte[hexStr.length()/2];
 
  for(inti=0;i<hexStr.length()/2;i++){
 
  inthigh=Integer.parseInt(hexStr.substring(i*2,i*2+1),16);
 
  intlow=Integer.parseInt(hexStr.substring(i*2+1,i*2+2),16);
 
  result[i]=(byte)(high*16+low);
 
  }
 
  returnresult;
 
  }
 
  //将二进制转换成16进制
 
  publicstaticStringparseByte2HexStr(bytebuf[]){
 
  StringBuffersb=newStringBuffer();
 
  for(inti=0;i<buf.length;i++){
 
  Stringhex=Integer.toHexString(buf[i]&0xFF);
 
  if(hex.length()==1){
 
  hex='0'+hex;
 
  }
 
  sb.append(hex.toUpperCase());
 
  }
 
  returnsb.toString();
 
  }
 
  //补全字符
 
  publicstaticStringcompletionCodeFor16Bytes(Stringstr)throwsException{
 
  try{
 
  intnum=str.getBytes(CODE_TYPE).length;
 
  intindex=num%16;
 
  //进行加密内容补全操作,加密内容应该为16字节的倍数,当不足16*n字节是进行补全,差一位时补全16+1位
 
  //补全字符以$开始,$后一位代表$后补全字符位数,之后全部以0进行补全;
 
  if(index!=0){
 
  StringBuffersbBuffer=newStringBuffer(str);
 
  if(16-index==1){
 
  sbBuffer.append("$"+consult[16-1]+addStr(16-1-1));
 
  }else{
 
  sbBuffer.append("$"+consult[16-index-1]+addStr(16-index-1-1));
 
  }
 
  str=sbBuffer.toString();
 
  }
 
  returnstr;
 
  }catch(Exceptione){
 
  logger.error("使用AES加密前补全字符异常",e);
 
  thrownewException("使用AES加密前补全字符异常",e);
 
  }
 
  }
 
  //追加字符
 
  publicstaticStringaddStr(intnum){
 
  StringBuffersbBuffer=newStringBuffer("");
 
  for(inti=0;i<num;i++){
 
  sbBuffer.append("0");
 
  }
 
  returnsbBuffer.toString();
 
  }
 
  //还原字符(进行字符判断)
 
  publicstaticStringresumeCodeOf16Bytes(Stringstr)throwsException{
 
  intindexOf=str.lastIndexOf("$");
 
  if(indexOf==-1){
 
  returnstr;
 
  }
 
  Stringtrim=str.substring(indexOf+1,indexOf+2).trim();
 
  intnum=0;
 
  for(inti=0;i<consult.length;i++){
 
  if(trim.equals(consult[i])){
 
  num=i;
 
  }
 
  }
 
  if(num==0){
 
  returnstr;
 
  }
 
  returnstr.substring(0,indexOf).trim();
 
  }
 
  }
 
  3,AESUtils通用工具类:
 
  packagecn.wangtao.utils;
 
  importorg.slf4j.Logger;
 
  importorg.slf4j.LoggerFactory;
 
  importjavax.crypto.Cipher;
 
  importjavax.crypto.spec.SecretKeySpec;
 
  importjava.io.*;
 
  importjava.security.interfaces.RSAPrivateKey;
 
  importjava.util.Map;
 
  /**
 
  *@ClassNameAESUtils
 
  *@Auth桃子
 
  *@Date2019-6-2712:05
 
  *@Version1.0
 
  *@Description
 
  **/
 
  publicclassAESUtils{
 
  privatestaticfinalLoggerlogger=LoggerFactory.getLogger(AESUtils.class);
 
  //填充类型
 
  publicstaticfinalStringAES_TYPE="AES/ECB/PKCS5Padding";
 
  privatestaticfinalStringAES="AES";//加密方式
 
  publicstaticfinalStringDES_TYPE="DES/ECB/PKCS5Padding";
 
  privatestaticfinalStringDES="DES";//加密方式
 
  privatefinalStringdefaultDesKey="11112222";//8位
 
  //对字符串加密
 
  publicstaticStringencryptStr(Stringcontent,StringaesKey)throwsException{
 
  try{
 
  SecretKeySpeckey=newSecretKeySpec(aesKey.getBytes(),AES);
 
  Ciphercipher=Cipher.getInstance(AES_TYPE);
 
  cipher.init(Cipher.ENCRYPT_MODE,key);
 
  //字符补全
 
  Stringcontent16Str=CommonUtils.completionCodeFor16Bytes(content);
 
  byte[]encryptedData=cipher.doFinal(content16Str.getBytes(CommonUtils.CODE_TYPE));
 
  //2进制转换成16进制
 
  StringhexStr=CommonUtils.parseByte2HexStr(encryptedData);
 
  returnhexStr;
 
  }catch(Exceptione){
 
  logger.error("使用AES对字符串加密异常",e);
 
  thrownewException("使用AES对字符串加密异常",e);
 
  }
 
  }
 
  //对字符串解密
 
  publicstaticStringdecryptStr(Stringcontent,StringaesKey)throwsException{
 
  try{
 
  //16进制转换成2进制
 
  byte[]bytes=CommonUtils.parseHexStr2Byte(content);
 
  SecretKeySpeckey=newSecretKeySpec(
 
  aesKey.getBytes(),AES);
 
  Ciphercipher=Cipher.getInstance(AES_TYPE);
 
  cipher.init(Cipher.DECRYPT_MODE,key);
 
  byte[]decryptedData=cipher.doFinal(bytes);
 
  Stringresult=newString(decryptedData,CommonUtils.CODE_TYPE);
 
  //还原字符
 
  StringorgResult=CommonUtils.resumeCodeOf16Bytes(result);
 
  returnorgResult;
 
  }catch(Exceptione){
 
  logger.error("使用AES对字符串解密异常",e);
 
  thrownewException("使用AES对字符串解密异常",e);
 
  }
 
  }
 
  //对文件加密
 
  publicstaticFileencryptFile(FileorgFile,FileencryptFile,Map<String,Object>context)throwsException{
 
  logger.info("使用AES对文件加密开始,源文件地址[{}]加密后文件地址[{}]",orgFile.getPath(),encryptFile.getPath());
 
  BufferedReaderbr=null;
 
  BufferedWriterbw=null;
 
  try{
 
  //获取AESKEY,如果没有为默认
 
  StringaesKey=(String)context.get(Dirt.AES_KEY);
 
  br=newBufferedReader(newFileReader(orgFile));
 
  bw=(BufferedWriter)context.get(Dirt.BUFFEREDWRITER);
 
  if(null==bw){
 
  bw=newBufferedWriter(newFileWriter(encryptFile));
 
  }
 
  Stringlen=null;
 
  while(null!=(len=br.readLine())){
 
  Stringencrypt=encryptStr(len,aesKey);
 
  bw.write(encrypt);
 
  bw.newLine();
 
  bw.flush();
 
  }
 
  logger.info("使用AES对文件加密结束,源文件地址[{}]加密后文件地址[{}]",orgFile.getPath(),encryptFile.getPath());
 
  returnencryptFile;
 
  }catch(Exceptione){
 
  logger.error("使用AES对文件加密异常,源文件地址[{}]加密后文件地址[{}]",orgFile.getPath(),encryptFile.getPath(),e);
 
  thrownewException("使用AES对文件加密异常",e);
 
  }finally{
 
  CommonUtils.closeReaderandWriter(br,bw);
 
  }
 
  }

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h56833.shtml