对称加密之简单加密
加密和解密是一个较为独立的软件领域,有时甚至运用到硬件知识。在做项目时,不时会遇到加密用户私隐信息的需要,例如加密码,然后在存到数据库。此处记录一下自己用过的简单加密。
密钥
这里需要说说加密的常用方式,一种是对称加密,一种是非对称加密。
- 对称加密
- 优点:算法公开、计算量小、加密速度快、加密效率高。
- 缺点:
- (1)交易双方都使用同样钥匙,安全性得不到保证。
- (2)每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。
- 非对称加密
- 非对称加密算法的核心源于数学问题,它存在公钥和私钥的概念,要完成加解密操作,需要两个密钥同时参与。我们常说的“公钥加密,私钥加密”或“私钥加密, 公钥解密”都属于非对称加密的范畴
对称式密钥
常用对称加密算法如DES、3DES(TripleDES)、AES、RC2、RC4、RC5和Blowfish等。
对称加密算法中,数据发信方,将明文(原始数据)和加密密钥一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。
收信方收到密文后,若想解读原文,则需要使用同样的密钥及相同算法的逆算法解密,才能使其恢复成可读明文。
在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
下图,一目了然:
非对称式密钥
一般简单加密中,算法上可以充分利用异或运算符^,运用对称加密的思想,需要有一个密钥,那么可以设计这样的方法
//src表示原文,key表示密钥
public String encrypt(String src,String key);
//src表示密文,key表示与上相同的密钥
public String decrypt(String src,String key);
下面设计一个类来实现
public class SimpleEncryption {
private static String charset = "utf-8";
public static String encrypt(String src, String key) {
//如果密钥没有,直接返回null
if(key.length()<1) {
return null;
}
try{
byte[] buf_txt = src.getBytes(charset);
byte[] buf_key = key.getBytes(charset);
for (int i = 0; i < buf_txt.length; i++) {
buf_txt[i] ^= buf_key[i%buf_key.length];//保证数组不会越界
}
return byteToAF(buf_txt);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
public static String decrypt(String src, String key){
if(key.length()<1) {
return null;
}
try{
byte[] buf_txt = AFToByte(src);
byte[] buf_key = key.getBytes(charset);
for (int i = 0; i < buf_txt.length; i++) {
buf_txt[i] ^= buf_key[i%buf_key.length];
}
return new String(buf_txt,charset);
}catch(Exception e){
e.printStackTrace();
}
return null;
}
//每个byte转换成16进制的串
private static String byteToAF(byte[] buf){
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
sb.append(String.format("%02X", buf[i]));
}
return sb.toString();
}
//用16进制串形式表达的byte,转换成byte数组
private static byte[] AFToByte(String str) {
byte[] out = new byte[str.length() / 2];
for (int i = 0; i < str.length(); i += 2) {
out[i / 2] = (byte) (Character.getNumericValue(str.charAt(i)) * 16 + Character
.getNumericValue(str.charAt(i + 1)));
}
return out;
}
}
经测试,成功加密并解密