java使用RSA与AES加密解密
首先了解下,什么是堆成加密,什么是非对称加密?
对称加密:加密与解密的密钥是相同的,加解密速度很快,比如AES
非对称加密:加密与解密的秘钥是不同的,速度较慢,比如RSA
先看代码(先会用在研究)
相关依赖:
org.bouncycastle
bcprov-jdk15on
1.58
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("验签失败");