RSA加密解密教程

RSA算法简介:

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(RonRSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。1973年,在英国政府通讯总部工作的数学家克利福德·柯克斯(Clifford Cocks)在一个内部文件中提出了一个相同的算法,但他的发现被列入机密,一直到1997年才被发表。对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到2013年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。(参考资料:http://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95)


密钥对的生成:

RSA秘钥对的生成有两种方式,一种是在代码中生成随机的秘钥对,另一种是使用工具OpenSSL通过命令行的方式来生成,多半情况下我们用的是OpenSSL来生成的。
方式一:代码生成
/**
* 随机生成RSA密钥对
* 
* @param keyLength
*            密钥长度,范围:512~2048<br>
*            一般1024
* @return
*/
public static KeyPair generateRSAKeyPair(int keyLength)
{
<span style="white-space:pre">	</span>try<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA);
<span style="white-space:pre">		</span>kpg.initialize(keyLength);
<span style="white-space:pre">		</span>return kpg.genKeyPair();
<span style="white-space:pre">	</span>} catch (NoSuchAlgorithmException e){
<span style="white-space:pre">		</span>e.printStackTrace();
<span style="white-space:pre">		</span>return null;
<span style="white-space:pre">	</span>}
}



方式二:OpenSSL工具生成
OpenSSl工具下载:OpenSSl工具下载地址:;使用OpenSSl工具生成密钥对的过程如下:

1)打开bin文件夹下的openssl.exe,打开之后是一个命令行窗口,输入命令:“genrsa -out rsa_private_key.pem 1024”    这是生成RSA私钥的命令,是让openssl随机生成了一份私钥,加密长度是1024位, 密钥长度,范围:512~2048。执行完毕会在bin目录下出现一个rsa_private_key.pem的文件。具体如下图:


2)输入命令:“rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem”    这是生成RSA公钥的命令,随后会在bin目录下出现一个rsa_public_key.pem的文件。具体如上图。
3)输入命令:“pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt”  可以将RSA私钥转换成PKCS8格式,具体如上图。

代码中的使用:

在代码中,需要用到Base64的加密解密,android的系统类中提供了这个接口,但是java中没有,所以记录一下。

package com.unj;


public final class Base64 {

