一个场景:服务器会给一个公钥给客户端,客户端用该公钥加密数据传给服务器,这个过程中,服务器用的是openssl方式生成的公私钥,如果直接用android自带的工具类是无法用公钥加密的,即便后端把他们的java代码发给你,你也无法加密成功
怎么处理这个问题?
1,用NDK编译Openssl的rsa,网上有很多解决办法,随便搜都可以搜到
2,不用ndk,直接用一个第三方jar包
我这边是用的第二种方法处理,bouncycastle这个jar包,但是我在网上搜了一圈,而且在官网下载jar,导入后都有各种各样的问题,始终搞不定
,相信如果你遇到了也会抓狂,那么怎么解决?
单凡你能找到的jar包,我觉得你第一反应应该去maven repository看看是否有对应的引用
是的,找到了,那剩下的就很简单了,直接在Gradle中引入
implementation “org.bouncycastle:bcprov-jdk15on:1.65”
以下是RSA的工具类
import android.util.Log;
import org.bouncycastle.asn1.pkcs.RSAPublicKey;
import org.bouncycastle.util.encoders.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.Cipher;
public class RSAUtils {
public static final String RSA = "RSA";// 非对称加密密钥算法
public static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";//加密填充方式
public static final int DEFAULT_KEY_SIZE = 2048;//秘钥默认长度
public static final byte[] DEFAULT_SPLIT = "#PART#".getBytes(); // 当要加密的内容超过bufferSize,则采用partSplit进行分块加密
public static final int DEFAULT_BUFFERSIZE = (DEFAULT_KEY_SIZE / 8) - 11;// 当前秘钥支持加密的最大字节数
/**
* bituan rsa
* @param key
* @param data
* @return
* @throws Exception
*/
public static String decryptByPublicKey(String key, String data) throws Exception {
// 加密
byte[] pubbyte = Base64.decode(key.split("-----")[2]);
RSAPublicKey rsaPubKey = RSAPublicKey.getInstance(pubbyte);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(rsaPubKey.getModulus(), rsaPubKey.getPublicExponent());
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey generatedPublic = kf.generatePublic(keySpec);
//公钥加密
byte[] encryptBytes= new byte[0];
try {
encryptBytes = encryptByPublicKeyForSpilt(data.getBytes(),generatedPublic.getEncoded());
} catch (Exception e) {
e.printStackTrace();
}
String encryStr=Base64.toBase64String(encryptBytes);
Log.e("RSA","加密后的数据:"+encryStr);
return encryStr;
}
/**
* 用公钥对字符串进行加密
*
* @param data 原文
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {
// 得到公钥
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
KeyFactory kf = KeyFactory.getInstance(RSA);
PublicKey keyPublic = kf.generatePublic(keySpec);
// 加密数据
Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING);
cp.init(Cipher.ENCRYPT_MODE, keyPublic);