我们在处理用户中心数据时(登陆和注册),为了增加用户信息的安全系数,一般需要把用户的密码进行加密。
具体流程:
在用户端把用户的密码进行AES加密,然后进行Base64编码,然后发送的奥服务器。服务器拿到数据后,先进行Base64转码,然后进行AES解码。
需要注意的是:在进行AES加解密时密匙必须相同,否则无法解密。
AES加解密原理
AES (Advanced Encryption Standard):在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。具体原理可以看看这篇文章 点击打开链接。
Base64编码原理
具体实现原理可以看看这篇文章 点击打开链接。
在Android中具体实现代码:
/**
* AES加密工具类
* Created by fblife on 2017/4/6.
*/
public class AESUtils {
private static final String TAG = AESUtils.class.getSimpleName();
//算法/模式/填充
private static final String CIPHER_MODE = "AES/ECB/pkcs7padding";
/**
* 创建密钥
* @param password 密匙 (必须为16位)
* @return
*/
private static SecretKeySpec createKey(String password) {
byte[] data = null;
StringBuilder sb = new StringBuilder();
sb.append(password);
while (sb.length() < 16){
sb.append("0");
}
if (sb.length() > 16){
sb.setLength(16);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(data, "AES");
}
/**
* 加密字节数据
* @param content 需要加密的内容
* @param password 密匙
* @return 加密完的字节数组
*/
private static byte[] encrypt(byte[] content, String password) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 加密 及转换
* @param content 加密的内容
* @param password 密匙
* @return 返回加密的数值
*/
public static String encrypt(String content, String password) {
byte[] data = null;
try {
data = content.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
data = encrypt(data, password);
return byteToHexStr(data);
}
/**
* 解密字节数组
* @param content 需要解密的内容
* @param password 密匙
* @return 解密完的字节数组
*/
public static byte[] decrypt(byte[] content, String password) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密及转换
* @param content 需要解密的内容
* @param password 密匙
* @return 解密完的字符串
*/
public static String decrypt(String content, String password) {
byte[] data = null;
try {
data = hexStrToByte(content);
} catch (Exception e) {
e.printStackTrace();
}
data = decrypt(data, password);
if (data == null)
return null;
try {
return new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将二进制转换成16进制
* @param buf
* @return
*/
public static String byteToHexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
String hex = null;
for (int i = 0; i < buf.length; i++) {
hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex);
}
return sb.toString();
}
/**
* 将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] hexStrToByte(String hexStr) {
if (hexStr == null || hexStr.length() < 1)
return null;
int length = hexStr.length() / 2;
int high = 0;
int low = 0;
byte[] result = new byte[length];
for (int i = 0; i< length; i++) {
high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
activity中的测试代码:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private String pass = "abc123def456ghi789";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String encrypt = AESUtils.encrypt("12345",pass);
Log.i(TAG, "onCreate: AES加密: " + encrypt);
encrypt = new String(Base64.encode(encrypt.getBytes(),Base64.DEFAULT));
Log.i(TAG, "onCreate: Base64编码: " + encrypt);
encrypt = new String(Base64.decode(encrypt.getBytes(), Base64.DEFAULT));
Log.i(TAG, "onCreate: Base64转码: " + encrypt);
String decrypt = AESUtils.decrypt(encrypt, pass);
Log.i(TAG, "onCreate: AES解密: " + decrypt);
}
}
测试结果:
/**
* AES加密工具类
* Created by fblife on 2017/4/6.
*/
public class AESUtils {
private static final String TAG = AESUtils.class.getSimpleName();
//算法/模式/填充
private static final String CIPHER_MODE = "AES/ECB/pkcs7padding";
/**
* 创建密钥
* @param password 密匙 (必须为16位)
* @return
*/
private static SecretKeySpec createKey(String password) {
byte[] data = null;
StringBuilder sb = new StringBuilder();
sb.append(password);
while (sb.length() < 16){
sb.append("0");
}
if (sb.length() > 16){
sb.setLength(16);
}
try {
data = sb.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return new SecretKeySpec(data, "AES");
}
/**
* 加密字节数据
* @param content 需要加密的内容
* @param password 密匙
* @return 加密完的字节数组
*/
private static byte[] encrypt(byte[] content, String password) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 加密 及转换
* @param content 加密的内容
* @param password 密匙
* @return 返回加密的数值
*/
public static String encrypt(String content, String password) {
byte[] data = null;
try {
data = content.getBytes("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
data = encrypt(data, password);
return byteToHexStr(data);
}
/**
* 解密字节数组
* @param content 需要解密的内容
* @param password 密匙
* @return 解密完的字节数组
*/
public static byte[] decrypt(byte[] content, String password) {
try {
SecretKeySpec key = createKey(password);
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(content);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密及转换
* @param content 需要解密的内容
* @param password 密匙
* @return 解密完的字符串
*/
public static String decrypt(String content, String password) {
byte[] data = null;
try {
data = hexStrToByte(content);
} catch (Exception e) {
e.printStackTrace();
}
data = decrypt(data, password);
if (data == null)
return null;
try {
return new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将二进制转换成16进制
* @param buf
* @return
*/
public static String byteToHexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
String hex = null;
for (int i = 0; i < buf.length; i++) {
hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex);
}
return sb.toString();
}
/**
* 将16进制转换为二进制
* @param hexStr
* @return
*/
public static byte[] hexStrToByte(String hexStr) {
if (hexStr == null || hexStr.length() < 1)
return null;
int length = hexStr.length() / 2;
int high = 0;
int low = 0;
byte[] result = new byte[length];
for (int i = 0; i< length; i++) {
high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
}
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private String pass = "abc123def456ghi789";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String encrypt = AESUtils.encrypt("12345",pass);
Log.i(TAG, "onCreate: AES加密: " + encrypt);
encrypt = new String(Base64.encode(encrypt.getBytes(),Base64.DEFAULT));
Log.i(TAG, "onCreate: Base64编码: " + encrypt);
encrypt = new String(Base64.decode(encrypt.getBytes(), Base64.DEFAULT));
Log.i(TAG, "onCreate: Base64转码: " + encrypt);
String decrypt = AESUtils.decrypt(encrypt, pass);
Log.i(TAG, "onCreate: AES解密: " + decrypt);
}
}