	private static final int BASELENGTH = 128;
	private static final int LOOKUPLENGTH = 64;
	private static final int TWENTYFOURBITGROUP = 24;
	private static final int EIGHTBIT = 8;
	private static final int SIXTEENBIT = 16;
	private static final int FOURBYTE = 4;
	private static final int SIGN = -128;
	private static char PAD = '=';
	private static byte[] base64Alphabet = new byte[BASELENGTH];
	private static char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];

	static {
		for (int i = 0; i < BASELENGTH; ++i) {
			base64Alphabet[i] = -1;
		}
		for (int i = 'Z'; i >= 'A'; i--) {
			base64Alphabet[i] = (byte) (i - 'A');
		}
		for (int i = 'z'; i >= 'a'; i--) {
			base64Alphabet[i] = (byte) (i - 'a' + 26);
		}

		for (int i = '9'; i >= '0'; i--) {
			base64Alphabet[i] = (byte) (i - '0' + 52);
		}

		base64Alphabet['+'] = 62;
		base64Alphabet['/'] = 63;

		for (int i = 0; i <= 25; i++) {
			lookUpBase64Alphabet[i] = (char) ('A' + i);
		}

		for (int i = 26, j = 0; i <= 51; i++, j++) {
			lookUpBase64Alphabet[i] = (char) ('a' + j);
		}

		for (int i = 52, j = 0; i <= 61; i++, j++) {
			lookUpBase64Alphabet[i] = (char) ('0' + j);
		}
		lookUpBase64Alphabet[62] = (char) '+';
		lookUpBase64Alphabet[63] = (char) '/';

	}

	private static boolean isWhiteSpace(char octect) {
		return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
	}

	private static boolean isPad(char octect) {
		return (octect == PAD);
	}

	private static boolean isData(char octect) {
		return (octect < BASELENGTH && base64Alphabet[octect] != -1);
	}

	/**
	 * Encodes hex octects into Base64
	 * 
	 * @param binaryData
	 *            Array containing binaryData
	 * @return Encoded Base64 array
	 */
	public static String encode(byte[] binaryData) {

		if (binaryData == null) {
			return null;
		}

		int lengthDataBits = binaryData.length * EIGHTBIT;
		if (lengthDataBits == 0) {
			return "";
		}

		int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
		int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
		int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
				: numberTriplets;
		char encodedData[] = null;

		encodedData = new char[numberQuartet * 4];

		byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;

		int encodedIndex = 0;
		int dataIndex = 0;

		for (int i = 0; i < numberTriplets; i++) {
			b1 = binaryData[dataIndex++];
			b2 = binaryData[dataIndex++];
			b3 = binaryData[dataIndex++];

			l = (byte) (b2 & 0x0f);
			k = (byte) (b1 & 0x03);

			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
					: (byte) ((b1) >> 2 ^ 0xc0);
			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
					: (byte) ((b2) >> 4 ^ 0xf0);
			byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6)
					: (byte) ((b3) >> 6 ^ 0xfc);

			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
			encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
			encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
			encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
		}

		// form integral number of 6-bit groups
		if (fewerThan24bits == EIGHTBIT) {
			b1 = binaryData[dataIndex];
			k = (byte) (b1 & 0x03);
			
			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
					: (byte) ((b1) >> 2 ^ 0xc0);
			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
			encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
			encodedData[encodedIndex++] = PAD;
			encodedData[encodedIndex++] = PAD;
		} else if (fewerThan24bits == SIXTEENBIT) {
			b1 = binaryData[dataIndex];
			b2 = binaryData[dataIndex + 1];
			l = (byte) (b2 & 0x0f);
			k = (byte) (b1 & 0x03);

			byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2)
					: (byte) ((b1) >> 2 ^ 0xc0);
			byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4)
					: (byte) ((b2) >> 4 ^ 0xf0);

			encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
			encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
			encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
			encodedData[encodedIndex++] = PAD;
		}

		return new String(encodedData);
	}

	/**
	 * Decodes Base64 data into octects
	 * 
	 * @param encoded
	 *            string containing Base64 data
	 * @return Array containind decoded data.
	 */
	public static byte[] decode(String encoded) {

		if (encoded == null) {
			return null;
		}

		char[] base64Data = encoded.toCharArray();
		// remove white spaces
		int len = removeWhiteSpace(base64Data);

		if (len % FOURBYTE != 0) {
			return null;// should be divisible by four
		}

		int numberQuadruple = (len / FOURBYTE);

		if (numberQuadruple == 0) {
			return new byte[0];
		}

		byte decodedData[] = null;
		byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
		char d1 = 0, d2 = 0, d3 = 0, d4 = 0;

		int i = 0;
		int encodedIndex = 0;
		int dataIndex = 0;
		decodedData = new byte[(numberQuadruple) * 3];

		for (; i < numberQuadruple - 1; i++) {

			if (!isData((d1 = base64Data[dataIndex++]))
					|| !isData((d2 = base64Data[dataIndex++]))
					|| !isData((d3 = base64Data[dataIndex++]))
					|| !isData((d4 = base64Data[dataIndex++]))) {
				return null;
			}// if found "no data" just return null

			b1 = base64Alphabet[d1];
			b2 = base64Alphabet[d2];
			b3 = base64Alphabet[d3];
			b4 = base64Alphabet[d4];

			decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
			decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
			decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
		}

		if (!isData((d1 = base64Data[dataIndex++]))
				|| !isData((d2 = base64Data[dataIndex++]))) {
			return null;// if found "no data" just return null
		}

		b1 = base64Alphabet[d1];
		b2 = base64Alphabet[d2];

		d3 = base64Data[dataIndex++];
		d4 = base64Data[dataIndex++];
		if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
			if (isPad(d3) && isPad(d4)) {
				if ((b2 & 0xf) != 0)// last 4 bits should be zero
				{
					return null;
				}
				byte[] tmp = new byte[i * 3 + 1];
				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
				tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
				return tmp;
			} else if (!isPad(d3) && isPad(d4)) {
				b3 = base64Alphabet[d3];
				if ((b3 & 0x3) != 0)// last 2 bits should be zero
				{
					return null;
				}
				byte[] tmp = new byte[i * 3 + 2];
				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
				tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
				tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
				return tmp;
			} else {
				return null;
			}
		} else { // No PAD e.g 3cQl
			b3 = base64Alphabet[d3];
			b4 = base64Alphabet[d4];
			decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
			decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
			decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);

		}

		return decodedData;
	}

	/**
	 * remove WhiteSpace from MIME containing encoded Base64 data.
	 * 
	 * @param data
	 *            the byte array of base64 data (with WS)
	 * @return the new length
	 */
	private static int removeWhiteSpace(char[] data) {
		if (data == null) {
			return 0;
		}

		// count characters that's not whitespace
		int newSize = 0;
		int len = data.length;
		for (int i = 0; i < len; i++) {
			if (!isWhiteSpace(data[i])) {
				data[newSize++] = data[i];
			}
		}
		return newSize;
	}
}

