android RSA 加密实现

一直用的MD5加密方式,最近服务器需要更换RSA加密方式,据悉是因为RSA更安全吧,查阅资料之后实现了。

第一步:

将服务给你的rsa公钥copy到assets文件下(加密只需要公钥,服务器端游对应的私钥来解密)

第二步:

    String rsaName = AppUtils.rsaEncode(this, name);
    //rsa加密
    public static String rsaEncode(Context context, String source) {
        String afterencrypt = "";
        try {
            // 从文件中得到公钥
            InputStream inPublic = context.getResources().getAssets().open("xxxxxx.pem");
            PublicKey publicKey = RSAUtils.loadPublicKey(inPublic);//方法如下
            // 加密
            byte[] encryptByte = RSAUtils.encryptData(source.getBytes(), publicKey);//方法如下
            // 为了方便观察吧加密后的数据用base64加密转一下,要不然看起来是乱码,所以解密是也是要用Base64先转换
            afterencrypt = Base64.encodeToString(encryptByte, Base64.DEFAULT);
        } catch (Exception e) {
            e.printStackTrace();
        }
        afterencrypt = afterencrypt.replaceAll("\n", "");//转换出来的字符串带有换行符,替换掉就好了
        return afterencrypt;
    } 
    private static String RSA = "RSA";
    /**
     * 从文件中输入流中加载公钥
     *
     * @param in 公钥输入流
     * @throws Exception 加载公钥时产生的异常
     */
    public static PublicKey loadPublicKey(InputStream in) throws Exception {
        try {
            return loadPublicKey(readKey(in));
        } catch (IOException e) {
            throw new Exception("公钥数据流读取错误");
        } catch (NullPointerException e) {
            throw new Exception("公钥输入流为空");
        }
    }
    /**
     * 读取密钥信息
     *
     * @param in
     * @return
     * @throws IOException
     */
    private static String readKey(InputStream in) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String readLine = null;
        StringBuilder sb = new StringBuilder();
        while ((readLine = br.readLine()) != null) {
            if (readLine.charAt(0) == '-') {
                continue;
            } else {
                sb.append(readLine);
                sb.append('\r');
            }
        }
        return sb.toString();
    }

    /**
     * 从字符串中加载公钥
     *
     * @param publicKeyStr 公钥数据字符串
     * @throws Exception 加载公钥时产生的异常
     */
    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
        try {
            byte[] buffer = Base64.decode(publicKeyStr,Base64.DEFAULT);
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("无此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("公钥非法");
        } catch (NullPointerException e) {
            throw new Exception("公钥数据为空");
        }
    }
    /**
     * 用公钥加密 <br>
     * 每次加密的字节数,不能超过密钥的长度值减去11
     *
     * @param data   需加密数据的byte数据
     * @param pubKey 公钥
     * @return 加密后的byte型数据
     */
    public static byte[] encryptData(byte[] data, PublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//这里的参数一定要填这个,否则会导致加密后和服务器不一致
            // 编码前设定编码方式及密钥
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // 传入编码数据并返回编码结果
            return cipher.doFinal(data);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

P.S.遇到两个问题
1.Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");//这里的参数一定要填这个,否则会导致加密后和服务器不一致
开始这里的参数传递的是"RSA",导致加密后和服务器不一致,所以一定要填如上参数
2.afterencrypt = afterencrypt.replaceAll("\n", "");//转换出来的字符串带有换行符,替换掉就好了
转换出来字符串带有换行符,替换all就好了

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值