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的文件。具体如下图:
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运行结果: