在做项目时,一些重要的数据用到了加密,记录下系统提供的这几种常见的加密数据方式的使用(不是原理):
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。
密钥长度可以是128,192或256比特,也就是16,24或32位字节
密钥向量长度只能是8位字节
注:这里默认使用的是填充方式pkcs5padding
/**
* 加解密方式
*/
enum Encryption {
AES, // Key length must 16/24/32 bytes IV length must 16 bytes
DES, // Key、IV 8 bytes
DES3 // Key 16 or 24 bytes. IV 8 bytes
}
/**
* 加解密模式
*/
enum EncryptMode {
ECB,
CBC,
CTR,
OFB,
CFB
}
/**
* 先AES 加密,再通过Base64加密
* @param str 需要加密的字符串
* @param strKey 加密的密钥key
* @param strIv 加密的向量iv
* @param mode 加密模式ECB
* 模式的填充方式的 PKCS5Padding
* 需要Padding的有:CBC(,PCBC也需要,本文未涉及该加密模式)、ECB。
不需要Padding的有:CFB、OFB、CTR
* @return
*/
public static String AesDesEncrypt(String str,String strKey,String strIv,Encryption encryption,EncryptMode mode){
if (TextUtils.isEmpty(str) || TextUtils.isEmpty(strKey))
return null;
String strMode = null;
String strEncryption = null;
switch (encryption){
case AES:
strEncryption = "AES";
break;
case DES:
strEncryption = "DES";
break;
case DES3:
strEncryption = "DESede";
break;
}
switch (mode){
case ECB:
return EcbEncrypt(str,strKey,strEncryption);
case CBC:
strMode = "CBC";
break;
case CTR:
strMode = "CTR";
break;
case OFB:
strMode = "OFB";
break;
case CFB:
strMode = "CFB";
break;
default:
return null;
}
if(TextUtils.isEmpty(strIv))
return null;
try {
byte[] raw = strKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, strEncryption);
Cipher cipher = Cipher.getInstance(String.format("%s/%s/PKCS5Padding",strEncryption,strMode));
IvParameterSpec iv = new IvParameterSpec(strIv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encryptBytes = cipher.doFinal(str.getBytes());
return Base64.encodeToString(encryptBytes, Base64.NO_WRAP);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* ECB方式加密
* @return
*/
private static String EcbEncrypt(String str,String key,String encryption){
try {
Cipher cipher = Cipher.getInstance(String.format("%s/ECB/pkcs5padding",encryption));
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), encryption));
byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
return Base64.encodeToString(bytes, Base64.NO_WRAP); //注 Base64.DEFAULT 加密后有\n
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 先通过Base64解密,再AES 解密
* @param str 需要解密的字符串
* @param strKey 解密的密钥key
* @param strIv 解密的向量iv
* @param mode 解密模式ECB
* 模式的填充方式的 PKCS5Padding
* @return
*/
public static String AesDesDecrypt(String str,String strKey,String strIv,Encryption encryption,EncryptMode mode){
if (TextUtils.isEmpty(str) || TextUtils.isEmpty(strKey))
return null;
String strMode = null;
String strEncryption = null;
switch (encryption){
case AES:
strEncryption = "AES";
break;
case DES:
strEncryption = "DES";
break;
case DES3:
strEncryption = "DESede";
break;
}
switch (mode){
case ECB:
return EcbDecrypt(str,strKey,strEncryption);
case CBC:
strMode = "CBC";
break;
case CTR:
strMode = "CTR";
break;
case OFB:
strMode = "OFB";
break;
case CFB:
strMode = "CFB";
break;
default:
return null;
}
if(TextUtils.isEmpty(strIv))
return null;
try {
byte[] raw = strKey.getBytes();
SecretKeySpec skeySpec = new SecretKeySpec(raw, strEncryption);
Cipher cipher = Cipher.getInstance(String.format("%s/%s/PKCS5Padding",strEncryption,strMode));
IvParameterSpec iv = new IvParameterSpec(strIv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decryptBytes = cipher.doFinal(Base64.decode(str.getBytes("utf-8"), Base64.NO_WRAP));
return new String(decryptBytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* ECB方式解密
* @return
*/
private static String EcbDecrypt(String str,String key,String encryption){
try {
Cipher cipher = Cipher.getInstance(String.format("%s/ECB/PKCS5Padding",encryption));
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), encryption));
byte[] bytes = cipher.doFinal(Base64.decode(str.getBytes("utf-8"), Base64.NO_WRAP));
return new String(bytes, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
注:密钥key和向量IV随机输入的,也可以代码随机生成
/**
* AES 加密的密钥key 和向量 iv
* Key 长度 16/24/32 bytes IV 长度 16 bytes
*/
private String AES_KEY = "adjiganaadjigana";
private String AES_IV = "adjiganaadjigana";
/**
* DES 加密的密钥key 和向量 iv
* 密钥和向量长度 必须为8
*/
private String DES_KEY = "adjigana";
private String DES_IV = "adjigana";
/**
* DES3 加密的密钥key 和向量 iv
* key 长度 16 or 24 bytes. 必须为8
*/
private String DES3_KEY = "asdjdsgnasgeaeesiaskdfje";
private String DES3_IV = "adjigana";
/**
* 测试原数据 AES DES DES3
*/
private String strTestData = "MainActivity";
Log.e("test","----------- :" + "加密结果 " + " 解密结果 ");
//Key length must 128/192/256 bits IV length must 16 bytes
String AesEncryptECB = EncryUtils.AesDesEncrypt(strTestData,AES_KEY,"",EncryUtils.Encryption.AES, EncryUtils.EncryptMode.ECB);
Log.e("test","AES ----- ECB:"+ AesEncryptECB + " " + EncryUtils.AesDesDecrypt(AesEncryptECB,AES_KEY,"", EncryUtils.Encryption.AES,EncryUtils.EncryptMode.ECB));
String AesEncryptCBC = EncryUtils.AesDesEncrypt(strTestData,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.CBC);
Log.e("test","AES ----- CBC:"+ AesEncryptCBC + " " + EncryUtils.AesDesDecrypt(AesEncryptCBC,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.CBC));
String AesEncryptCFB = EncryUtils.AesDesEncrypt(strTestData,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.CFB);
Log.e("test","AES ----- CFB:"+ AesEncryptCFB + " " + EncryUtils.AesDesDecrypt(AesEncryptCFB,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.CFB));
String AesEncryptCTR = EncryUtils.AesDesEncrypt(strTestData,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.CTR);
Log.e("test","AES ----- CTR:"+ AesEncryptCTR + " " + EncryUtils.AesDesDecrypt(AesEncryptCTR,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.CTR));
String AesEncryptOFB = EncryUtils.AesDesEncrypt(strTestData,AES_KEY,AES_IV,EncryUtils.Encryption.AES, EncryUtils.EncryptMode.OFB);
Log.e("test","AES ----- OFB:"+ AesEncryptOFB + " " + EncryUtils.AesDesDecrypt(AesEncryptOFB,AES_KEY,AES_IV, EncryUtils.Encryption.AES,EncryUtils.EncryptMode.OFB));
String DesEncryptECB = EncryUtils.AesDesEncrypt(strTestData,DES_KEY,"",EncryUtils.Encryption.DES, EncryUtils.EncryptMode.ECB);
Log.e("test","DES ----- ECB:"+ DesEncryptECB + " " + EncryUtils.AesDesDecrypt(DesEncryptECB,DES_KEY,"", EncryUtils.Encryption.DES,EncryUtils.EncryptMode.ECB));
String DesEncryptCBC = EncryUtils.AesDesEncrypt(strTestData,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.CBC);
Log.e("test","DES ----- CBC:"+ DesEncryptCBC + " " + EncryUtils.AesDesDecrypt(DesEncryptCBC,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.CBC));
String DesEncryptCFB = EncryUtils.AesDesEncrypt(strTestData,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.CFB);
Log.e("test","DES ----- CFB:"+ DesEncryptCFB + " " + EncryUtils.AesDesDecrypt(DesEncryptCFB,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.CFB));
String DesEncryptCTR = EncryUtils.AesDesEncrypt(strTestData,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.CTR);
Log.e("test","DES ----- CTR:"+ DesEncryptCTR + " " + EncryUtils.AesDesDecrypt(DesEncryptCTR,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.CTR));
String DesEncryptOFB = EncryUtils.AesDesEncrypt(strTestData,DES_KEY,DES_IV,EncryUtils.Encryption.DES, EncryUtils.EncryptMode.OFB);
Log.e("test","DES ----- OFB:"+ DesEncryptOFB + " " + EncryUtils.AesDesDecrypt(DesEncryptOFB,DES_KEY,DES_IV, EncryUtils.Encryption.DES,EncryUtils.EncryptMode.OFB));
String Des3EncryptECB = EncryUtils.AesDesEncrypt(strTestData,DES3_KEY,"",EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.ECB);
Log.e("test","DES3----- ECB:"+ Des3EncryptECB + " " + EncryUtils.AesDesDecrypt(Des3EncryptECB,DES3_KEY,"", EncryUtils.Encryption.DES3,EncryUtils.EncryptMode.ECB));
String Des3EncryptCBC = EncryUtils.AesDesEncrypt(strTestData,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.CBC);
Log.e("test","DES3----- CBC:"+ Des3EncryptCBC + " " + EncryUtils.AesDesDecrypt(Des3EncryptCBC,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.CBC));
String Des3EncryptCFB = EncryUtils.AesDesEncrypt(strTestData,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.CFB);
Log.e("test","DES3----- CFB:"+ Des3EncryptCFB + " " + EncryUtils.AesDesDecrypt(Des3EncryptCFB,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.CFB));
String Des3EncryptCTR = EncryUtils.AesDesEncrypt(strTestData,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.CTR);
Log.e("test","DES3----- CTR:"+ Des3EncryptCTR + " " + EncryUtils.AesDesDecrypt(Des3EncryptCTR,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.CTR));
String Des3EncryptOFB = EncryUtils.AesDesEncrypt(strTestData,DES3_KEY,DES3_IV,EncryUtils.Encryption.DES3, EncryUtils.EncryptMode.OFB);
Log.e("test","DES3----- OFB:"+ Des3EncryptOFB + " " + EncryUtils.AesDesDecrypt(Des3EncryptOFB,DES3_KEY,DES3_IV, EncryUtils.Encryption.DES3,EncryUtils.EncryptMode.OFB));
//结果打印:
----------- :加密结果 解密结果
AES ----- ECB:+fm/DlMcKrTzXsI6K8K7DQ== MainActivity
AES ----- CBC:RLUOIuFLn9Zni1hX5IsYEQ== MainActivity
AES ----- CFB:XWAyrMAJTf85G/cbG/boWg== MainActivity
AES ----- CTR:XWAyrMAJTf85G/cbG/boWg== MainActivity
AES ----- OFB:XWAyrMAJTf85G/cbG/boWg== MainActivity
DES ----- ECB:0+EYSR8mKeLmcCc/EwBnEw== MainActivity
DES ----- CBC:wjlJm8sXFOVBdKEmYpVMdA== MainActivity
DES ----- CFB:A7BTeblDVsLJLU0HHQV7WA== MainActivity
DES ----- CTR:A7BTeblDVsJQ3pKy2fp7FA== MainActivity
DES ----- OFB:A7BTeblDVsKRzzVhqB0djA== MainActivity
DES3----- ECB:eCGQso2m9erT3oCsWQgQ8w== MainActivity
DES3----- CBC:qHYReGQi3uTr7ZOyaxjj/w== MainActivity
DES3----- CFB:pmtnb3L7IbrYP1bu4qdWmg== MainActivity
DES3----- CTR:pmtnb3L7IbqzXwIZ0gzpeQ== MainActivity
DES3----- OFB:pmtnb3L7IbrtZBB1H5No3Q== MainActivity
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年首次公布,当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。
今天只有短的RSA钥匙才可能被强力方式解破。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战。
RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
通过以下代码生成或者在这个工具网http://web.chacuo.net/netrsakeypair
/**
* 生成RSA key
* 网上生成密钥对 http://web.chacuo.net/netrsakeypair
*/
private void createRsaKey(){
try {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//密钥位数
keyPairGen.initialize(1024);
//密钥对
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
PublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
PrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
String publicKeyString = getKeyString(publicKey);
Log.e("test","--------- public:\n" + publicKeyString);
String privateKeyString = getKeyString(privateKey);
Log.e("test","--------- private:\n" + privateKeyString);
Log.e("test","------ Public Modulus :" + ((RSAPublicKey)publicKey).getModulus().toString(16));
Log.e("test","------ Public Exponent :" + ((RSAPublicKey)publicKey).getPublicExponent());
Log.e("test","------ private Modulus :" + ((RSAPrivateKey)privateKey).getModulus().toString(16));
Log.e("test","------ private Exponent :" + ((RSAPrivateKey)privateKey).getPrivateExponent().toString(16));
} catch (Exception e) {
e.printStackTrace();
}
}
//结果输出
--------- public:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDZxEp9h5xf6tm6M3PDoY3z2iY6mN0NY1vxh6moO1TmNtyBqThoEU8mrYu/9SAqNiWxdb3s5XTXI/zPnZCuHPHpfeO2L2BuA0IU3vtKlOUaYltPURoH5rsTBOqgF+i5nZSCoP9SqLdzq7aVrpYJcqpGj2PtgOx+9NpZ9agkOFjr6wIDAQAB
--------- private:
MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBANnESn2HnF/q2bozc8OhjfPaJjqY3Q1jW/GHqag7VOY23IGpOGgRTyati7/1ICo2JbF1vezldNcj/M+dkK4c8el947YvYG4DQhTe+0qU5RpiW09RGgfmuxME6qAX6LmdlIKg/1Kot3OrtpWulglyqkaPY+2A7H702ln1qCQ4WOvrAgMBAAECgYEAoo07bWiE+bQ8whkWGLnHVHdKggMJPq0kPK6fncxsG0xoXQEL8eK5yo1Q/ADl+Zxhlo3lL6g4Bz/9vpxHGzDQAbIZmNuvbUKkNN8KfQ8wmlcmLP4f/4B8NIog4rY4n728vcra/Pgo3pUiFhsA3IIoecTDsuiIeSzr8C7khHbrdkECQQD0fFhksVvT7Qhn/Fl7Y+vS+4LMFlGSYKZC4+KJFuzcW884eb3bdduGV2fMfRlVbRMPJqP41qF/8OiSjyJXIljfAkEA5AXOoVILLsfCY9NMOrcYVNhjYDtHTY1DfQwoUQKqhLREAnPfo3yr39+kyv5mB7HbOUA4LXkzNVXNg/p4gU1ydQJBAM0DaGwnfcVcwuvP5Ilf5OTrG2dgX87LVSBKUDB9FOpD4qSNEfPyBL/Gk7gaPyAvcwgFcwK7mHnc3mnntPg0SSkCQQC4DgfwJ21nYU8DjPcnHcvCELiGYNL5QmGLeljAq0pAu9F5uVZ3fJavqrI2OIrbAzFVUQUHj6FKF+w/79l9ZapRAkEAozb1xksXzax9qTx5NTrz5brxmCq53ymf8dI0NRFF+PHM4iey50ymroJswmlU6uflej6mv6G+Klecta+u4QQRvA==
------ Public Modulus :d9c44a7d879c5fead9ba3373c3a18df3da263a98dd0d635bf187a9a83b54e636dc81a93868114f26ad8bbff5202a3625b175bdece574d723fccf9d90ae1cf1e97de3b62f606e034214defb4a94e51a625b4f511a07e6bb1304eaa017e8b99d9482a0ff52a8b773abb695ae960972aa468f63ed80ec7ef4da59f5a8243858ebeb
------ Public Exponent :65537
------ private Modulus :d9c44a7d879c5fead9ba3373c3a18df3da263a98dd0d635bf187a9a83b54e636dc81a93868114f26ad8bbff5202a3625b175bdece574d723fccf9d90ae1cf1e97de3b62f606e034214defb4a94e51a625b4f511a07e6bb1304eaa017e8b99d9482a0ff52a8b773abb695ae960972aa468f63ed80ec7ef4da59f5a8243858ebeb
------ private Exponent :a28d3b6d6884f9b43cc2191618b9c754774a8203093ead243cae9f9dcc6c1b4c685d010bf1e2b9ca8d50fc00e5f99c61968de52fa838073ffdbe9c471b30d001b21998dbaf6d42a434df0a7d0f309a57262cfe1fff807c348a20e2b6389fbdbcbdcadafcf828de9522161b00dc822879c4c3b2e888792cebf02ee48476eb7641
package com.ly.encrydemo;
import android.util.Base64;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.security.KeyFactory;
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.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import static android.util.Base64.decode;
/**
* Created by user on 2017/3/22.
*/
public class RSAUtil {
/**
* RSA 加密,通过公钥加密数据,密钥从文件流读取
* @param paramStr
* @param inputStream
* @return
*/
public static String EncryptDataOfPublicKey(String paramStr,InputStream inputStream){
try {
byte[] paramBytes = paramStr.getBytes("utf-8");
PublicKey publicKey = getPublicKey(inputStream);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = cipher.getBlockSize(); //获取每次加密的数据长度 官方文档 https://developer.android.google.cn/reference/javax/crypto/CipherSpi.html#engineDoFinal(byte[], int, int)
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] encryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
String str = Base64.encodeToString(encryptData, Base64.NO_WRAP);
return str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 加密,通过私钥加密数据,密钥从文件流读取
* @param paramStr
* @param inputStream
* @return
*/
public static String EncryptDataOfPrivateKey(String paramStr,InputStream inputStream){
try {
byte[] paramBytes = paramStr.getBytes("utf-8");
PrivateKey privateKey = getPrivateKey(inputStream);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = cipher.getBlockSize(); //获取每次加密的数据长度 官方文档 https://developer.android.google.cn/reference/javax/crypto/CipherSpi.html#engineDoFinal(byte[], int, int)
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] encryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
String str = Base64.encodeToString(encryptData, Base64.NO_WRAP);
return str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 解密,通过公钥解密数据,密钥从文件流读取
* @param paramStr
* @param inputStream
* @return
*/
public static String DecryptDataOfPublicKey(String paramStr,InputStream inputStream){
try {
PublicKey publicKey = getPublicKey(inputStream);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] paramBytes = Base64.decode(paramStr,Base64.NO_WRAP);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = 128; //每次解密的长度,每段数据加密后长度都是128
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] decryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
return new String(decryptData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 解密,通过私钥解密数据,密钥从文件流读取
* @param paramStr
* @param inputStream
* @return
*/
public static String DecryptDataOfPrivateKey(String paramStr,InputStream inputStream){
try {
PrivateKey privateKey = getPrivateKey(inputStream);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] paramBytes = Base64.decode(paramStr,Base64.NO_WRAP);
// byte[] decryptData = cipher.doFinal(paramBytes);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = 128; //每次解密的长度,每段数据加密后长度都是128
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] decryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
return new String(decryptData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 通过文件流来读取公钥
* @param paramInputStream
* @return
* @throws Exception
*/
private static PublicKey getPublicKey(InputStream paramInputStream) throws Exception {
try {
PublicKey localPublicKey = null;
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(paramInputStream));
StringBuilder stringbuilder = new StringBuilder();
do
{
String s = bufferedreader.readLine();
if(s == null)
break;
if(s.charAt(0) != '-')
{
stringbuilder.append(s);
stringbuilder.append('\r');
}
} while(true);
String paramString = stringbuilder.toString();
byte[] arrayOfByte = decode(paramString, Base64.NO_WRAP);
localPublicKey = (RSAPublicKey) KeyFactory
.getInstance("RSA").generatePublic(
new X509EncodedKeySpec(arrayOfByte));
return localPublicKey;
} catch (IOException localIOException) {
throw new Exception("公钥数据流读取错误");
} catch (NullPointerException localNullPointerException) {
}catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
throw new Exception("无此算法");
} catch (InvalidKeySpecException localInvalidKeySpecException) {
throw new Exception("公钥非法");
}
throw new Exception("公钥输入流为空");
}
/**
* 通过文件流来读取私钥
* @param paramInputStream
* @return
* @throws Exception
*/
private static PrivateKey getPrivateKey(InputStream paramInputStream) throws Exception {
try {
BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(paramInputStream));
StringBuilder stringbuilder = new StringBuilder();
do {
String s = bufferedreader.readLine();
if (s == null)
break;
if (s.charAt(0) != '-') {
stringbuilder.append(s);
stringbuilder.append('\r');
}
} while (true);
String paramString = stringbuilder.toString();
byte[] buffer = decode(paramString, Base64.NO_WRAP);
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("私钥数据为空");
}
}
/**
* RSA 加密,通过私钥加密数据,密钥由n e生成
* @param paramStr
* @param modulus
* @param exponent
* @return
*/
public static String EncryptDataOfPublicKey(String paramStr,String modulus, String exponent){
try {
byte[] paramBytes = paramStr.getBytes("utf-8");
PublicKey publicKey = getPublicKey(modulus,exponent);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING"); //RSA/ECB/PKCS1Padding
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = cipher.getBlockSize(); //获取每次加密的数据长度 官方文档 https://developer.android.google.cn/reference/javax/crypto/CipherSpi.html#engineDoFinal(byte[], int, int)
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] encryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
String str = Base64.encodeToString(encryptData, Base64.NO_WRAP);
return str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 解密,通过私钥解密数据,密钥由n e生成
* @param paramStr
* @param modulus
* @param exponent
* @return
*/
public static String DecryptDataOfPrivateKey(String paramStr,String modulus, String exponent){
try {
PrivateKey privateKey = getPrivateKey(modulus,exponent);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] paramBytes = Base64.decode(paramStr,Base64.NO_WRAP);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = 128; //每次解密的长度,每段数据加密后长度都是128
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] decryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
return new String(decryptData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 加密,通过私钥加密数据,密钥由n e生成
* @param paramStr
* @param modulus
* @param exponent
* @return
*/
public static String EncryptDataOfPrivateKey(String paramStr,String modulus, String exponent){
try {
byte[] paramBytes = paramStr.getBytes("utf-8");
PrivateKey privateKey = getPrivateKey(modulus,exponent);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = cipher.getBlockSize(); //获取每次加密的数据长度 官方文档 https://developer.android.google.cn/reference/javax/crypto/CipherSpi.html#engineDoFinal(byte[], int, int)
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] encryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
String str = Base64.encodeToString(encryptData, Base64.NO_WRAP);
return str;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* RSA 解密,通过公钥解密数据,密钥由n e生成
* @param paramStr
* @param modulus
* @param exponent
* @return
*/
public static String DecryptDataOfPublicKey(String paramStr,String modulus, String exponent){
try {
PublicKey publicKey = getPublicKey(modulus,exponent);
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPADDING");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] paramBytes = Base64.decode(paramStr,Base64.NO_WRAP);
int i = paramBytes.length; //数据总长度
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
int len = 128; //每次解密的长度,每段数据加密后长度都是128
int j = 0;
int k = 0;
while (i - k > 0) {
byte midBytes[];
int l;
if (i - k > len)
midBytes = cipher.doFinal(paramBytes, k, len);
else
midBytes = cipher.doFinal(paramBytes, k, i - k);
bytearrayoutputstream.write(midBytes, 0, midBytes.length);
l = j + 1;
k = l * len;
j = l;
}
byte[] decryptData = bytearrayoutputstream.toByteArray();
bytearrayoutputstream.close();
return new String(decryptData);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 公钥由n e生成
* @param modulus
* @param exponent
* @return
*/
private static PublicKey getPublicKey(String modulus, String exponent) throws Exception {
return KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger(modulus, 16), new BigInteger(exponent, 16)));
}
/**
* 私钥由n e生成
* @param modulus
* @param exponent
* @return
*/
private static PrivateKey getPrivateKey(String modulus, String exponent) throws Exception {
return KeyFactory.getInstance("RSA").generatePrivate(new RSAPrivateKeySpec(new BigInteger(modulus, 16), new BigInteger(exponent, 16)));
}
}
private void RSAUtilTest(){
try {
//加密数据
String rsaTestData = "asdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsgeasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsge";
//公钥加密 私钥解密
String encryptPub = RSAUtil.EncryptDataOfPublicKey(rsaTestData,mContext.getResources().openRawResource(R.raw.rsa_public_key));
String decryptPri = RSAUtil.DecryptDataOfPrivateKey(encryptPub,mContext.getResources().openRawResource(R.raw.rsa_private_key));
Log.e("test","----1--- : " + String.format("%s\n\r%s",encryptPub,decryptPri));
//私钥加密 公钥解密
String encryptPri = RSAUtil.EncryptDataOfPrivateKey(rsaTestData,mContext.getResources().openRawResource(R.raw.rsa_private_key));
String decryptPub = RSAUtil.DecryptDataOfPublicKey(encryptPri,mContext.getResources().openRawResource(R.raw.rsa_public_key));
Log.e("test","----2--- : " + String.format("%s\n\r%s",encryptPri,decryptPub));
/**
* 密钥对 M E 形式的
*/
String publicModulus = "c1209bfb8f649d891be8f0f32e79ed227800a0a845083cf6b51a217de84e03d442e180b57ad05b155d3f1996c8fb9cb9f233e14846c02cd2991c70216d626221220a6f136936a517c3f73328ad369a12d1d13fc5af6bb2dce04530ab016f101fc90898c6a1afd944e147d16995b90a471add8ee9f8737f57f6bf2d6f52a741ef";
String publicExponent = "010001";
String privateExponent = "c1209bfb8f649d891be8f0f32e79ed227800a0a845083cf6b51a217de84e03d442e180b57ad05b155d3f1996c8fb9cb9f233e14846c02cd2991c70216d626221220a6f136936a517c3f73328ad369a12d1d13fc5af6bb2dce04530ab016f101fc90898c6a1afd944e147d16995b90a471add8ee9f8737f57f6bf2d6f52a741ef";
String privateModulus = "35f8b1fec45cfef5913a311414d9f81e58e0fc04ea7dd9e3ac4ae82f329b92d05ffc7b26bc72bbf1a5847bd73ac5ae4ffcd2e8d3750a41bc7d1388769f060e9bed2669b0e5c1f62cb9e33ea663506554997dd10276902aac4affca89c066dc6fac9720715e6f85c005ec4e18fa9d9acaeb7ecf11cf71fb0c45b1110ea66ec5b1";
//公钥加密 私钥解密
String encryptPubME = RSAUtil.EncryptDataOfPublicKey(rsaTestData,publicModulus,publicExponent);
String decryptPriME = RSAUtil.DecryptDataOfPrivateKey(encryptPubME,privateExponent,privateModulus);
Log.e("test","----1 ME--- : " + String.format("%s\n\r%s",encryptPubME,decryptPriME));
//私钥加密 公钥解密
String encryptPriME = RSAUtil.EncryptDataOfPrivateKey(rsaTestData,privateExponent,privateModulus);
String decryptPubME = RSAUtil.DecryptDataOfPublicKey(encryptPriME,publicModulus,publicExponent);
Log.e("test","----2 ME--- : " + String.format("%s\n\r%s",encryptPriME,decryptPubME));
} catch (Exception e) {
e.printStackTrace();
}
}
//结果
----1--- : Ee8qnbUSj+6rXlq3rUovi+FWSvjRIAA/+lUoiggOKZvDJG8TmhtWGlh+B4u4sgR8n6HnmeD3fEeSFl8mQ+lq11NkaTPEi5enhZGjEvMgIlvsYOUlwxoRu1lXcVXsFFkAThuU418JYaLPRC5C+V1I3E4zzvrGkB4LFsPUXb+kJsMIiwE2XiVEclalTQmi86j3+ua0TWq9K6CNOHxAWBT0D/cWzSc861+7bY9j1ilXRFeRAopsPCszv3jPApKqRJNU3Ewno9FsIk3xUgLXOIEYolf/7TpPBqeF867WX01rWzQM1uh62+t1Ul1DWEvAJsGZm7cw+LGnd8jK7CGAfFlDiQ==
asdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsgeasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsge
----2--- : MpDSK3T9w4DGMDqYjDkxkQixBnZQpogMC/Eq+RCNYwla5JQrMiEOoa3TXhRbfrbyKts8Dq4C7bWuQad1Z+aLBwKHgazKMUWLwoxkZVl0+GJnqT5sCWy/inmC5HT48Q/U6OA0+JGsanQk8klwq+cgsRaEPQHJq5RyR+oeNvbSWo+IUBhEigrPUQJqnrq9wYHcMKfT1GGBXcXjOXFlEtDZukI+ds+7kLall6ovU723rXkfGUe13qJm8cUiJEhkt+O9AUs9H54RELgw3LPVhMPDaQlyLcU/dJd8sOiAsi2Xm+kZdpK90O5xYK5gkiqykuwLyJ7tYT4vM+dGLTnRZ1F82Q==
asdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsgeasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsge
----1 ME--- : Ut7TFeS8cTUN5o1AONLQV1WPS0PLHqMMhU/JOEyQ8oor5s1QKiBPC+cX5fj/dow9uiWi6e7RqRM8QNvd2Top0rLa8njPdYtIcIzcpFTWllHbi7k8k7qaMNZqTxlzcXos7SepnM5af7ZnR+wdKl6AotQhJyH5KhpnSgNrHPGWDrgZY3LOTu6Xn1JdK5/CMcJ+5XNkU0Yvjhf5RidwkrIsTqOYsG8S89Yh7a6Lkk+HaG7+5EULQp9h1YqMLG5GyLSvC8N1bZtSdiTHa5vaN86caIquDo1Dfpx/ld5seKRuX0fs7dpGIBznEbZE+seOUx9v0iepxsx9mK7JkTdtEeS2tA==
asdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsgeasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsge
----2 ME--- : noR44piyaRrvT/jDIf+7CbQeBW5jFJqdsEBP1mTGfbQjS0n5/RRBbhxta26pJd6ap6++YAHkg8OJHnyAZvMCGULq6zE6UUbuH9VVWqby+S1EL7ytHfauwUVdC2g+/ro/DBVswngl5IjG1uUexNFHQQy+HSwE0Q4aD51Ho5aqqRIyk2V1wpt57Sn1O6b99gL9Hs+KsQDTQrVQbAZGsUDHYph4AO2T8hNcQfZuLrPHqsu0pKkr5r91I09jY8VRY8O57ZqHlsaGbnzB9NFctx/BBG9SLsRYY8MJGNxmh1us+6rc+pPQ+eoM5dUAXoDKC1TUYIiV5W60mwi00PoaaiNOpg==
asdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdgasgegesgasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsgeasdegfsgeasdegfsgeasdgasgegesgasdegfsgeasdegfsge