Android 客户端RSA加密的实现方法
Android客户端RSA加密的实现方法
针对java后端进行的RSA加密,android客户端进行解密,结果是部分乱码的问题:
注意两点,编码问题和客户端使用的算法问题
即:都使用UTF-8编码,Base64使用一致,另外,使用下面的代码在后端和移动端解密只有一点不同:
移动端使用
Ciphercipher=Cipher.getInstance("RSA/ECB/PKCS1Padding");
后端使用
Ciphercipher=Cipher.getInstance("RSA");
其他地方都不需要改动
packagersa; importandroid.util.Base64; importjava.io.ByteArrayInputStream; importjava.io.ByteArrayOutputStream; importjava.io.File; importjava.io.FileInputStream; importjava.io.FileOutputStream; importjava.io.InputStream; importjava.io.OutputStream; //importorg.apache.commons.codec.binary.Base64; /***//** **BASE64编码解码工具包 *
*@authorIceWee *@date2012-5-19 *@version1.0 */ publicclassBase64Utils{ /***//** *文件读取缓冲区大小 */ privatestaticfinalintCACHE_SIZE=1024; /***//** **BASE64字符串解码为二进制数据 *
* *@parambase64 *@return *@throwsException */ publicstaticbyte[]decode(Stringbase64)throwsException{ returnBase64.decode(base64.getBytes(),Base64.DEFAULT); } /***//** **二进制数据编码为BASE64字符串 *
* *@parambytes *@return *@throwsException */ publicstaticStringencode(byte[]bytes)throwsException{ returnnewString(Base64.encode(bytes,Base64.DEFAULT)); } /** * *@paramstr *@return *@throwsException */ publicstaticStringencode(Stringstr)throwsException{ byte[]bytes=str.getBytes("utf-8"); returnencode(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(); } }
packagersa; importandroid.util.Base64; 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=Base64.decode(privateKey,0); PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); PrivateKeyprivateK=keyFactory.generatePrivate(pkcs8KeySpec); Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(privateK); signature.update(data); returnBase64.encodeToString(signature.sign(),0); } /** **校验数字签名 *
* *@paramdata已加密数据 *@parampublicKey公钥(BASE64编码) *@paramsign数字签名 * *@return *@throwsException * */ publicstaticbooleanverify(byte[]data,StringpublicKey,Stringsign) throwsException{ byte[]keyBytes=Base64.decode(publicKey,0); 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(Base64.decode(sign,0)); } /** **私钥解密 *
* *@paramencryptedData已加密数据 *@paramprivateKey私钥(BASE64编码) *@return *@throwsException */ publicstaticbyte[]decryptByPrivateKey(byte[]encryptedData,StringprivateKey) throwsException{ byte[]keyBytes=Base64.decode(privateKey,0); PKCS8EncodedKeySpecpkcs8KeySpec=newPKCS8EncodedKeySpec(keyBytes); KeyFactorykeyFactory=KeyFactory.getInstance(KEY_ALGORITHM); KeyprivateK=keyFactory.generatePrivate(pkcs8KeySpec); Ciphercipher=Cipher.getInstance("RSA/ECB/PKCS1Padding"); 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=Base64.decode(publicKey,0); 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=Base64.decode(publicKey,0); 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=Base64.decode(privateKey,0); 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); returnBase64.encodeToString(key.getEncoded(),0); } /** * *获取公钥 *
* *@paramkeyMap密钥对 *@return *@throwsException */ publicstaticStringgetPublicKey(MapkeyMap) throwsException{ Keykey=(Key)keyMap.get(PUBLIC_KEY); returnBase64.encodeToString(key.getEncoded(),0); } }
如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!