android RSA 加密实现

来源:互联网 发布:编程小游戏用什么软件 编辑:程序博客网 时间:2024/04/29 07:04

一直用的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 0