RSA是目前最有影响力的公钥加密算法,是一种非对称加密算法。随机产生一对公钥和私钥,解密者拥有私钥,并且将由私钥计算生成的公钥发布给加密者。加密都使用公钥进行加密,并将密文发送到解密者,解密者用私钥解密将密文解码为明文。
下面是一个工具类,可以直接使用。
package com.example.RsaCode;
import android.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* Created with IntelliJ IDEA.
* User: zhangmin
* Module: Contacts
* Date: 14-5-26
* Time: 下午2:05
*/
public class RSACodeHelper {
public RSAPublicKey mPublicKey;
public RSAPrivateKey mPrivateKey;
public void initKey() {
KeyPairGenerator keyPairGen = null;
try {
//设置使用何种加密算法
keyPairGen = KeyPairGenerator.getInstance("RSA");
// 密钥位数
keyPairGen.initialize(512);
// 密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
mPublicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
mPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
/****************************************
* 函数说明:getPublicKey 取得公钥
*
* @param key 公钥字符串
* @throws Exception
* @return PublicKey 返回公钥
* @author zhangmin
***************************************/
public static PublicKey getPublicKey(String key) throws Exception
{
byte[] keyBytes = base64Dec(key);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
/****************************************
* 函数说明:getPrivateKey 取得私钥
*
* @param key 私钥字符串
* @throws Exception
* @return PrivateKey 返回私钥
* @author zhangmin
***************************************/
public static PrivateKey getPrivateKey(String key) throws Exception
{
byte[] keyBytes = base64Dec(key);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public String encrypt(String passwd) {
String strEncrypt = null;
try {
// 实例化加解密类
Cipher cipher = Cipher.getInstance("RSA");
// 明文
byte[] plainText = passwd.getBytes();
// 加密
cipher.init(Cipher.ENCRYPT_MODE, mPublicKey);
//将明文转化为根据公钥加密的密文,为byte数组格式
byte[] enBytes = cipher.doFinal(plainText);
//为了方便传输我们可以将byte数组转化为base64的编码
strEncrypt = base64Enc(enBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InvalidKeyException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (BadPaddingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (NoSuchAlgorithmException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (NoSuchPaddingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
return strEncrypt;
}
}
public String decrypt(String encString) {
Cipher cipher = null;
String strDecrypt = null;
try {
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, mPrivateKey);
//先将转为base64编码的加密后的数据转化为byte数组
byte[] enBytes = base64Dec(encString);
//解密称为byte数组,应该为字符串数组最后转化为字符串
byte[] deBytes = cipher.doFinal(enBytes);
strDecrypt = new String(deBytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (NoSuchPaddingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (BadPaddingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (IllegalBlockSizeException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} catch (InvalidKeyException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
return strDecrypt;
}
}
//base64编码
public static String base64Enc(byte[] enBytes) {
return Base64.encodeToString(enBytes, Base64.DEFAULT);
}
//base64解码
public static byte[] base64Dec(String str) {
return Base64.decode(str, Base64.DEFAULT);
}
}
//初始化工作
mRSAHelper = new RSACodeHelper();
mRSAHelper.initKey();
//公钥加密密码后的字符串
String encryptString = mRSAHelper.encrypt(mEditText.getText().toString());
//私钥解密,还原密码
String password = mRSAHelper.decrypt(encryptString);
一般实际使用过程中需要将公钥和私钥转换成 base64的编码,然后再存储到sqlite数据库中,这样就有一个String转换成PrivateKey 或 PublicKey的过程,这里主要就用到了上面代码中的两个函数:
public static PublicKey getPublicKey(String key) throws Exception
public static PrivateKey getPrivateKey(String key) throws Exception
调用方法:
存储公钥:String strPublicKey = base64Enc(mPublicKey.getEncoded())
存储私钥:String strPrivateKey = base64Enc(mPrivateKey.getEncoded())
还原公钥:RSAPublicKey publicKey = (RSAPublicKey)getPublicKey(strPublicKey);
还原私钥:RSAPrivateKey privateKey = (RSAPrivateKey)getPrivateKey(strPrivateKey );
更强悍的使用方法:密码用MD5加密,再用明文密码给私钥用AES加密,解密也就需要明文密码,真正的数据文件用RSA加密解密。