RSA加密解密代码:

package com.unj;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import android.util.Log;

public class RSAUtil {
	private static final String TAG = "RSALoger";

	public static void log(String msg) {
		Log.i(TAG, msg);
	}

	/**
	 * 初始化密钥,秘钥生成有两种方式,一是用代码(即下面的这个方法)生成,二是用openSSL工具生成,一般用第二种
	 * 
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> initKey() throws Exception {
		KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
		keyPairGen.initialize(1024);

		KeyPair keyPair = keyPairGen.generateKeyPair();

		// 公钥
		RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

		// 私钥
		RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

		Map<String, Object> keyMap = new HashMap<String, Object>(2);

		keyMap.put("publicKey", publicKey);
		keyMap.put("privateKey", privateKey);
		return keyMap;
	}


	/**
	 * 通过私钥字符串得到私钥
	 * 
	 * @param key
	 *            密钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(String key) throws Exception {
		log("str_privateKey from str:" + key);
		byte[] keyBytes;

		keyBytes = Base64.decode(key);

		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

		KeyFactory keyFactory = KeyFactory.getInstance("RSA");

		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		log("privateKey :" + privateKey.toString());
		return privateKey;
	}

	/**
	 * 通过输入流得到私钥,可用于读取文件
	 * 
	 * @param in
	 *            输入流
	 * @throws Exception
	 */
	public static PrivateKey getPrivateKey(InputStream in) throws Exception {
		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');
			}
		}

		String strPrivate = sb.toString();
		log("str_privateKey from inputStream :" + strPrivate);

		byte[] keyBytes = Base64.decode(strPrivate);

		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);

		KeyFactory keyFactory = KeyFactory.getInstance("RSA");

		PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
		log("privateKey :" + privateKey.toString());
		return privateKey;
	}

	/**
	 * 通过公钥字符串得到公钥
	 * 
	 * @param key
	 *            公钥字符串(经过base64编码)
	 * @throws Exception
	 */
	public static PublicKey getPublicKey(String key) throws Exception {
		log("str_PublicKey from str :" + key);
		byte[] keyBytes = Base64.decode(key);

		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

		KeyFactory keyFactory = KeyFactory.getInstance("RSA");

		PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
		log("publicKey :" + publicKey.toString());
		return publicKey;
	}

	/**
	 * 通过输入流得到公钥,可用于读取文件
	 * 
	 * @param in
	 *            输入流
	 * @throws Exception
	 */
	public static PublicKey getPublicKey(InputStream in) throws Exception {

		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');
			}
		}

		String strPublic = sb.toString();
		log("str_PublicKey from inputStream :" + strPublic);
		byte[] keyBytes = Base64.decode(strPublic);

		X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);

		KeyFactory keyFactory = KeyFactory.getInstance("RSA");

		PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
		log("publicKey :" + publicKey.toString());
		return publicKey;
	}

	/**
	 * 用私钥对信息进行数字签名
	 * 
	 * @param content
	 *            待签名数据(即加密后的数据)
	 * @param privateKey
	 *            商户私钥
	 * @param input_charset
	 *            编码格式
	 * @return 签名值
	 */
	public static String sign(String content, PrivateKey privateKey,
			String input_charset) {
		try {
			java.security.Signature signature = java.security.Signature
					.getInstance("SHA1WithRSA");

			signature.initSign(privateKey);
			signature.update(content.getBytes(input_charset));

			byte[] signed = signature.sign();
			log("use privatekey signed :"+Base64.encode(signed));
			return Base64.encode(signed);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * RSA 用公钥校验数字签名
	 * 
	 * @param content
	 *            待签名数据(即加密后的数据)
	 * @param sign
	 *            签名值(即签名后的数据)
	 * @param PublicKey
	 *            公钥
	 * @param input_charset
	 *            编码格式
	 * @return 布尔值
	 */
	public static boolean verify(String content, String sign,
			PublicKey publicKey, String input_charset) {
		try {
			java.security.Signature signature = java.security.Signature
					.getInstance("SHA1WithRSA");

			signature.initVerify(publicKey);
			signature.update(content.getBytes(input_charset));

			boolean bverify = signature.verify(Base64.decode(sign));
			log("use publickey verify result :"+bverify);
			return bverify;

		} catch (Exception e) {
			e.printStackTrace();
		}

		return false;
	}

	/**
	 * 用私钥加密
	 * 
	 * @param data
	 *            待加密字符串
	 * @param privateKey
	 *            私钥
	 * @return 加密后的字符串
	 * @throws Exception
	 */
	public static String encryptByPrivateKey(String content,
			PrivateKey privateKey, String input_charset) throws Exception {

		// 对数据加密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, privateKey);

		InputStream ins = new ByteArrayInputStream(
				content.getBytes(input_charset));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
		byte[] buf = new byte[128];
		int bufl;

		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;

			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}

			writer.write(cipher.doFinal(block));
		}

		// return new String(writer.toByteArray(), input_charset);
		log("privatekey encrypted :"+Base64.encode(writer.toByteArray()));
		return Base64.encode(writer.toByteArray());
	}


	/**
	 * 用公钥加密
	 * 
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptByPublicKey(String content,
			PublicKey publicKey, String input_charset) throws Exception {

		// 对密钥解密
		// byte[] keyBytes = Base64.decode(public_key);
		//
		// // 取得公钥
		// X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
		// KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		// PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);

		// 对数据加密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);

		InputStream ins = new ByteArrayInputStream(
				content.getBytes(input_charset));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
		byte[] buf = new byte[128];
		int bufl;

		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;

			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}

			writer.write(cipher.doFinal(block));
		}

		// return new String( writer.toByteArray(), input_charset);
		log("privatekey encrypted :"+Base64.encode(writer.toByteArray()));
		return Base64.encode(writer.toByteArray());
	}

	/**
	 * 用私钥解密
	 * 
	 * @param content
	 *            密文
	 * @param privateKey
	 *            私钥
	 * @param input_charset
	 *            编码格式
	 * @return 解密后的字符串
	 */
	public static String decryptByPrivateKey(String content,
			PrivateKey privateKey, String input_charset) throws Exception {
		// PrivateKey prikey = getPrivateKey(private_key);

		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, privateKey);

		InputStream ins = new ByteArrayInputStream(Base64.decode(content));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
		byte[] buf = new byte[128];
		int bufl;

		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;

			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}

			writer.write(cipher.doFinal(block));
		}

		log("publickey decrypted :"+new String(writer.toByteArray(), input_charset));
		return new String(writer.toByteArray(), input_charset);
	}

	/**
	 * 用公钥解密
	 * 
	 * @param content
	 *            密文
	 * @param public_key
	 *            商户公钥
	 * @param input_charset
	 *            编码格式
	 * @return 解密后的字符串
	 * @throws Exception
	 */
	public static String decryptByPublicKey(String content,
			PublicKey publicKey, String input_charset) throws Exception {

		// 对数据解密
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.DECRYPT_MODE, publicKey);

		InputStream ins = new ByteArrayInputStream(Base64.decode(content));
		ByteArrayOutputStream writer = new ByteArrayOutputStream();
		// rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密
		byte[] buf = new byte[128];
		int bufl;

		while ((bufl = ins.read(buf)) != -1) {
			byte[] block = null;

			if (buf.length == bufl) {
				block = buf;
			} else {
				block = new byte[bufl];
				for (int i = 0; i < bufl; i++) {
					block[i] = buf[i];
				}
			}

			writer.write(cipher.doFinal(block));
		}
		log("publickey decrypted :"+new String(writer.toByteArray(), input_charset));
		return new String(writer.toByteArray(), input_charset);
	}
}


