Android下使用加解密很大程度上依赖于java。AES和RSA加解密对数据格式有一定的要求,单次加密数据长度有限制。加解密文件在处理数据时,需注意保真的问题。所以对文件加解密前,需要将文件内容进行统一编码或解码,避免特殊符号或转义符号的丢失问题。除此之外,还需对文本内容进行一定格式的填充,以保证每次加密解密的数据长度的一致性和规范性。
SecFile.java:
<Android>
package android.sec.stream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import android.sec.Sec;
import android.util.Base64;
import com.cx.mm.web.lokoo.io.FileIO;
import com.cx.mm.web.lokoo.sec.Cypher;
public final class SecFile {
public static final String SUFFIX_SECURE_FILE = ".sec";
public static final String SUFFIX_SECURE_FILE_2 = ".secx";
public static boolean isEncoded(String arg0) {
if (isEncodedSuffix(arg0)) {
File tempFile = new File(arg0);
if (tempFile != null && tempFile.exists() && tempFile.isFile()) {
return true;
} else {
return false;
}
} else {
return false;
}
}
public static boolean isEncodedSuffix(String arg0) {
String suffix = FileIO.getFileNameSuffix(arg0);
if (suffix.endsWith(SecFile.SUFFIX_SECURE_FILE)
|| suffix.endsWith(SecFile.SUFFIX_SECURE_FILE_2)) {
return true;
} else {
return false;
}
}
public static boolean isMultiEncoded(String arg0) {
String suffix = FileIO.getFileNameSuffix(arg0);
if (suffix.endsWith(SecFile.SUFFIX_SECURE_FILE_2)) {
return true;
} else {
return false;
}
}
public static void decode(String tempdir, RSAPrivateKey privateKey)
throws IOException, InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException {
// TODO Auto-generated method stub
File secFile = new File(tempdir);
File tempFile = new File(tempdir.substring(0,
tempdir.indexOf(SUFFIX_SECURE_FILE_2)));
FileInputStream raf = new FileInputStream(secFile);
byte[] buffer = new byte[1024];
ByteArrayOutputStream sb = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream(tempFile);
int readSize = 0;
while ((readSize = raf.read(buffer)) > 0) {
sb.write(buffer, 0, readSize);
}
sb.flush();
sb.close();
// Basic conversion for Image files.
byte[] a = decodeBase64(Sec.decryptByteStream(privateKey,
sb.toByteArray()));
for (int l = 0; l < a.length;) {
int len = a.length - l;
if (len > 1024)
len = 1024;
fos.write(a, l, len);
l += len;
}
fos.flush();
fos.close();
raf.close();
secFile.delete();
}
public static void decode(String tempdir, String key) throws Exception {
// TODO Auto-generated method stub
File secFile = new File(tempdir);
File tempFile = new File(tempdir.substring(0,
tempdir.indexOf(SUFFIX_SECURE_FILE)));
FileInputStream raf = new FileInputStream(secFile);
byte[] buffer = new byte[1024];
ByteArrayOutputStream sb = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream(tempFile);
int readSize = 0;
while ((readSize = raf.read(buffer)) > 0) {
sb.write(buffer, 0, readSize);
}
sb.flush();
sb.close();
byte[] a = Cypher.decrypt(sb.toByteArray(), key);
for (int l = 0; l < a.length;) {
int len = a.length - l;
if (len > 1024)
len = 1024;
fos.write(a, l, len);
l += len;
}
fos.flush();
fos.close();
raf.close();
secFile.delete();
}
public static void encode(String tempdir, RSAPublicKey publicKey)
throws IOException, InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException {
// TODO Auto-generated method stub
File secFile = new File(tempdir + SUFFIX_SECURE_FILE_2);
File tempFile = new File(tempdir);
FileInputStream raf = new FileInputStream(tempFile);
ByteArrayOutputStream sb = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream(secFile);
byte[] buffer = new byte[1024];
int readSize = 0;
while ((readSize = raf.read(buffer)) > 0) {
sb.write(buffer, 0, readSize);
}
sb.flush();
sb.close();
// Basic conversion for Image files.
byte[] a = Sec.encryptByteStream(publicKey,
encodeToBase64(sb.toByteArray()));
for (int l = 0; l < a.length;) {
int len = a.length - l;
if (len > 1024)
len = 1024;
fos.write(a, l, len);
l += len;
}
fos.flush();
fos.close();
raf.close();
tempFile.delete();
}
public static void encode(String tempdir, String key) throws Exception {
// TODO Auto-generated method stub
File secFile = new File(tempdir + SUFFIX_SECURE_FILE);
File tempFile = new File(tempdir);
FileInputStream raf = new FileInputStream(tempFile);
byte[] buffer = new byte[1024];
ByteArrayOutputStream sb = new ByteArrayOutputStream();
FileOutputStream fos = new FileOutputStream(secFile);
int readSize = 0;
while ((readSize = raf.read(buffer)) > 0) {
sb.write(buffer, 0, readSize);
}
sb.flush();
sb.close();
byte[] a = Cypher.encrypt(sb.toByteArray(), key);
for (int l = 0; l < a.length;) {
int len = a.length - l;
if (len > 1024)
len = 1024;
fos.write(a, l, len);
l += len;
}
fos.flush();
fos.close();
raf.close();
tempFile.delete();
}
public static byte[] decodeBase64(byte[] input) throws IOException {
return Base64.decode(input, Base64.NO_WRAP);
}
public static byte[] encodeToBase64(byte[] input) throws IOException {
return Base64.encodeToString(input, Base64.NO_WRAP).getBytes("UTF-8");
}
}
</Android>
Sec.java:
<Android>
package android.sec;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
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.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import android.util.Base64;
import com.cx.cm.log.Logs;
public final class Sec {
// Recommend: 1024 or more in actual cases.
private static final int KEY_BITS = 1024;
// Reserve block for encryption key of specified key length(KEY_SIZE);
private static final int RESERVE_BLOCK_SIZE = 11;
@SuppressWarnings("unused")
private static final int ENCRYPT_BLOCK_SIZE = 117;
@SuppressWarnings("unused")
private static final int DECRYPT_BLOCK_SIZE = 128;
private static final String KEY_ALGORITHM = "RSA";
private static final String CIPHER_ALGORITHM = "RSA";
public static final int KEY_PUBLIC = 0;
public static final int KEY_PRIVATE = 1;
public static final int KEY_PUBLIC_EXP = 2;
public static final int KEY_PRIVATE_EXP = 3;
public static final int KEY_SECRET = 4;
public static final int KEY_PUBLIC_X = 5;
public static final int KEY_PRIVATE_X = 6;
public static void init() throws NoSuchAlgorithmException {
String[] args = initLog();
Logs.log(0, args[0]);
Logs.log(1, args[1]);
Logs.log(2, args[2]);
Logs.log(3, args[3]);
}
public static String[] initLog() throws NoSuchAlgorithmException {
KeyPair keyPair = Sec.getKeyPair();
String arg0 = Sec.getPublicModulus(keyPair);
String arg1 = Sec.getPrivateModulus(keyPair);
String arg2 = Sec.getPublicExponent(keyPair);
String arg3 = Sec.getPrivateExponent(keyPair);
return new String[] { arg0, arg1, arg2, arg3 };
}
public static void $init() throws NoSuchAlgorithmException {
KeyPair keyPair = Sec.getKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Logs.log(KEY_PUBLIC_X, $getPublicKeyBase64(publicKey));
Logs.log(KEY_PRIVATE_X, $getPrivateKeyBase64(privateKey));
}
public static void initSec() throws Exception {
KeyPair keyPair = Sec.getKeyPair();
String arg0 = Sec.getPublicModulus(keyPair);
Logs.log(4, arg0);
}
public static RSAPublicKey getPublicKey() throws NoSuchAlgorithmException,
InvalidKeySpecException {
return Logs.logValid(KEY_PUBLIC) ? Sec.getPublicKey(
Logs.getLog(Sec.KEY_PUBLIC), Logs.getLog(Sec.KEY_PUBLIC_EXP))
: null;
}
public static boolean isValidPublicKey() {
return Logs.getLog(Sec.KEY_PUBLIC).length() <= KEY_BITS
&& Logs.getLog(Sec.KEY_PUBLIC_EXP).length() > 0
&& Logs.getLog(Sec.KEY_PUBLIC_EXP).length() <= KEY_BITS;
}
public static RSAPrivateKey getPrivateKey()
throws NoSuchAlgorithmException, InvalidKeySpecException {
return Logs.logValid(KEY_PRIVATE) ? Sec.getPrivateKey(
Logs.getLog(Sec.KEY_PRIVATE), Logs.getLog(Sec.KEY_PRIVATE_EXP))
: null;
}
public static boolean $isValidPublicKey() {
return Logs.getLog(Sec.KEY_PUBLIC_X).length() > 0;
}
public static boolean isValidPrivateKey() {
return Logs.getLog(Sec.KEY_PRIVATE).length() <= KEY_BITS
&& Logs.getLog(Sec.KEY_PRIVATE_EXP).length() > 0
&& Logs.getLog(Sec.KEY_PRIVATE_EXP).length() <= KEY_BITS;
}
public static RSAPrivateKey $getPrivateKey()
throws NoSuchAlgorithmException, InvalidKeySpecException,
UnsupportedEncodingException {
if (Logs.logValid(KEY_PRIVATE_X)) {
PKCS8EncodedKeySpec keySpec1 = new PKCS8EncodedKeySpec(
$getPrivateKeyEncoded());
KeyFactory keyFactory1 = KeyFactory.getInstance(KEY_ALGORITHM);
return (RSAPrivateKey) keyFactory1.generatePrivate(keySpec1);
} else
return null;
}
public static RSAPublicKey $getPublicKey() throws NoSuchAlgorithmException,
InvalidKeySpecException, UnsupportedEncodingException {
if (Logs.logValid(KEY_PRIVATE_X)) {
X509EncodedKeySpec keySpec1 = new X509EncodedKeySpec(
$getPublicKeyEncoded());
KeyFactory keyFactory1 = KeyFactory.getInstance(KEY_ALGORITHM);
return (RSAPublicKey) keyFactory1.generatePublic(keySpec1);
} else
return null;
}
public static boolean $isValidPrivateKey() {
return Logs.getLog(Sec.KEY_PRIVATE_X).length() > 0;
}
public static String getSecretKey() {
return Logs.logValid(KEY_SECRET) ? Logs.getLog(KEY_SECRET) : null;
}
public static KeyPair getKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(KEY_BITS);
KeyPair keyPair = (KeyPair) keyPairGen.generateKeyPair();
return keyPair;
}
public static RSAPublicKey $getPublicKey(KeyPair keyPair) {
return (RSAPublicKey) keyPair.getPublic();
}
public static RSAPrivateKey $getPrivateKey(KeyPair keyPair) {
return (RSAPrivateKey) keyPair.getPrivate();
}
public static byte[] $getPublicKeyEncoded()
throws UnsupportedEncodingException {
return $getBase64Decoded(Logs.getLog(Sec.KEY_PUBLIC_X));
}
public static byte[] $getPrivateKeyEncoded()
throws UnsupportedEncodingException {
return $getBase64Decoded(Logs.getLog(Sec.KEY_PRIVATE_X));
}
public static String $getPublicKeyBase64(RSAPublicKey publicKey) {
return Base64.encodeToString(publicKey.getEncoded(), Base64.NO_WRAP);
}
public static String $getPrivateKeyBase64(RSAPrivateKey privateKey) {
return Base64.encodeToString(privateKey.getEncoded(), Base64.NO_WRAP);
}
public static byte[] $getBase64Decoded(String arg0)
throws UnsupportedEncodingException {
return Base64.decode(arg0.getBytes("UTF-8"), Base64.NO_WRAP);
}
public static byte[] $encrypt(RSAPublicKey publicKey, byte[] input)
throws IllegalBlockSizeException, BadPaddingException,
InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(input);
}
public static byte[] $decrypt(RSAPrivateKey privateKey, byte[] input)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(input);
}
public static String getPublicModulus(KeyPair keyPair) {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
return publicKey.getModulus().toString(16);
}
public static String getPublicModulus(RSAPublicKey publicKey) {
return publicKey.getModulus().toString(16);
}
public static String getPrivateModulus(KeyPair keyPair) {
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
return privateKey.getModulus().toString(16);
}
public static String getPrivateModulus(RSAPrivateKey privateKey) {
return privateKey.getModulus().toString(16);
}
public static String getPrivateExponent(KeyPair keyPair) {
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
return privateKey.getPrivateExponent().toString(16);
}
public static String getPrivateExponent(RSAPrivateKey privateKey) {
return privateKey.getPrivateExponent().toString(16);
}
public static String getPublicExponent(KeyPair keyPair) {
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
return publicKey.getPublicExponent().toString(16);
}
public static String getPublicExponent(RSAPublicKey publicKey) {
return publicKey.getPublicExponent().toString(16);
}
public static RSAPublicKey getPublicKey(String modulus,
String publicExponent) throws NoSuchAlgorithmException,
InvalidKeySpecException {
BigInteger bigIntModulus = new BigInteger(modulus, 16);
BigInteger bigIntPrivateExponent = new BigInteger(publicExponent, 16);
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus,
bigIntPrivateExponent);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
RSAPublicKey publicKey = (RSAPublicKey) keyFactory
.generatePublic(keySpec);
// X509EncodedKeySpec keySpec2 = new X509EncodedKeySpec(
// publicKey.getEncoded());
// return (RSAPublicKey) keyFactory.generatePublic(keySpec2);
return publicKey;
}
public static RSAPrivateKey getPrivateKey(String modulus,
String privateExponent) throws NoSuchAlgorithmException,
InvalidKeySpecException {
BigInteger bigIntModulus = new BigInteger(modulus, 16);
BigInteger bigIntPublicExponent = new BigInteger(privateExponent, 16);
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(bigIntModulus,
bigIntPublicExponent);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory
.generatePrivate(keySpec);
return privateKey;
}
public static byte[] encrypt(RSAPublicKey key, byte[] input)
throws NoSuchAlgorithmException, NoSuchPaddingException,
IllegalBlockSizeException, BadPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(input);
}
public static byte[] decrypt(RSAPrivateKey key, byte[] input)
throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(input);
}
public static byte[] encryptByteStream(RSAPublicKey key, byte[] arg0)
throws NoSuchAlgorithmException, NoSuchPaddingException,
IllegalBlockSizeException, BadPaddingException,
InvalidKeyException, IOException {
// Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// cipher.init(Cipher.ENCRYPT_MODE, key);
// byte[] input = arg0;
// int blocks = input.length / ENCRYPT_BLOCK_SIZE;
// if (input.length % ENCRYPT_BLOCK_SIZE != 0) {
// blocks++;
// }
// ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(blocks
// * DECRYPT_BLOCK_SIZE);
// byte[] encryptedBlock;
// for (int cursor = 0; cursor < input.length;) {
// int inputLength = input.length - cursor;
// if (inputLength > ENCRYPT_BLOCK_SIZE)
// inputLength = ENCRYPT_BLOCK_SIZE;
// encryptedBlock = cipher.doFinal(input, cursor, inputLength);
// outBuffer.write(encryptedBlock, 0, DECRYPT_BLOCK_SIZE);
// cursor += ENCRYPT_BLOCK_SIZE;
// }
// outBuffer.flush();
// outBuffer.close();
// return outBuffer.toByteArray();
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
int decryptBlock = KEY_BITS / 8; // 128 bytes
int encryptBlock = decryptBlock - RESERVE_BLOCK_SIZE; // 117 bytes
int nBlock = (arg0.length / encryptBlock);
if ((arg0.length % encryptBlock) != 0) {
nBlock += 1;
}
ByteArrayOutputStream outbuf = new ByteArrayOutputStream(nBlock
* decryptBlock);
cipher.init(Cipher.ENCRYPT_MODE, key);
// cryptedBase64Str =
// Base64.encodeBase64String(cipher.doFinal(plaintext.getBytes()));
ByteArrayInputStream bas = new ByteArrayInputStream(arg0);
for (int offset = 0; offset < arg0.length; offset += encryptBlock) {
int inputLen = (arg0.length - offset);
if (inputLen > encryptBlock) {
inputLen = encryptBlock;
}
byte[] buffer = new byte[inputLen];
bas.read(buffer);
byte[] encryptedBlock = cipher.doFinal(buffer, 0, inputLen);
outbuf.write(encryptedBlock);
}
return outbuf.toByteArray();
}
public static byte[] decryptByteStream(RSAPrivateKey key, byte[] arg0)
throws NoSuchAlgorithmException, NoSuchPaddingException,
IllegalBlockSizeException, BadPaddingException,
InvalidKeyException, IOException {
// Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// cipher.init(Cipher.DECRYPT_MODE, key);
// byte[] input = arg0;
// // if (input.length % DECRYPT_BLOCK_SIZE != 0) {
// // throw new IllegalBlockSizeException(
// // "blocks are invalid or damaged.");
// // }
// int blocks = (input.length / DECRYPT_BLOCK_SIZE);
// ByteArrayOutputStream outBuffer = new ByteArrayOutputStream(blocks
// * ENCRYPT_BLOCK_SIZE);
// cipher.init(Cipher.DECRYPT_MODE, key);
// for (int cursor = 0; cursor < input.length;) {
// int inputLength = (input.length - cursor);
// if (inputLength > DECRYPT_BLOCK_SIZE) {
// inputLength = DECRYPT_BLOCK_SIZE;
// }
//
// byte[] decryptedBlock = cipher.doFinal(input, cursor, inputLength);
// outBuffer.write(decryptedBlock, 0, ENCRYPT_BLOCK_SIZE);
// cursor += DECRYPT_BLOCK_SIZE;
// }
// outBuffer.flush();
// outBuffer.close();
// return outBuffer.toByteArray();
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
int decryptBlock = KEY_BITS / 8; // 128 bytes
int encryptBlock = decryptBlock - RESERVE_BLOCK_SIZE; // 117 bytes
int nBlock = (arg0.length / decryptBlock);
ByteArrayOutputStream outbuf = new ByteArrayOutputStream(nBlock
* encryptBlock);
cipher.init(Cipher.DECRYPT_MODE, key);
// plaintext = new
// String(cipher.doFinal(Base64.decodeBase64(cryptedBase64Str)));
ByteArrayInputStream bas = new ByteArrayInputStream(arg0);
for (int offset = 0; offset < arg0.length; offset += decryptBlock) {
int inputLen = (arg0.length - offset);
if (inputLen > decryptBlock) {
inputLen = decryptBlock;
}
byte[] buffer = new byte[inputLen];
bas.read(buffer);
byte[] decryptedBlock = cipher.doFinal(buffer, 0, inputLen);
outbuf.write(decryptedBlock);
}
outbuf.flush();
outbuf.close();
return outbuf.toByteArray();
}
}
</Android>
Cipher.java:
<Android>
package com.cx.mm.web.lokoo.sec;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
import android.util.Log;
import com.cx.cm.log.Logs;
public class Cypher {
private static final String TAG = "Cypher";
private Cipher mCipher;
private SecretKeySpec mSecretKey;
public static final String SHA256 = "SHA256";
public static final String SHA512 = "SHA512";
public static final String SHA1024 = "SHA1024";
public static final int SHA_256 = 0;
public static final int SHA_512 = 1;
public static final int SHA_1024 = 2;
public static final int SECURITY_LOW = -10000;
public static final int SECURITY_NORMAL = -10001;
public static final int SECURITY_HIGH = -10002;
public Cypher(String param) {
this.mSecretKey = new SecretKeySpec(generateKey(param), "AES");
instantiate(this.mSecretKey, 1);
}
public static String md5(String message) {
try {
MessageDigest a = MessageDigest.getInstance("MD5");
a.update(message.getBytes());
return getString(a);
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, e.getMessage());
}
return null;
}
private static String getString(MessageDigest a) {
try {
String s;
for (Object n = new BigInteger(1, a.digest()).toString(16);; n = s) {
if (((String) n).length() >= 32)
return (String) n;
s = "0" + (String) n;
}
} catch (Exception unknown) {
Log.e(TAG, unknown.getMessage());
}
return (String) "";
}
public static byte[] generateKey(String param) {
try {
return MessageDigest.getInstance("SHA256").digest(
param.getBytes("UTF-8"));
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
public static byte[] generateKey(String param, int security) {
try {
switch (security) {
case SHA_256:
case SECURITY_LOW:
return MessageDigest.getInstance(SHA256).digest(
param.getBytes("UTF-8"));
case SHA_512:
case SECURITY_NORMAL:
case SECURITY_HIGH:
return MessageDigest.getInstance(SHA512).digest(
param.getBytes("UTF-8"));
case SHA_1024:
return MessageDigest.getInstance(SHA1024).digest(
param.getBytes("UTF-8"));
default:
return MessageDigest.getInstance("SHA256").digest(
param.getBytes("UTF-8"));
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return null;
}
public void instantiate(SecretKey key, int mode) {
byte[] params = new byte[16];
params[1] = 1;
params[2] = 2;
params[3] = 3;
params[4] = 4;
params[5] = 5;
params[6] = 6;
params[7] = 7;
params[8] = 8;
params[9] = 9;
params[10] = 10;
params[11] = 11;
params[12] = 12;
params[13] = 13;
params[14] = 14;
params[15] = 15;
IvParameterSpec ivParameterSpec = new IvParameterSpec(params);
try {
this.mCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
this.mCipher.init(mode, key, ivParameterSpec);
return;
} catch (Exception e) {
this.mCipher = null;
Log.e(TAG, e.getMessage());
}
}
public static Cipher instantiate(SecretKey key, int mode, int arg0) {
byte[] params = new byte[16];
params[1] = 1;
params[2] = 2;
params[3] = 3;
params[4] = 4;
params[5] = 5;
params[6] = 6;
params[7] = 7;
params[8] = 8;
params[9] = 9;
params[10] = 10;
params[11] = 11;
params[12] = 12;
params[13] = 13;
params[14] = 14;
params[15] = 15;
IvParameterSpec ivParameterSpec = new IvParameterSpec(params);
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(mode, key, ivParameterSpec);
return cipher;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
return null;
}
}
public String encrypt(String msg) {
if (null == this.mCipher)
return "";
try {
String str = Base64.encodeToString(
this.mCipher.doFinal(msg.getBytes()), Base64.NO_WRAP);
return str;
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return "";
}
public static byte[] encrypt(byte[] msg, String param)
throws UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException {
return encrypt(msg, param, SECURITY_LOW);
}
public static byte[] encrypt(byte[] msg, String param, int security)
throws UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException {
SecretKeySpec key = new SecretKeySpec(generateKey(param, security),
"AES");
Cipher cipher = instantiate(key, Cipher.ENCRYPT_MODE, -1);
if (null == cipher)
return null;
return Base64.encodeToString(cipher.doFinal(msg), Base64.NO_WRAP)
.getBytes("UTF-8");
}
public String decrypt(String e) {
instantiate(this.mSecretKey, 2);
if (null == this.mCipher)
return "";
try {
String str = new String(this.mCipher.doFinal(Base64.decode(e,
Base64.NO_WRAP)));
return str;
} catch (Exception e1) {
Logs.ef(TAG, e1);
}
return "";
}
public static byte[] decrypt(byte[] e, String param)
throws UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException {
return decrypt(e, param, SECURITY_LOW);
}
public static byte[] decrypt(byte[] e, String param, int security)
throws UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException {
SecretKeySpec key = new SecretKeySpec(generateKey(param, security),
"AES");
Cipher cipher = instantiate(key, Cipher.DECRYPT_MODE, -1);
if (null == cipher)
return null;
return cipher.doFinal(Base64.decode(e, Base64.NO_WRAP));
}
}
</Android>
不论是在Android还是纯Java、PHP或Python等其他编程语言环境下,其原理走的是几乎一致的路线:数据的编码和填充。编码是为了是数据的加密和解密能避免因平台的差异而导致数据失真,填充是为了保证加解密的数据一致性。