一个场景:服务器会给一个公钥给客户端,客户端用该公钥加密数据传给服务器,这个过程中,服务器用的是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);        return cp.doFinal(data);    }    /**     * 私钥加密     *     * @param data       待加密数据     * @param privateKey 密钥     * @return byte[] 加密数据     */    public static byte[] encryptByPrivateKey(byte[] data, byte[] privateKey) throws Exception {        // 得到私钥        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);        KeyFactory kf = KeyFactory.getInstance(RSA);        PrivateKey keyPrivate = kf.generatePrivate(keySpec);        // 数据加密        Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);        cipher.init(Cipher.ENCRYPT_MODE, keyPrivate);        return cipher.doFinal(data);    }    /**     * 公钥解密     *     * @param data      待解密数据     * @param publicKey 密钥     * @return byte[] 解密数据     */    public static byte[] decryptByPublicKey(byte[] data, byte[] publicKey) throws Exception {        // 得到公钥        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);        KeyFactory kf = KeyFactory.getInstance(RSA);        PublicKey keyPublic = kf.generatePublic(keySpec);        // 数据解密        Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);        cipher.init(Cipher.DECRYPT_MODE, keyPublic);        return cipher.doFinal(data);    }    /**     * 使用私钥进行解密     */    public static byte[] decryptByPrivateKey(byte[] encrypted, byte[] privateKey) throws Exception {        // 得到私钥        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey);        KeyFactory kf = KeyFactory.getInstance(RSA);        PrivateKey keyPrivate = kf.generatePrivate(keySpec);        // 解密数据        Cipher cp = Cipher.getInstance(ECB_PKCS1_PADDING);        cp.init(Cipher.DECRYPT_MODE, keyPrivate);        byte[] arr = cp.doFinal(encrypted);        return arr;    }    /**     * 用公钥对字符串进行分段加密     *     */    public static byte[] encryptByPublicKeyForSpilt(byte[] data, byte[] publicKey) throws Exception {        int dataLen = data.length;        if (dataLen <= DEFAULT_BUFFERSIZE) {            return encryptByPublicKey(data, publicKey);        }        List<Byte> allBytes = new ArrayList<Byte>(2048);        int bufIndex = 0;        int subDataLoop = 0;        byte[] buf = new byte[DEFAULT_BUFFERSIZE];        for (int i = 0; i < dataLen; i++) {            buf[bufIndex] = data[i];            if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) {                subDataLoop++;                if (subDataLoop != 1) {                    for (byte b : DEFAULT_SPLIT) {                        allBytes.add(b);                    }                }                byte[] encryptBytes = encryptByPublicKey(buf, publicKey);                for (byte b : encryptBytes) {                    allBytes.add(b);                }                bufIndex = 0;                if (i == dataLen - 1) {                    buf = null;                } else {                    buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)];                }            }        }        byte[] bytes = new byte[allBytes.size()];        {            int i = 0;            for (Byte b : allBytes) {                bytes[i++] = b.byteValue();            }        }        return bytes;    }    /**     * 分段加密     *     * @param data       要加密的原始数据     * @param privateKey 秘钥     */    public static byte[] encryptByPrivateKeyForSpilt(byte[] data, byte[] privateKey) throws Exception {        int dataLen = data.length;        if (dataLen <= DEFAULT_BUFFERSIZE) {            return encryptByPrivateKey(data, privateKey);        }        List<Byte> allBytes = new ArrayList<Byte>(2048);        int bufIndex = 0;        int subDataLoop = 0;        byte[] buf = new byte[DEFAULT_BUFFERSIZE];        for (int i = 0; i < dataLen; i++) {            buf[bufIndex] = data[i];            if (++bufIndex == DEFAULT_BUFFERSIZE || i == dataLen - 1) {                subDataLoop++;                if (subDataLoop != 1) {                    for (byte b : DEFAULT_SPLIT) {                        allBytes.add(b);                    }                }                byte[] encryptBytes = encryptByPrivateKey(buf, privateKey);                for (byte b : encryptBytes) {                    allBytes.add(b);                }                bufIndex = 0;                if (i == dataLen - 1) {                    buf = null;                } else {                    buf = new byte[Math.min(DEFAULT_BUFFERSIZE, dataLen - i - 1)];                }            }        }        byte[] bytes = new byte[allBytes.size()];        {            int i = 0;            for (Byte b : allBytes) {                bytes[i++] = b.byteValue();            }        }        return bytes;    }    /**     * 公钥分段解密     *     * @param encrypted 待解密数据     * @param publicKey 密钥     */    public static byte[] decryptByPublicKeyForSpilt(byte[] encrypted, byte[] publicKey) throws Exception {        int splitLen = DEFAULT_SPLIT.length;        if (splitLen <= 0) {            return decryptByPublicKey(encrypted, publicKey);        }        int dataLen = encrypted.length;        List<Byte> allBytes = new ArrayList<Byte>(1024);        int latestStartIndex = 0;        for (int i = 0; i < dataLen; i++) {            byte bt = encrypted[i];            boolean isMatchSplit = false;            if (i == dataLen - 1) {                // 到data的最后了                byte[] part = new byte[dataLen - latestStartIndex];                System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);                byte[] decryptPart = decryptByPublicKey(part, publicKey);                for (byte b : decryptPart) {                    allBytes.add(b);                }                latestStartIndex = i + splitLen;                i = latestStartIndex - 1;            } else if (bt == DEFAULT_SPLIT[0]) {                // 这个是以split[0]开头                if (splitLen > 1) {                    if (i + splitLen < dataLen) {                        // 没有超出data的范围                        for (int j = 1; j < splitLen; j++) {                            if (DEFAULT_SPLIT[j] != encrypted[i + j]) {                                break;                            }                            if (j == splitLen - 1) {                                // 验证到split的最后一位,都没有break,则表明已经确认是split段                                isMatchSplit = true;                            }                        }                    }                } else {                    // split只有一位,则已经匹配了                    isMatchSplit = true;                }            }            if (isMatchSplit) {                byte[] part = new byte[i - latestStartIndex];                System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);                byte[] decryptPart = decryptByPublicKey(part, publicKey);                for (byte b : decryptPart) {                    allBytes.add(b);                }                latestStartIndex = i + splitLen;                i = latestStartIndex - 1;            }        }        byte[] bytes = new byte[allBytes.size()];        {            int i = 0;            for (Byte b : allBytes) {                bytes[i++] = b.byteValue();            }        }        return bytes;    }    /**     * 使用私钥分段解密     *     */    public static byte[] decryptByPrivateKeyForSpilt(byte[] encrypted, byte[] privateKey) throws Exception {        int splitLen = DEFAULT_SPLIT.length;        if (splitLen <= 0) {            return decryptByPrivateKey(encrypted, privateKey);        }        int dataLen = encrypted.length;        List<Byte> allBytes = new ArrayList<Byte>(1024);        int latestStartIndex = 0;        for (int i = 0; i < dataLen; i++) {            byte bt = encrypted[i];            boolean isMatchSplit = false;            if (i == dataLen - 1) {                // 到data的最后了                byte[] part = new byte[dataLen - latestStartIndex];                System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);                byte[] decryptPart = decryptByPrivateKey(part, privateKey);                for (byte b : decryptPart) {                    allBytes.add(b);                }                latestStartIndex = i + splitLen;                i = latestStartIndex - 1;            } else if (bt == DEFAULT_SPLIT[0]) {                // 这个是以split[0]开头                if (splitLen > 1) {                    if (i + splitLen < dataLen) {                        // 没有超出data的范围                        for (int j = 1; j < splitLen; j++) {                            if (DEFAULT_SPLIT[j] != encrypted[i + j]) {                                break;                            }                            if (j == splitLen - 1) {                                // 验证到split的最后一位,都没有break,则表明已经确认是split段                                isMatchSplit = true;                            }                        }                    }                } else {                    // split只有一位,则已经匹配了                    isMatchSplit = true;                }            }            if (isMatchSplit) {                byte[] part = new byte[i - latestStartIndex];                System.arraycopy(encrypted, latestStartIndex, part, 0, part.length);                byte[] decryptPart = decryptByPrivateKey(part, privateKey);                for (byte b : decryptPart) {                    allBytes.add(b);                }                latestStartIndex = i + splitLen;                i = latestStartIndex - 1;            }        }        byte[] bytes = new byte[allBytes.size()];        {            int i = 0;            for (Byte b : allBytes) {                bytes[i++] = b.byteValue();            }        }        return bytes;    }}

调用加密方法,key为公钥,data为加密的字符串

RSAUtils.decryptByPublicKey(key, data)

解密也类似,ok,问题其实很容易

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. 修改Android中strings.xml文件, 动态改变数据
  3. 关于android app相关破解技术
  4. 总结Android(安卓)Socket开发中可能遇到的问题
  5. 支持单选,多选,还可以限制选择的数量的android流式布局
  6. Android连接远程数据库(PHP+MYSQL)
  7. Android(安卓)LBS系列06 位置策略(二)模拟位置数据的方法
  8. Android开发者必知的Java知识(三) 结合注解分析ActiveAndroid的
  9. Android(安卓)App之间通过Intent交互

随机推荐

  1. Android Logo消息角标数字提醒
  2. Android 网络连接-重试机制-HttpRequestR
  3. android启动时自动抓取logcat
  4. Android世界的Swift - Kotlin语言
  5. android 锁屏页
  6. android聊天表情开发
  7. android 图表引擎AChartEngine(柱状图)
  8. android 网络判断的几种方法
  9. android:showAsAction
  10. Android(安卓)软件在线升级,在线安装apk程