android 8.0加密,Android RSA加密解密

概述

RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。关于RSA其它需要了解的知识,参考维基百科:http://zh.wikipedia.org/zh-cn/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95

在项目开发中对于一些比较敏感的信息需要对其进行加密处理,我们就可以使用RSA这种非对称加密算法来对数据进行加密处理。

特别注意:

私钥是用来解密的,公钥是用来公开给大家加密的。如果反过来,则自己自己发的消息所有人都能用公钥解密,不符合要求。

使用

秘钥对的生成

1、我们可以在代码里随机生成密钥对KeyPair generateRSAKeyPair(=

2、下载开源RSA密钥生成工具openssl(通常Linux系统都自带该程序),解压缩至独立的文件夹,进入其中的bin目录,执行以下命令:openssl genrsa -out rsa_private_key.pem 1024openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

第一条命令生成原始 RSA私钥文件 rsa_private_key.pem,第二条命令将原始 RSA私钥转换为 pkcs8格式,第三条生成RSA公钥 rsa_public_key.pem

从上面看出通过私钥能生成对应的公钥,因此我们将私钥private_key.pem用在服务器端,公钥发放给android跟ios等前端

代码中的使用

首先我们需要封装写个RSA的工具类,方便加密解密的操作。final   String RSA =

generateRSAKeyPair(

KeyPair generateRSAKeyPair(=

[] encryptData(=

[] decryptData(=

PublicKey getPublicKey(= ==

PrivateKey getPrivateKey(= ==

= = = ==

= = = ==

[] buffer ===   Exception(  Exception(  Exception(

[] buffer =

PKCS8EncodedKeySpec keySpec = =  Exception(  Exception(  Exception(

PublicKey loadPublicKey(InputStream  loadPublicKey(readKey(  Exception(  Exception(

PrivateKey loadPrivateKey(InputStream  loadPrivateKey(readKey(  Exception(  Exception(

String readKey(InputStream =  BufferedReader( InputStreamReader(= =  ((readLine = br.readLine()) !=  (readLine.charAt() ==

=.println(.println( +.println( +.println( +.println( +  =.println(.println( +.println( +.println( +.println( +

上面需要注意的就是加密是有长度限制的,过长的话会抛异常!!!

代码中有些需要使用Base64再转换的,而java中不自带,Android中自带,所以自己写出一个来,方便Java后台使用package com.example.rsa;

import java.io.UnsupportedEncodingException;/**

* @author Mr.Zheng

* @date 2014年8月22日 下午9:50:28 */public class Base64Utils

{    private static char[] base64EncodeChars = new char[]

{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',            'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',            '6', '7', '8', '9', '+', '/' };    private static byte[] base64DecodeChars = new byte[]

{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53,            54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,            12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29,            30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,            -1, -1, -1 };    /**

* 加密

*

* @param data

* @return     */

public static String encode(byte[] data)

{

StringBuffer sb = new StringBuffer();        int len = data.length;        int i = 0;        int b1, b2, b3;        while (i 

{

b1 = data[i++] & 0xff;            if (i == len)

{

sb.append(base64EncodeChars[b1 >>> 2]);

sb.append(base64EncodeChars[(b1 & 0x3) <

sb.append("==");                break;

}

b2 = data[i++] & 0xff;            if (i == len)

{

sb.append(base64EncodeChars[b1 >>> 2]);

sb.append(base64EncodeChars[((b1 & 0x03) <>> 4)]);

sb.append(base64EncodeChars[(b2 & 0x0f) <

sb.append("=");                break;

}

b3 = data[i++] & 0xff;

sb.append(base64EncodeChars[b1 >>> 2]);

sb.append(base64EncodeChars[((b1 & 0x03) <>> 4)]);

sb.append(base64EncodeChars[((b2 & 0x0f) <>> 6)]);

sb.append(base64EncodeChars[b3 & 0x3f]);

}        return sb.toString();

}    /**

* 解密

*

* @param str

* @return     */

public static byte[] decode(String str)

{        try

{            return decodePrivate(str);

} catch (UnsupportedEncodingException e)

{

e.printStackTrace();

}        return new byte[]

{};

}    private static byte[] decodePrivate(String str) throws UnsupportedEncodingException

{

StringBuffer sb = new StringBuffer();        byte[] data = null;

data = str.getBytes("US-ASCII");        int len = data.length;        int i = 0;        int b1, b2, b3, b4;        while (i 

{            do

{

b1 = base64DecodeChars[data[i++]];

} while (i 

{

b2 = base64DecodeChars[data[i++]];

} while (i 

sb.append((char) ((b1 <>> 4)));            do

{

b3 = data[i++];                if (b3 == 61)                    return sb.toString().getBytes("iso8859-1");

b3 = base64DecodeChars[b3];

} while (i 

sb.append((char) (((b2 & 0x0f) <>> 2)));            do

{

b4 = data[i++];                if (b4 == 61)                    return sb.toString().getBytes("iso8859-1");

b4 = base64DecodeChars[b4];

} while (i 

sb.append((char) (((b3 & 0x03) <

}        return sb.toString().getBytes("iso8859-1");

}

}

最后就是真正使用它们了:package com.example.rsa;

import java.io.InputStream;

import java.security.PrivateKey;

import java.security.PublicKey;

import android.app.Activity;

import android.os.Bundle;

import android.util.Base64;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;public class MainActivity extends Activity implements OnClickListener

{    private Button btn1, btn2;// 加密,解密

private EditText et1, et2, et3;// 需加密的内容,加密后的内容,解密后的内容

/* 密钥内容 base64 code */

private static String PUCLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfRTdcPIH10gT9f31rQuIInLwe"

+ "\r" + "7fl2dtEJ93gTmjE9c2H+kLVENWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThra" + "\r"

+ "z/L3nYJYlbqjHC3jTjUnZc0luumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG" + "\r"

+ "9aYqgE7zyTRZYX9byQIDAQAB" + "\r";    private static String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ9FN1w8gfXSBP1/"

+ "\r" + "fWtC4gicvB7t+XZ20Qn3eBOaMT1zYf6QtUQ1aAQKIlVDmyidA1/BOgwp07Rvc6V/" + "\r"

+ "imAEp4tOGtrP8vedgliVuqMcLeNONSdlzSW66alcayjHrb4+5IYGV9vzMk7qGLHg" + "\r"

+ "ZX++HJBUKkb1piqATvPJNFlhf1vJAgMBAAECgYA736xhG0oL3EkN9yhx8zG/5RP/" + "\r"

+ "WJzoQOByq7pTPCr4m/Ch30qVerJAmoKvpPumN+h1zdEBk5PHiAJkm96sG/PTndEf" + "\r"

+ "kZrAJ2hwSBqptcABYk6ED70gRTQ1S53tyQXIOSjRBcugY/21qeswS3nMyq3xDEPK" + "\r"

+ "XpdyKPeaTyuK86AEkQJBAM1M7p1lfzEKjNw17SDMLnca/8pBcA0EEcyvtaQpRvaL" + "\r"

+ "n61eQQnnPdpvHamkRBcOvgCAkfwa1uboru0QdXii/gUCQQDGmkP+KJPX9JVCrbRt" + "\r"

+ "7wKyIemyNM+J6y1ZBZ2bVCf9jacCQaSkIWnIR1S9UM+1CFE30So2CA0CfCDmQy+y" + "\r"

+ "7A31AkB8cGFB7j+GTkrLP7SX6KtRboAU7E0q1oijdO24r3xf/Imw4Cy0AAIx4KAu" + "\r"

+ "L29GOp1YWJYkJXCVTfyZnRxXHxSxAkEAvO0zkSv4uI8rDmtAIPQllF8+eRBT/deD" + "\r"

+ "JBR7ga/k+wctwK/Bd4Fxp9xzeETP0l8/I+IOTagK+Dos8d8oGQUFoQJBAI4Nwpfo" + "\r"

+ "MFaLJXGY9ok45wXrcqkJgM+SN6i8hQeujXESVHYatAIL/1DgLi+u46EFD69fw0w+" + "\r" + "c7o0HLlMsYPAzJw="

+ "\r";

@Override    protected void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initView();

}    private void initView()

{

btn1 = (Button) findViewById(R.id.btn1);

btn2 = (Button) findViewById(R.id.btn2);

btn1.setOnClickListener(this);

btn2.setOnClickListener(this);

et1 = (EditText) findViewById(R.id.et1);

et2 = (EditText) findViewById(R.id.et2);

et3 = (EditText) findViewById(R.id.et3);

}

@Override    public void onClick(View v)

{        switch (v.getId())

{        // 加密

case R.id.btn1:

String source = et1.getText().toString().trim();            try

{                // 从字符串中得到公钥                // PublicKey publicKey = RSAUtils.loadPublicKey(PUCLIC_KEY);                // 从文件中得到公钥

InputStream inPublic = getResources().getAssets().open("rsa_public_key.pem");

PublicKey publicKey = RSAUtils.loadPublicKey(inPublic);                // 加密

byte[] encryptByte = RSAUtils.encryptData(source.getBytes(), publicKey);                // 为了方便观察吧加密后的数据用base64加密转一下,要不然看起来是乱码,所以解密是也是要用Base64先转换

String afterencrypt = Base64Utils.encode(encryptByte);

et2.setText(afterencrypt);

} catch (Exception e)

{

e.printStackTrace();

}            break;        // 解密

case R.id.btn2:

String encryptContent = et2.getText().toString().trim();            try

{                // 从字符串中得到私钥                // PrivateKey privateKey = RSAUtils.loadPrivateKey(PRIVATE_KEY);                // 从文件中得到私钥

InputStream inPrivate = getResources().getAssets().open("pkcs8_rsa_private_key.pem");

PrivateKey privateKey = RSAUtils.loadPrivateKey(inPrivate);                // 因为RSA加密后的内容经Base64再加密转换了一下,所以先Base64解密回来再给RSA解密

byte[] decryptByte = RSAUtils.decryptData(Base64Utils.decode(encryptContent), privateKey);

String decryptStr = new String(decryptByte);

et3.setText(decryptStr);

} catch (Exception e)

{

e.printStackTrace();

}            break;        default:            break;

}

}

}

我把密钥放到assest资源文件夹里了,也可以直接使用字符串得到,上面注释掉了。

后记:后来发现,android的rsa机制和php,java的默认机制有点不同

也就是说android系统的RSA实现是"RSA/None/NoPadding",而标准JDK实现是"RSA/ECB/PKCS1Padding"

稍微作修改一下这里:Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");就行了

修改后的RSAUtils类final   String RSA =   String RSA1 =

generateRSAKeyPair(

KeyPair generateRSAKeyPair(=

[] encryptData(=

[] decryptData(=

PublicKey getPublicKey(= ==

PrivateKey getPrivateKey(= ==

= = = ==

= = = ==

[] buffer ===   Exception(  Exception(  Exception(

[] buffer =

PKCS8EncodedKeySpec keySpec = =  Exception(  Exception(  Exception(

PublicKey loadPublicKey(InputStream  loadPublicKey(readKey(  Exception(  Exception(

PrivateKey loadPrivateKey(InputStream  loadPrivateKey(readKey(  Exception(  Exception(

String readKey(InputStream =  BufferedReader( InputStreamReader(= =  ((readLine = br.readLine()) !=  (readLine.charAt() ==

=.println(.println( +.println( +.println( +.println( +  =.println(.println( +.println( +.println( +.println( +

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值