Java RSA加密解密实现方法分析【附BASE64 jar包下载】
本文实例讲述了JavaRSA加密解密实现方法。分享给大家供大家参考,具体如下:
该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1.jar
javabase64-1.3.1.jar本站下载地址。
注意:
RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块进行。
RSA加密对明文的长度是有限制的,如果加密数据过大会抛出如下异常:
Exceptioninthread"main"javax.crypto.IllegalBlockSizeException:Datamustnotbelongerthan117bytes atcom.sun.crypto.provider.RSACipher.a(DashoA13*..) atcom.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..) atjavax.crypto.Cipher.doFinal(DashoA13*..)
RSAUtils.java
packagesecurity; importjava.io.ByteArrayOutputStream; importjava.security.Key; importjava.security.KeyFactory; importjava.security.KeyPair; importjava.security.KeyPairGenerator; importjava.security.PrivateKey; importjava.security.PublicKey; importjava.security.Signature; importjava.security.interfaces.RSAPrivateKey; importjava.security.interfaces.RSAPublicKey; importjava.security.spec.PKCS8EncodedKeySpec; importjava.security.spec.X509EncodedKeySpec; importjava.util.HashMap; importjava.util.Map; importjavax.crypto.Cipher; /***//** **RSA公钥/私钥/签名工具包 *
**罗纳德·李维斯特(Ron[R]ivest)、阿迪·萨莫尔(Adi[S]hamir)和伦纳德·阿德曼(Leonard[A]dleman) *
**字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式
* *@authorIceWee *@date2012-4-26 *@version1.0 */ publicclassRSAUtils{ /***//** *加密算法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; /***//** *
*由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,
*非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 **生成密钥对(公钥和私钥) *
* *@return *@throwsException */ publicstaticMapgenKeyPair()throwsException{ KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPairkeyPair=keyPairGen.generateKeyPair(); RSAPublicKeypublicKey=(RSAPublicKey)keyPair.getPublic(); RSAPrivateKeyprivateKey=(RSAPrivateKey)keyPair.getPrivate(); Map keyMap=newHashMap (2); keyMap.put(PUBLIC_KEY,publicKey); keyMap.put(PRIVATE_KEY,privateKey); returnkeyMap; } /***//** * *用私钥对信息生成数字签名 *
* *@paramdata已加密数据 *@paramprivateKey私钥(BASE64编码) * *@return *@throwsException */ publicstaticStringsign(byte[]data,StringprivateKey)throwsException{ byte[]keyBytes=Base64Utils.decode(privateKey); PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); PrivateKeyprivateK=keyFactory.generatePrivate(pkcs8KeySpec); Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); returnBase64Utils.encode(signature.sign()); } /***//** **校验数字签名 *
* *@paramdata已加密数据 *@parampublicKey公钥(BASE64编码) *@paramsign数字签名 * *@return *@throwsException * */ publicstaticbooleanverify(byte[]data,StringpublicKey,Stringsign) throwsException{ byte[]keyBytes=Base64Utils.decode(publicKey); X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); PublicKeypublicK=keyFactory.generatePublic(keySpec); Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(publicK); signature.update(data); returnsignature.verify(Base64Utils.decode(sign)); } /***//** **私钥解密 *
* *@paramencryptedData已加密数据 *@paramprivateKey私钥(BASE64编码) *@return *@throwsException */ publicstaticbyte[]decryptByPrivateKey(byte[]encryptedData,StringprivateKey) throwsException{ byte[]keyBytes=Base64Utils.decode(privateKey); PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); KeyprivateK=keyFactory.generatePrivate(pkcs8KeySpec); Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE,privateK); intinputLen=encryptedData.length; ByteArrayOutputStreamout=newByteArrayOutputStream(); intoffSet=0; byte[]cache; inti=0; //对数据分段解密 while(inputLen-offSet>0){ if(inputLen-offSet>MAX_DECRYPT_BLOCK){ cache=cipher.doFinal(encryptedData,offSet,MAX_DECRYPT_BLOCK); }else{ cache=cipher.doFinal(encryptedData,offSet,inputLen-offSet); } out.write(cache,0,cache.length); i++; offSet=i*MAX_DECRYPT_BLOCK; } byte[]decryptedData=out.toByteArray(); out.close(); returndecryptedData; } /***//** **公钥解密 *
* *@paramencryptedData已加密数据 *@parampublicKey公钥(BASE64编码) *@return *@throwsException */ publicstaticbyte[]decryptByPublicKey(byte[]encryptedData,StringpublicKey) throwsException{ byte[]keyBytes=Base64Utils.decode(publicKey); X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); KeypublicK=keyFactory.generatePublic(x509KeySpec); Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE,publicK); intinputLen=encryptedData.length; ByteArrayOutputStreamout=newByteArrayOutputStream(); intoffSet=0; byte[]cache; inti=0; //对数据分段解密 while(inputLen-offSet>0){ if(inputLen-offSet>MAX_DECRYPT_BLOCK){ cache=cipher.doFinal(encryptedData,offSet,MAX_DECRYPT_BLOCK); }else{ cache=cipher.doFinal(encryptedData,offSet,inputLen-offSet); } out.write(cache,0,cache.length); i++; offSet=i*MAX_DECRYPT_BLOCK; } byte[]decryptedData=out.toByteArray(); out.close(); returndecryptedData; } /***//** **公钥加密 *
* *@paramdata源数据 *@parampublicKey公钥(BASE64编码) *@return *@throwsException */ publicstaticbyte[]encryptByPublicKey(byte[]data,StringpublicKey) throwsException{ byte[]keyBytes=Base64Utils.decode(publicKey); X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); KeypublicK=keyFactory.generatePublic(x509KeySpec); //对数据加密 Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE,publicK); intinputLen=data.length; ByteArrayOutputStreamout=newByteArrayOutputStream(); intoffSet=0; byte[]cache; inti=0; //对数据分段加密 while(inputLen-offSet>0){ if(inputLen-offSet>MAX_ENCRYPT_BLOCK){ cache=cipher.doFinal(data,offSet,MAX_ENCRYPT_BLOCK); }else{ cache=cipher.doFinal(data,offSet,inputLen-offSet); } out.write(cache,0,cache.length); i++; offSet=i*MAX_ENCRYPT_BLOCK; } byte[]encryptedData=out.toByteArray(); out.close(); returnencryptedData; } /***//** **私钥加密 *
* *@paramdata源数据 *@paramprivateKey私钥(BASE64编码) *@return *@throwsException */ publicstaticbyte[]encryptByPrivateKey(byte[]data,StringprivateKey) throwsException{ byte[]keyBytes=Base64Utils.decode(privateKey); PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); KeyprivateK=keyFactory.generatePrivate(pkcs8KeySpec); Ciphercipher=Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE,privateK); intinputLen=data.length; ByteArrayOutputStreamout=newByteArrayOutputStream(); intoffSet=0; byte[]cache; inti=0; //对数据分段加密 while(inputLen-offSet>0){ if(inputLen-offSet>MAX_ENCRYPT_BLOCK){ cache=cipher.doFinal(data,offSet,MAX_ENCRYPT_BLOCK); }else{ cache=cipher.doFinal(data,offSet,inputLen-offSet); } out.write(cache,0,cache.length); i++; offSet=i*MAX_ENCRYPT_BLOCK; } byte[]encryptedData=out.toByteArray(); out.close(); returnencryptedData; } /***//** **获取私钥 *
* *@paramkeyMap密钥对 *@return *@throwsException */ publicstaticStringgetPrivateKey(MapkeyMap) throwsException{ Keykey=(Key)keyMap.get(PRIVATE_KEY); returnBase64Utils.encode(key.getEncoded()); } /***//** * *获取公钥 *
* *@paramkeyMap密钥对 *@return *@throwsException */ publicstaticStringgetPublicKey(MapkeyMap) throwsException{ Keykey=(Key)keyMap.get(PUBLIC_KEY); returnBase64Utils.encode(key.getEncoded()); } }
Base64Utils.java
packagesecurity; importjava.io.ByteArrayInputStream; importjava.io.ByteArrayOutputStream; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; importjava.io.InputStream; importjava.io.OutputStream; importit.sauronsoftware.base64.Base64; /***//** **BASE64编码解码工具包 *
**依赖javabase64-1.3.1.jar *
* *@authorIceWee *@date2012-5-19 *@version1.0 */ publicclassBase64Utils{ /***//** *文件读取缓冲区大小 */ privatestaticfinalintCACHE_SIZE=1024; /***//** **BASE64字符串解码为二进制数据 *
* *@parambase64 *@return *@throwsException */ publicstaticbyte[]decode(Stringbase64)throwsException{ returnBase64.decode(base64.getBytes()); } /***//** **二进制数据编码为BASE64字符串 *
* *@parambytes *@return *@throwsException */ publicstaticStringencode(byte[]bytes)throwsException{ returnnewString(Base64.encode(bytes)); } /***//** **将文件编码为BASE64字符串 *
**大文件慎用,可能会导致内存溢出 *
* *@paramfilePath文件绝对路径 *@return *@throwsException */ publicstaticStringencodeFile(StringfilePath)throwsException{ byte[]bytes=fileToByte(filePath); returnencode(bytes); } /***//** **BASE64字符串转回文件 *
* *@paramfilePath文件绝对路径 *@parambase64编码字符串 *@throwsException */ publicstaticvoiddecodeToFile(StringfilePath,Stringbase64)throwsException{ byte[]bytes=decode(base64); byteArrayToFile(bytes,filePath); } /***//** **文件转换为二进制数组 *
* *@paramfilePath文件路径 *@return *@throwsException */ publicstaticbyte[]fileToByte(StringfilePath)throwsException{ byte[]data=newbyte[0]; Filefile=newFile(filePath); if(file.exists()){ FileInputStreamin=newFileInputStream(file); ByteArrayOutputStreamout=newByteArrayOutputStream(2048); byte[]cache=newbyte[CACHE_SIZE]; intnRead=0; while((nRead=in.read(cache))!=-1){ out.write(cache,0,nRead); out.flush(); } out.close(); in.close(); data=out.toByteArray(); } returndata; } /***//** **二进制数据写文件 *
* *@parambytes二进制数据 *@paramfilePath文件生成目录 */ publicstaticvoidbyteArrayToFile(byte[]bytes,StringfilePath)throwsException{ InputStreamin=newByteArrayInputStream(bytes); FiledestFile=newFile(filePath); if(!destFile.getParentFile().exists()){ destFile.getParentFile().mkdirs(); } destFile.createNewFile(); OutputStreamout=newFileOutputStream(destFile); byte[]cache=newbyte[CACHE_SIZE]; intnRead=0; while((nRead=in.read(cache))!=-1){ out.write(cache,0,nRead); out.flush(); } out.close(); in.close(); } }
RSATester.java
packagesecurity; importjava.util.Map; publicclassRSATester{ staticStringpublicKey; staticStringprivateKey; static{ try{ MapkeyMap=RSAUtils.genKeyPair(); publicKey=RSAUtils.getPublicKey(keyMap); privateKey=RSAUtils.getPrivateKey(keyMap); System.err.println("公钥:\n\r"+publicKey); System.err.println("私钥:\n\r"+privateKey); }catch(Exceptione){ e.printStackTrace(); } } publicstaticvoidmain(String[]args)throwsException{ test(); testSign(); } staticvoidtest()throwsException{ System.err.println("公钥加密——私钥解密"); Stringsource="这是一行没有任何意义的文字,你看完了等于没看,不是吗?"; System.out.println("\r加密前文字:\r\n"+source); byte[]data=source.getBytes(); byte[]encodedData=RSAUtils.encryptByPublicKey(data,publicKey); System.out.println("加密后文字:\r\n"+newString(encodedData)); byte[]decodedData=RSAUtils.decryptByPrivateKey(encodedData,privateKey); Stringtarget=newString(decodedData); System.out.println("解密后文字:\r\n"+target); } staticvoidtestSign()throwsException{ System.err.println("私钥加密——公钥解密"); Stringsource="这是一行测试RSA数字签名的无意义文字"; System.out.println("原文字:\r\n"+source); byte[]data=source.getBytes(); byte[]encodedData=RSAUtils.encryptByPrivateKey(data,privateKey); System.out.println("加密后:\r\n"+newString(encodedData)); byte[]decodedData=RSAUtils.decryptByPublicKey(encodedData,publicKey); Stringtarget=newString(decodedData); System.out.println("解密后:\r\n"+target); System.err.println("私钥签名——公钥验证签名"); Stringsign=RSAUtils.sign(encodedData,privateKey); System.err.println("签名:\r"+sign); booleanstatus=RSAUtils.verify(encodedData,publicKey,sign); System.err.println("验证结果:\r"+status); } }
PS:关于加密解密感兴趣的朋友还可以参考本站在线工具:
文字在线加密解密工具(包含AES、DES、RC4等):
http://tools.jb51.net/password/txt_encode
MD5在线加密工具:
http://tools.jb51.net/password/CreateMD5Password
在线散列/哈希算法加密工具:
http://tools.jb51.net/password/hash_encrypt
在线MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:
http://tools.jb51.net/password/hash_md5_sha
在线sha1/sha224/sha256/sha384/sha512加密工具:
http://tools.jb51.net/password/sha_encode
更多关于java相关内容感兴趣的读者可查看本站专题:《Java数学运算技巧总结》、《Java数据结构与算法教程》、《Java字符与字符串操作技巧总结》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。