RSA测试类:

package com.unj;

import java.io.IOException;
import java.io.InputStream;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.unj.rsademo.R;

public class RSAActivity extends Activity implements OnClickListener {

	EditText etxt;
	TextView txtJiamiqian;
	TextView txtJiamihou;
	TextView txtJiemihou;
	TextView txtQianminghou;
	TextView txtQianmingyangzheng;

	String strDaijiami = "";
	String strJiamihou = "";
	String strJiemihou = "";
	String strQianminghou = "";
	boolean bolQianming = false;
	boolean isUseStr = false;

	public static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALZVV2DIk03lTSJq"
			+ "YFiJRVaMIXVK9m768TV3Z5FtPxADcKYsFqNIic2Ne5xRyOJh9kXsR2S3j+iPNY4y"
			+ "8OhOtIrE+r3mr/4p5phA1TDqMbzcg1W6ZADJ8twiQfxfBKzP/7oSD0qD7CUtPCxb"
			+ "vZMHmylizlhtiMJPL38TYDhzsypxAgMBAAECgYEAqr1711u75QPGmWW31vCkh4kt"
			+ "g6Kw5fgDjCfGSj5dAWfXQySiBkFVGbFVgWpsjOFjNtMtf7kM/5+rbP9y7HdXQ84W"
			+ "oWAWg2L3LXyqqtqCMvz9qs/h23IgF+QpV1/mZ3PAZ4WmkVS8cvMFEmG6feLXq9C0"
			+ "CIRin9zE4eRFu72P9AECQQDlgjSjfwWHd+GDA9TNyged47Knr2whMI1pD+iVmDOu"
			+ "45d88yhRswAA5G0Mmz1anps3xuqSydLM82We3yLdOJqhAkEAy2ElJTlql20I+Bmp"
			+ "LVyY8NUMdjDiKgzGjxNpNDaF0XHaOYv/pJ8DOFb1DONqIpjuRqlABGWZdHMEgFxo"
			+ "vmrN0QJARcUOYYGU2bjc6mo4wBKhvCLjRcyzT2emJYE7kHaDh7ASdl6pLCUBZEQM"
			+ "zp9GyIyc3RjwaI1IMxvvEZv9ykiR4QJAb9+GIU3OFnHB50emSe+PqZpn+nO1VNAm"
			+ "QPm6eyAqyCVKlzEtdI6LpOggb/CAp3tcRr4/GqwQl3/VUA6FB4mUoQJBALlug+oI"
			+ "cW1WuHTevhYmwwSCdxbzrZPkmKb8xd9/ycCPcZf+htZHOddjKIYDo+fqQhZMPIwa"
			+ "8snN/pEqxioHvdo=";//rsa_private_key_pkcs8.txt里面的字符串

