`
luckliu521
  • 浏览: 258783 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Android RSA加密解密

 
阅读更多
Android RSA加密解密
2014-11-24 10:31 17848人阅读 评论(4) 收藏 举报
分类: Android开发(1715)   Android UI(812) 
转载请注明出处: http://blog.csdn.net/bbld_/article/details/38777491

概述
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、我们可以在代码里随机生成密钥对
[java] view plaincopy
/**
* 随机生成RSA密钥对

* @param keyLength
*            密钥长度,范围:512~2048<br>
*            一般1024
* @return
*/ 
public static KeyPair generateRSAKeyPair(int keyLength) 

    try 
    { 
        KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA); 
        kpg.initialize(keyLength); 
        return kpg.genKeyPair(); 
    } catch (NoSuchAlgorithmException e) 
    { 
        e.printStackTrace(); 
        return null; 
    } 


通过这方法我们得到KeyPair后就可以调用 keyPair.getPrivate() 和 pair.getPublic()得到 私钥 和 公钥了。不过实际我们一般是使用2的方法把生成的密钥对保存起来,密钥自己保存,比如服务端,把公钥给客户端(Android)用于加密需要发送的数据,最后服务端根据私钥吧客户端加密的信息解密再处理。
2、通过OpenSSl工具生成密钥对
OpenSSl工具下载:OpenSSl工具 (64位的也可使用)使用OpenSSl工具生成密钥对的过程如下:
首先双击打开bin文件夹下的openssl.exe,打开之后是一个命令行窗口:

然后通过如下命令生成私钥:
[plain] view plaincopy
genrsa -out rsa_private_key.pem 1024 


这条命令是让openssl随机生成了一份私钥,加密长度是1024位, 密钥长度,范围:512~2048。执行完命令后就可在bin文件夹下看到rsa_private_key.pem文件了。
用文本类工具打开可看到里面的内容:
[plain] view plaincopy
-----BEGIN RSA PRIVATE KEY----- 
MIICXQIBAAKBgQCfRTdcPIH10gT9f31rQuIInLwe7fl2dtEJ93gTmjE9c2H+kLVE 
NWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThraz/L3nYJYlbqjHC3jTjUnZc0l 
uumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG9aYqgE7zyTRZYX9byQIDAQAB 
AoGAO9+sYRtKC9xJDfcocfMxv+UT/1ic6EDgcqu6Uzwq+Jvwod9KlXqyQJqCr6T7 
pjfodc3RAZOTx4gCZJverBvz053RH5GawCdocEgaqbXAAWJOhA+9IEU0NUud7ckF 
yDko0QXLoGP9tanrMEt5zMqt8QxDyl6Xcij3mk8rivOgBJECQQDNTO6dZX8xCozc 
Ne0gzC53Gv/KQXANBBHMr7WkKUb2i5+tXkEJ5z3abx2ppEQXDr4AgJH8Gtbm6K7t 
EHV4ov4FAkEAxppD/iiT1/SVQq20be8CsiHpsjTPiestWQWdm1Qn/Y2nAkGkpCFp 
yEdUvVDPtQhRN9EqNggNAnwg5kMvsuwN9QJAfHBhQe4/hk5Kyz+0l+irUW6AFOxN 
KtaIo3TtuK98X/yJsOAstAACMeCgLi9vRjqdWFiWJCVwlU38mZ0cVx8UsQJBALzt 
M5Er+LiPKw5rQCD0JZRfPnkQU/3XgyQUe4Gv5PsHLcCvwXeBcafcc3hEz9JfPyPi 
Dk2oCvg6LPHfKBkFBaECQQCODcKX6DBWiyVxmPaJOOcF63KpCYDPkjeovIUHro1x 
ElR2GrQCC/9Q4C4vruOhBQ+vX8NMPnO6NBy5TLGDwMyc 
-----END RSA PRIVATE KEY----- 

这里面的内容是标准的ASCII字符,中间的一大串字符就是私钥数据了。

然后通过如下命令生成公钥:
[plain] view plaincopy
rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout 

打开文件看下里面的内容:
[plain] view plaincopy
-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfRTdcPIH10gT9f31rQuIInLwe 
7fl2dtEJ93gTmjE9c2H+kLVENWgECiJVQ5sonQNfwToMKdO0b3Olf4pgBKeLThra 
z/L3nYJYlbqjHC3jTjUnZc0luumpXGsox62+PuSGBlfb8zJO6hix4GV/vhyQVCpG 
9aYqgE7zyTRZYX9byQIDAQAB 
-----END PUBLIC KEY----- 

可以看到是跟私钥的文件类似的。

这样密钥就基本生成了,不过这样密钥对的私钥是无法在代码中直接使用的,要想使用它需要借助RSAPrivateKeyStructure这个类,Java是不自带的。所以为了方便使用,我们需要对私钥进行PKCS#8编码,命令如下:
[plain] view plaincopy
pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt   

这条命令的结果依然是在bin文件夹生成了pkcs8_rsa_private_key.pem文件,打开内容如下:
[plain] view plaincopy
-----BEGIN PRIVATE KEY----- 
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ9FN1w8gfXSBP1/ 
fWtC4gicvB7t+XZ20Qn3eBOaMT1zYf6QtUQ1aAQKIlVDmyidA1/BOgwp07Rvc6V/ 
imAEp4tOGtrP8vedgliVuqMcLeNONSdlzSW66alcayjHrb4+5IYGV9vzMk7qGLHg 
ZX++HJBUKkb1piqATvPJNFlhf1vJAgMBAAECgYA736xhG0oL3EkN9yhx8zG/5RP/ 
WJzoQOByq7pTPCr4m/Ch30qVerJAmoKvpPumN+h1zdEBk5PHiAJkm96sG/PTndEf 
kZrAJ2hwSBqptcABYk6ED70gRTQ1S53tyQXIOSjRBcugY/21qeswS3nMyq3xDEPK 
XpdyKPeaTyuK86AEkQJBAM1M7p1lfzEKjNw17SDMLnca/8pBcA0EEcyvtaQpRvaL 
n61eQQnnPdpvHamkRBcOvgCAkfwa1uboru0QdXii/gUCQQDGmkP+KJPX9JVCrbRt 
7wKyIemyNM+J6y1ZBZ2bVCf9jacCQaSkIWnIR1S9UM+1CFE30So2CA0CfCDmQy+y 
7A31AkB8cGFB7j+GTkrLP7SX6KtRboAU7E0q1oijdO24r3xf/Imw4Cy0AAIx4KAu 
L29GOp1YWJYkJXCVTfyZnRxXHxSxAkEAvO0zkSv4uI8rDmtAIPQllF8+eRBT/deD 
JBR7ga/k+wctwK/Bd4Fxp9xzeETP0l8/I+IOTagK+Dos8d8oGQUFoQJBAI4Nwpfo 
MFaLJXGY9ok45wXrcqkJgM+SN6i8hQeujXESVHYatAIL/1DgLi+u46EFD69fw0w+ 
c7o0HLlMsYPAzJw= 
-----END PRIVATE KEY----- 

可以看到中间的私钥内容有所变化了,这样的私钥我们在代码里就方便使用了。

以上的密钥文件使用时需要注意吧头和尾的字符串去掉,我们只取中间的内容。

代码中的使用
首先我们需要封装写个RSA的工具类,方便加密解密的操作。
[java] view plaincopy
package com.example.rsa; 
 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.math.BigInteger; 
import java.security.KeyFactory; 
import java.security.KeyPair; 
import java.security.KeyPairGenerator; 
import java.security.NoSuchAlgorithmException; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.interfaces.RSAPrivateKey; 
import java.security.interfaces.RSAPublicKey; 
import java.security.spec.InvalidKeySpecException; 
import java.security.spec.PKCS8EncodedKeySpec; 
import java.security.spec.RSAPublicKeySpec; 
import java.security.spec.X509EncodedKeySpec; 
 
import javax.crypto.Cipher; 
 
/**
* @author Mr.Zheng
* @date 2014年8月22日 下午1:44:23
*/ 
public final class RSAUtils 

    private static String RSA = "RSA"; 
 
    /**
     * 随机生成RSA密钥对(默认密钥长度为1024)
     * 
     * @return
     */ 
    public static KeyPair generateRSAKeyPair() 
    { 
        return generateRSAKeyPair(1024); 
    } 
 
    /**
     * 随机生成RSA密钥对
     * 
     * @param keyLength
     *            密钥长度,范围:512~2048<br>
     *            一般1024
     * @return
     */ 
    public static KeyPair generateRSAKeyPair(int keyLength) 
    { 
        try 
        { 
            KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA); 
            kpg.initialize(keyLength); 
            return kpg.genKeyPair(); 
        } catch (NoSuchAlgorithmException e) 
        { 
            e.printStackTrace(); 
            return null; 
        } 
    } 
 
    /**
     * 用公钥加密 <br>
     * 每次加密的字节数,不能超过密钥的长度值减去11
     * 
     * @param data
     *            需加密数据的byte数据
     * @param pubKey
     *            公钥
     * @return 加密后的byte型数据
     */ 
    public static byte[] encryptData(byte[] data, PublicKey publicKey) 
    { 
        try 
        { 
            Cipher cipher = Cipher.getInstance(RSA); 
            // 编码前设定编码方式及密钥 
            cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
            // 传入编码数据并返回编码结果 
            return cipher.doFinal(data); 
        } catch (Exception e) 
        { 
            e.printStackTrace(); 
            return null; 
        } 
    } 
 
    /**
     * 用私钥解密
     * 
     * @param encryptedData
     *            经过encryptedData()加密返回的byte数据
     * @param privateKey
     *            私钥
     * @return
     */ 
    public static byte[] decryptData(byte[] encryptedData, PrivateKey privateKey) 
    { 
        try 
        { 
            Cipher cipher = Cipher.getInstance(RSA); 
            cipher.init(Cipher.DECRYPT_MODE, privateKey); 
            return cipher.doFinal(encryptedData); 
        } catch (Exception e) 
        { 
            return null; 
        } 
    } 
 
    /**
     * 通过公钥byte[](publicKey.getEncoded())将公钥还原,适用于RSA算法
     * 
     * @param keyBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */ 
    public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, 
            InvalidKeySpecException 
    { 
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 
        KeyFactory keyFactory = KeyFactory.getInstance(RSA); 
        PublicKey publicKey = keyFactory.generatePublic(keySpec); 
        return publicKey; 
    } 
 
    /**
     * 通过私钥byte[]将公钥还原,适用于RSA算法
     * 
     * @param keyBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */ 
    public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException, 
            InvalidKeySpecException 
    { 
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); 
        KeyFactory keyFactory = KeyFactory.getInstance(RSA); 
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec); 
        return privateKey; 
    } 
 
    /**
     * 使用N、e值还原公钥
     * 
     * @param modulus
     * @param publicExponent
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */ 
    public static PublicKey getPublicKey(String modulus, String publicExponent) 
            throws NoSuchAlgorithmException, InvalidKeySpecException 
    { 
        BigInteger bigIntModulus = new BigInteger(modulus); 
        BigInteger bigIntPrivateExponent = new BigInteger(publicExponent); 
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); 
        KeyFactory keyFactory = KeyFactory.getInstance(RSA); 
        PublicKey publicKey = keyFactory.generatePublic(keySpec); 
        return publicKey; 
    } 
 
    /**
     * 使用N、d值还原私钥
     * 
     * @param modulus
     * @param privateExponent
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */ 
    public static PrivateKey getPrivateKey(String modulus, String privateExponent) 
            throws NoSuchAlgorithmException, InvalidKeySpecException 
    { 
        BigInteger bigIntModulus = new BigInteger(modulus); 
        BigInteger bigIntPrivateExponent = new BigInteger(privateExponent); 
        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus, bigIntPrivateExponent); 
        KeyFactory keyFactory = KeyFactory.getInstance(RSA); 
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec); 
        return privateKey; 
    } 
 
    /**
     * 从字符串中加载公钥
     * 
     * @param publicKeyStr
     *            公钥数据字符串
     * @throws Exception
     *             加载公钥时产生的异常
     */ 
    public static PublicKey loadPublicKey(String publicKeyStr) throws Exception 
    { 
        try 
        { 
            byte[] buffer = Base64Utils.decode(publicKeyStr); 
            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>
     * 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。
     * 
     * @param privateKeyStr
     * @return
     * @throws Exception
     */ 
    public static PrivateKey loadPrivateKey(String privateKeyStr) throws Exception 
    { 
        try 
        { 
            byte[] buffer = Base64Utils.decode(privateKeyStr); 
            // X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer); 
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); 
            KeyFactory keyFactory = KeyFactory.getInstance(RSA); 
            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec); 
        } catch (NoSuchAlgorithmException e) 
        { 
            throw new Exception("无此算法"); 
        } catch (InvalidKeySpecException e) 
        { 
            throw new Exception("私钥非法"); 
        } catch (NullPointerException e) 
        { 
            throw new Exception("私钥数据为空"); 
        } 
    } 
 
    /**
     * 从文件中输入流中加载公钥
     * 
     * @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 keyFileName
     *            私钥文件名
     * @return 是否成功
     * @throws Exception
     */ 
    public static PrivateKey loadPrivateKey(InputStream in) throws Exception 
    { 
        try 
        { 
            return loadPrivateKey(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 publicKey
     */ 
    public static void printPublicKeyInfo(PublicKey publicKey) 
    { 
        RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey; 
        System.out.println("----------RSAPublicKey----------"); 
        System.out.println("Modulus.length=" + rsaPublicKey.getModulus().bitLength()); 
        System.out.println("Modulus=" + rsaPublicKey.getModulus().toString()); 
        System.out.println("PublicExponent.length=" + rsaPublicKey.getPublicExponent().bitLength()); 
        System.out.println("PublicExponent=" + rsaPublicKey.getPublicExponent().toString()); 
    } 
 
    public static void printPrivateKeyInfo(PrivateKey privateKey) 
    { 
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) privateKey; 
        System.out.println("----------RSAPrivateKey ----------"); 
        System.out.println("Modulus.length=" + rsaPrivateKey.getModulus().bitLength()); 
        System.out.println("Modulus=" + rsaPrivateKey.getModulus().toString()); 
        System.out.println("PrivateExponent.length=" + rsaPrivateKey.getPrivateExponent().bitLength()); 
        System.out.println("PrivatecExponent=" + rsaPrivateKey.getPrivateExponent().toString()); 
 
    } 
 

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

代码中有些需要使用Base64再转换的,而java中不自带,Android中自带,所以自己写出一个来,方便Java后台使用
[java] view plaincopy
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 < len) 
        { 
            b1 = data[i++] & 0xff; 
            if (i == len) 
            { 
                sb.append(base64EncodeChars[b1 >>> 2]); 
                sb.append(base64EncodeChars[(b1 & 0x3) << 4]); 
                sb.append("=="); 
                break; 
            } 
            b2 = data[i++] & 0xff; 
            if (i == len) 
            { 
                sb.append(base64EncodeChars[b1 >>> 2]); 
                sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); 
                sb.append(base64EncodeChars[(b2 & 0x0f) << 2]); 
                sb.append("="); 
                break; 
            } 
            b3 = data[i++] & 0xff; 
            sb.append(base64EncodeChars[b1 >>> 2]); 
            sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); 
            sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 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 < len) 
        { 
 
            do 
            { 
                b1 = base64DecodeChars[data[i++]]; 
            } while (i < len && b1 == -1); 
            if (b1 == -1) 
                break; 
 
            do 
            { 
                b2 = base64DecodeChars[data[i++]]; 
            } while (i < len && b2 == -1); 
            if (b2 == -1) 
                break; 
            sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4))); 
 
            do 
            { 
                b3 = data[i++]; 
                if (b3 == 61) 
                    return sb.toString().getBytes("iso8859-1"); 
                b3 = base64DecodeChars[b3]; 
            } while (i < len && b3 == -1); 
            if (b3 == -1) 
                break; 
            sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2))); 
 
            do 
            { 
                b4 = data[i++]; 
                if (b4 == 61) 
                    return sb.toString().getBytes("iso8859-1"); 
                b4 = base64DecodeChars[b4]; 
            } while (i < len && b4 == -1); 
            if (b4 == -1) 
                break; 
            sb.append((char) (((b3 & 0x03) << 6) | b4)); 
        } 
        return sb.toString().getBytes("iso8859-1"); 
    } 
 


最后就是真正使用它们了:
[java] view plaincopy
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资源文件夹里了,也可以直接使用字符串得到,上面注释掉了。
最后我们来看下效果吧:


源码下载地址:http://download.csdn.net/detail/bbld_/7806673
分享到:
评论

相关推荐

    Android RSA加密解密demo

    本示例"Android RSA加密解密demo"提供了一个完整的实现过程,帮助开发者理解如何在Android平台上使用RSA进行数据的加密和解密操作。 RSA算法基于数论,它的核心思想是利用两个大素数的乘积作为公钥,这两个大素数的...

    Android RSA 加密解密Demo

    本文将深入探讨Android平台上的RSA加密解密技术,并基于提供的"Android RSA 加密解密Demo"进行详细讲解。 首先,RSA加密算法基于大数因子分解的难题,由Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出。它...

    Android RSA加密解密文件

    Android RSA加密解密文件

    Android使用RSA加密解密功能的实现Demo

    本教程将详细介绍如何在Android项目中实现RSA加密解密功能,并通过一个Demo来说明其具体步骤。 首先,我们需要了解RSA加密的基本原理。RSA是由Ron Rivest、Adi Shamir和Leonard Adleman三位科学家于1977年提出的,...

    C#Android互通RSA加密解密

    "C# Android互通RSA加密解密"这一主题就聚焦于如何在C#和Android之间安全地进行数据传输,通过RSA加密算法确保数据的安全性。 RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,它基于大数因子分解的困难性,为...

    android RSA2加密解密

    android RSA2加密解密,里边提供两个方法,一个是生成公有私有秘钥加密解密,另一个是加密解密

    RSA加密解密的使用,含jsencrypt.js文件(uni-app也可用)

    RSA加密解密是一种广泛应用于网络安全中的非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman三位科学家在1977年提出,因此得名RSA。这种算法基于大数因子分解的困难性,为数据提供了一种安全的传输方式。 ...

    RSA加密解密示例工程

    RSA加密解密示例工程是一个专门针对Android平台设计的学习资源,旨在帮助开发者深入理解并实践RSA加密算法。RSA,全称Rivest-Shamir-Adleman,是一种非对称加密技术,广泛应用于网络安全、数据保护等领域。该示例...

    Java RSA 加密解密

    在`android-rsa-master`这个项目中,可能包含了完整的Android RSA加密解密示例,包括如何在Android环境中生成和使用密钥对,以及如何处理文件的加解密。这个项目可能包括了Android特有的安全存储,如Keystore系统,...

    Android RSA加密jar包

    这个“Android RSA加密jar包”就是专为Android平台设计的,用于实现RSA加密和解密功能的Java库。 RSA加密的基本原理是基于两个大素数的乘积,这两个大素数只有乘积关系,很难从结果反推出原始素数。加密过程使用...

    RSA加密解密的Android的演示Demo

    **RSA加密解密在Android中的应用** RSA是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman在1977年提出,是现代密码学的基石之一。它广泛应用于数据加密、数字签名等领域,尤其在移动应用如Android...

    Android之RSA加密解密签名验签(亲测可用)

    在Android开发中,数据安全是至关重要的,尤其是在...通过以上步骤,您可以在Android应用中实现RSA加密解密和签名验签功能,确保数据的安全传输和验证。记住,安全无小事,合理的加密策略是保障应用安全的重要一环。

    RSA加密解密教程

    这个"RSA加密解密教程"对于Android开发新手来说,是一个很好的起点,可以帮助他们理解非对称加密的基本概念,以及如何在实际项目中应用RSA技术。通过学习和实践,开发者可以更好地保护应用程序中的敏感数据,提高...

    android和 ios 与java web服务器端的rsa 加密解密

    本文将深入探讨Android和iOS客户端以及Java Web服务器之间的RSA加密解密技术,特别关注Android端的特殊处理需求。 RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,它基于两个密钥:公钥和私钥。公钥用于加密...

    RSA、AES混合加密解密,Java工程、安卓Demo,1024和2048长度密钥都可用,兼容Android所有版本

    本项目结合了这两种算法,创建了一个混合加密解密方案,适用于Java工程和Android应用。下面将详细介绍RSA、AES加密解密以及它们在混合模式下的应用。 RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,基于数论...

    RSADemo:Android RSA加密解密

    RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困 难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥...

    Android,java实现RSA加密

    RSA加密算法,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息...本资源是通过Android、java实现的RSA加密的例子,可供大家参考学习。

    Android之RSA算法加密解密

    Android之RSA算法加密解密

    RSA加密解密,签名验证代码

    在Android和Java平台实现RSA加密解密,主要涉及以下几个步骤: 1. **密钥生成**:首先,我们需要生成RSA密钥对。这通常通过`KeyPairGenerator`类来实现,指定算法为"RSA",并设置密钥长度,比如2048位。生成的密钥...

    RSA加密解密算法

    总的来说,RSA加密解密算法在Android、Java以及iOS之间的实现虽有差异,但原理相通,通过Base64编码适应不同环境的需求,是保障数据安全传输的有效手段。正确理解和应用这些知识,对于开发安全的跨平台应用至关重要...

Global site tag (gtag.js) - Google Analytics