在Android开发中,可能会遇到对数据进行加密的情况。典型的对称加密算法有DES、3DES、AES等。
一.DES
DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES设计中使用了分组密码设计的两个原则:混淆(confusion)和扩散,其目的是抗击敌手对密码系统的统计分析。混淆是使密文的统计特性与密钥的取值之间的关系尽可能复杂化,以使密钥和明文以及密文之间的依赖性对密码分析者来说是无法利用的。扩散的作用就是将每一位明文的影响尽可能迅速地作用到较多的输出密文位中,以便在大量的密文中消除明文的统计结构,并且使每一位密钥的影响尽可能迅速地扩展到较多的密文位中,以防对密钥进行逐段破译。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1),其算法主要分为两步:
(1)初始置换
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。
3DES又称Triple DES,是DES加密算法的一种模式,它使用3条56位的密钥对数据进行三次加密。数据加密标准(DES)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ANSI组织规范为ANSI X.3.92。DES使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的DES,3DES更为安全。
3DES是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:
3DES加密过程为:C=Ek3(Dk2(Ek1(M)))
3DES解密过程为:M=Dk1(EK2(Dk3(C)))
三.AES
20世纪末,当差分密码分析及线性密码分析出现以后,由美国人开创的DES(DataEncryptionStandard,即数据加密标准)逐渐由繁荣走向衰落。1997年 1月2日,美国国家和标准技术研究所 (NIST)发布高级加密标准fAES—FIPS)研发计划,9月12日发布征集候选算法公告,NIST计划确定一种可以保护敏感信息的公开、全球通用并且免费的算法作为AES(Advanced EncryptionStandard,即高级加密标准),用以取代DES。对该标准的基本要求是 :支持 128比特分组长度和 128、192、256比特 密钥长度,并且算法必须是私钥体制的分组密码。经过 3年多时间的反复较量,对首轮人选的15种不同算法进行了广泛的评估和测试,筛选出5种算法进人决赛。由比利时的密码专家JoanDaemen及VincentRijmen所提出的R~ndeal加密算法,最终胜出。2000年l0月2日,Rijndael算法被 NIST确定为新一代高级加密标准。
密码算法的理论与实现研究是信息安全研究的基础。对各类电子信息进行加密,在其存储、处理、传送以及交换过程中实施保护,是保证信息安全的有效措施。数据加密标准DES于 1977年1月向社会公布,它是第一个世界公认的实用分组密码算法标准。但在经过20年的应用后,DES已被认为不可靠。3DES作为DES的替代,密钥长度为168bits,可克服穷举攻击问题。同时,3DES的底层加密算法对密码分析攻击有很强的免疫力。但由于用软件实现该算法的速度慢,使得3DES不能成为长期使用的加密算法标准,需要一种新的高级加密标准来替代。
AES具有密钥灵活性及较高的可实现性,具有较高的安全性能及实现效率,其密钥建立时间极短,且灵敏性 良好。Rijndeal 算法给出了最佳查分特征概率,进行了算法抵抗差分密码分析以及线性密码分析。无论Rijndeal使用反馈模式或无反馈模式,其硬件和软件实现性能都表现优秀。此外,Rijndeal对内存的极低需求使其适合于在存储器受限环境下使用,并能够表现出极好的性能。
下面就写一个简单的demo来实现DES、3DES、AES的加密功能。在这个工程中需要引入特定的jar包。(http://download.csdn.net/detail/ldld1717/9667995)。
工程结构见图1:
MainActivity.java
package com.example.leidong.encrypttest;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.example.leidong.encrypttest.utils.AESUtil;
import com.example.leidong.encrypttest.utils.DESUtil;
import com.example.leidong.encrypttest.utils.DESedeUtil;
import org.apache.commons.codec.binary.Base64;
/**
* Created by leidong on 2016/11/9.
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//标签
private static final String TAG = "MainActivity";
//明文输入框(可输入、单行)
private EditText et_inputInfo;
//密钥输入框(不可输入、单行)
private EditText et_secretKey;
//已加密信息输入框(不可输入、单行)
private EditText et_encryptInfo;
//已解密信息输入框(不可输入、单行)
private EditText et_decryptInfo;
//DES处理按钮
private Button bt_des;
//3DES处理按钮
private Button bt_3des;
//AES处理按钮
private Button bt_aes;
//清空按钮
private Button bt_clear;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
//获取并初始化组件
init();
}
/**
* 获取并初始化组件
*/
private void init() {
et_inputInfo = (EditText)findViewById(R.id.et_inputInfo);
et_secretKey = (EditText)findViewById(R.id.et_secretKey);
et_encryptInfo = (EditText)findViewById(R.id.et_encryptInfo);
et_decryptInfo = (EditText)findViewById(R.id.et_decryptInfo);
//设置文本输入框不可输入
et_secretKey.setEnabled(false);
et_encryptInfo.setEnabled(false);
et_decryptInfo.setEnabled(false);
bt_des = (Button)findViewById(R.id.bt_des);
bt_3des = (Button)findViewById(R.id.bt_3des);
bt_aes = (Button)findViewById(R.id.bt_aes);
bt_clear = (Button)findViewById(R.id.bt_clear);
//设置按钮监听器
bt_des.setOnClickListener(MainActivity.this);
bt_3des.setOnClickListener(MainActivity.this);
bt_aes.setOnClickListener(MainActivity.this);
bt_clear.setOnClickListener(MainActivity.this);
//初始化按钮的颜色,未点击为灰色,点击为绿色
initButtonsColor();
}
/**
* 对按钮点击事件的监控
* @param view
*/
@Override
public void onClick(View view) {
switch(view.getId()){
/**
* 点击DES按钮
*/
case R.id.bt_des:{
try {
initButtonsColor();
bt_des.setTextColor(Color.GREEN);
Toast.makeText(MainActivity.this, "DES", Toast.LENGTH_LONG).show();
String inputStr = et_inputInfo.getText().toString().trim();
byte[] inputData = inputStr.getBytes();
byte[] key = DESUtil.initKey();
et_secretKey.setText(new String(Base64.encodeBase64(key)));
inputData = DESUtil.encrypt(inputData, key);
et_encryptInfo.setText(new String(Base64.encodeBase64(inputData)));
byte[] outputData = DESUtil.decrypt(inputData, key);
et_decryptInfo.setText(new String(outputData));
}
catch (Exception e){
e.printStackTrace();
}
}
break;
/**
* 点击3DES按钮
*/
case R.id.bt_3des:{
try {
initButtonsColor();
bt_3des.setTextColor(Color.GREEN);
Toast.makeText(MainActivity.this, "3DES", Toast.LENGTH_LONG).show();
String inputStr = et_inputInfo.getText().toString().trim();
byte[] inputData = inputStr.getBytes();
byte[] key = DESedeUtil.initKey();
et_secretKey.setText(new String(Base64.encodeBase64(key)));
inputData = DESedeUtil.encrypt(inputData, key);
et_encryptInfo.setText(new String(Base64.encodeBase64(inputData)));
byte[] outputData = DESedeUtil.decrypt(inputData, key);
et_decryptInfo.setText(new String(outputData));
}catch (Exception e){
e.printStackTrace();
}
}
break;
/**
* 点击AES按钮
*/
case R.id.bt_aes:{
try {
initButtonsColor();
bt_aes.setTextColor(Color.GREEN);
Toast.makeText(MainActivity.this, "AES", Toast.LENGTH_LONG).show();
String inputStr = et_inputInfo.getText().toString().trim();
byte[] inputData = inputStr.getBytes();
byte[] key = AESUtil.initKey();
et_secretKey.setText(new String(Base64.encodeBase64(key)));
inputData = AESUtil.encrypt(inputData, key);
et_encryptInfo.setText(new String(Base64.encodeBase64(inputData)));
byte[] outputData = AESUtil.decrypt(inputData, key);
et_decryptInfo.setText(new String(outputData));
}
catch(Exception e){
e.printStackTrace();
}
}
break;
/**
* 点击清空内容按钮
*/
case R.id.bt_clear:{
et_inputInfo.setText(null);
et_secretKey.setText(null);
et_encryptInfo.setText(null);
et_decryptInfo.setText(null);
Toast.makeText(MainActivity.this, "清空完成", Toast.LENGTH_LONG).show();
}
break;
/**
* 默认情况
*/
default:
break;
}
}
/**
* 初始化按钮的颜色
*/
private void initButtonsColor(){
bt_des.setTextColor(Color.GRAY);
bt_3des.setTextColor(Color.GRAY);
bt_aes.setTextColor(Color.GRAY);
}
}
package com.example.leidong.encrypttest.utils;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by leidong on 2016/11/9.
* DES类
*/
public abstract class DESUtil {
/**
* 密钥算法
*/
private static final String KEY_ALGORITHM = "DES";
/**
* 加密/解密算法 工作模式 填充模式
*/
private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
/**
* 转换密钥
* @param key
* @return
* @throws Exception
*/
private static Key toKey(byte[] key) throws Exception{
//实例化密钥
SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
return secretKey;
}
/**
* 加密
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key) throws Exception{
//还原密钥
Key k = toKey(key);
//实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//初始化
cipher.init(Cipher.ENCRYPT_MODE, k);
//执行操作
return cipher.doFinal(data);
}
/**
* 解密
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception{
//还原密钥
Key k = toKey(key);
//实例化
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
//初始化
cipher.init(Cipher.DECRYPT_MODE, k);
//执行操作
return cipher.doFinal(data);
}
/**
* 初始化密钥
* @return
* @throws Exception
*/
public static byte[] initKey() throws Exception{
//实例化KeyGenerator
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
//初始化
keyGenerator.init(56);
//生成密钥
SecretKey secretKey = keyGenerator.generateKey();
//返回密钥
return secretKey.getEncoded();
}
}
DES的情况:
3DES的情况:
AES的情况:
完整的工程下载地址:
http://download.csdn.net/detail/ldld1717/9678097