	public static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2VVdgyJNN5U0iamBYiUVWjCF1"
			+ "SvZu+vE1d2eRbT8QA3CmLBajSInNjXucUcjiYfZF7Edkt4/ojzWOMvDoTrSKxPq9"
			+ "5q/+KeaYQNUw6jG83INVumQAyfLcIkH8XwSsz/+6Eg9Kg+wlLTwsW72TB5spYs5Y"
			+ "bYjCTy9/E2A4c7MqcQIDAQAB";//rsa_public_key.pem里面的字符串

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.rsa_activity);
		etxt = (EditText) this.findViewById(R.id.daijiami);

		txtJiamiqian = (TextView) this.findViewById(R.id.jiamiqian);
		txtJiamihou = (TextView) this.findViewById(R.id.jiamihou);
		txtJiemihou = (TextView) this.findViewById(R.id.jiemihou);
		txtQianminghou = (TextView) this.findViewById(R.id.qianminghou);
		txtQianmingyangzheng = (TextView) this
				.findViewById(R.id.qianmingjieguo);
	}

	@Override
	public void onClick(View v) {
		strDaijiami = etxt.getText().toString().trim();
		if (strDaijiami == null || "".equals(strDaijiami)) {
			showToast("请输入待加密的字符串");
			return;
		}
		switch (v.getId()) {
		case R.id.reset:
			strDaijiami = "";
			strJiamihou = "";
			strJiemihou = "";
			strQianminghou = "";
			bolQianming = false;
			break;
		case R.id.sijia:
			try {
				PrivateKey privatekey = (PrivateKey) getKey(isUseStr, true);
				strJiamihou = RSAUtil.encryptByPrivateKey(strDaijiami,
						privatekey, "utf-8");
				System.out.println(strJiamihou);
			} catch (Exception e) {
				showToast("私钥加密失败" + e.getMessage());
				e.printStackTrace();
			}
			break;
		case R.id.gongjia:
			try {
				PublicKey publickey = (PublicKey) getKey(isUseStr, false);
				strJiamihou = RSAUtil.encryptByPublicKey(strDaijiami,
						publickey, "utf-8");
				System.out.println(strJiamihou);
			} catch (Exception e) {
				showToast("公钥加密失败");
				e.printStackTrace();
			}
			break;
		case R.id.sijie:
			try {
				PrivateKey privateKey = (PrivateKey) getKey(isUseStr, true);
				strJiemihou = RSAUtil.decryptByPrivateKey(strJiamihou,
						privateKey, "utf-8");
				System.out.println(strJiemihou);
			} catch (Exception e) {
				showToast("私钥解密失败");
				e.printStackTrace();
			}
			break;
		case R.id.gongjie:
			try {
				PublicKey publickey = (PublicKey) getKey(isUseStr, false);
				strJiemihou = RSAUtil.decryptByPublicKey(strJiamihou,
						publickey, "utf-8");
				System.out.println(strJiemihou);
			} catch (Exception e) {
				showToast("公钥解密失败");
				e.printStackTrace();
			}
			break;
		case R.id.siqian:// 私钥签名
			PrivateKey privateKey = (PrivateKey) getKey(isUseStr, true);
			strQianminghou = RSAUtil.sign(strJiamihou, privateKey, "utf-8");
			System.out.println(strQianminghou);
			break;
		case R.id.gongqian:// 公钥签名
			// PublicKey publickey = (PublicKey) getKey(isUseStr, false);
			// strQianminghou = RSAUtil.sign(strJiamihou, publickey, "utf-8");
			// System.out.println(strQianminghou);
			showToast("公钥不能用于签名");
			break;
		case R.id.siyan:// 私钥验证签名
			// bolQianming = RSAUtil.verify(strJiamihou, strQianminghou,
			// PRIVATE_KEY, "utf-8");
			// System.out.println(bolQianming);
			showToast("私钥不能用于验证签名");
			break;
		case R.id.gongyan:// 公钥验证签名
			PublicKey publickey = (PublicKey) getKey(isUseStr, false);
			bolQianming = RSAUtil.verify(strJiamihou, strQianminghou,
					publickey, "utf-8");
			System.out.println(bolQianming);
			break;

		default:
			break;
		}
		txtJiamiqian.setText(getString(R.string.jiami_qian, strDaijiami));
		txtJiamihou.setText(getString(R.string.jiami_hou, strJiamihou));
		txtJiemihou.setText(getString(R.string.jiemi_hou, strJiemihou));
		txtQianminghou
				.setText(getString(R.string.qianming_hou, strQianminghou));
		txtQianmingyangzheng.setText(bolQianming ? "签名验证结果:验证成功"
				: "签名验证结果:验证失败");

	}

	public void showToast(String message) {
		Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
	}

	private Key getKey(boolean isUseStr, boolean isGetPrivateKey) {
		PrivateKey privatekey = null;
		PublicKey publickey = null;
		if (isUseStr) {
			if (isGetPrivateKey) {
				try {
					privatekey = RSAUtil.getPrivateKey(PRIVATE_KEY);
					return privatekey;
				} catch (Exception e) {
					e.printStackTrace();
				}

			} else {
				try {
					publickey = RSAUtil.getPublicKey(PUBLIC_KEY);
					return publickey;
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} else {
			if (isGetPrivateKey) {
				InputStream inPrivate;
				try {
					inPrivate = getResources().getAssets().open(
							"rsa_private_key_pkcs8.txt");
					privatekey = RSAUtil.getPrivateKey(inPrivate);
					return privatekey;
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else {
				InputStream inpublic;
				try {
					inpublic = getResources().getAssets().open(
							"rsa_public_key.pem");
					publickey = RSAUtil.getPublicKey(inpublic);
					return publickey;
				} catch (IOException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

}


demo运行结果:



demo下载地址:http://download.csdn.net/detail/u012049463/8299171


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值