自创简易加密算法
2017-12-08 16:24
204 查看
前几日和同事聊天,说到经常忘记密码,但记在一些地方,又不放心。我们就想,要是实现一个加密算法,每次记录加密结果,需要时再解密,那问题不就迎刃而解了嘛。
后来根据需求,设计了一个基于异或的对称加密算法。算法非常简单:
1.先定义一个由一系列不规则字符组成的盐值(SALT),然后生成一个密钥,密钥是一个整数数组,里面的值随机生成,对应盐值字符串的下标。
2.加密时,根据密钥与盐值生成一个用来加密的字节数组。
3.通过这个字节数组,与被加密数据的字节数组进行异或操作
4.返回加密结果,由于异或的特性,解密过程同加密过程。
后来经过一些修改,将加密的字节数组转换为对应的16进制字符串(4位二进制表示一位16进制,根据这个规律生成)。这样就能将任何数据加密为一串字符串,解密时,先将这串字符串转换为对应的字节数组,再进行解密还原。
老规矩,上王者(呸,代码 最近有些沉迷游戏):
package com.myself.tryit;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA
* Date: 2017/12/8
* Time: 上午11:04
*
* @author 陈樟杰
*/
public class EncryptDecrypt {
/**
* 盐值
*/
private static final String SALT = "dfsad@#%$@TDGDF%$#%@#%WFRGFDHJKcvxznmfdsgdfgs2432534fgdf46t";
/**
* 内部密钥
*/
private static final int[] KEY = {
23, 22, 24, 4, 51, 26, 37, 27, 24, 6, 26, 38, 29, 35, 18, 21, 14, 3, 12, 4, 41, 39, 18, 44, 54, 21, 33, 35, 31, 22, 34, 53, 51, 44, 8, 12, 3, 0, 28, 1, 48, 9, 51, 57, 20, 44, 27, 3, 16, 48
};
/**
* 16进制映射表
*/
private static final Map MMP = new HashMap(12);
static {
short i = 10;
for (; i < 16; i++) {
MMP.put(i, (char) ('A' + i - 10));
MMP.put((char) ('A' + i - 10), i);
}
}
/**
* 生成密钥
*
* @param len 密钥长度
* @return
*/
public static int[] generateKey(int len) {
int ceiling = SALT.length();
int[] key = new int[len];
for (int i = 0; i < len; i++) {
key[i] = (int) (Math.random() * ceiling);
}
return key;
}
/**
* 加密
*
* @param original
* @return
*/
public static byte[] encrypt(byte[] original) {
byte[] keyByte = new byte[KEY.length];
/**
* 获取加密字节数组
*/
for (int i = 0; i < KEY.length; i++) {
keyByte[i] = (byte) SALT.charAt(KEY[i]);
}
/**
* 加密
*/
int k = 0;
byte[] encryptByte = new byte[original.length];
for (int i = 0; i < original.length; i++) {
encryptByte[i] = (byte) (original[i] ^ keyByte[k++ % keyByte.length]);
}
return encryptByte;
}
/**
* 解密
*
* @param original
* @return
*/
public static byte[] decrypt(byte[] original) {
return encrypt(original);
}
/**
* 对字符串加密
* 由于解码时 byte数组不一定符合规范 所以解码算法可能会改变字节数组的值 所以只能返回字节数组 而不能返回字符串
*
* @param original
* @return
*/
public static byte[] encryptString(String original) {
return encrypt(original.getBytes());
}
/**
* 对字符串解密
*
* @param original
* @return
*/
public static String decryptToString(byte[] original) {
return new String(encrypt(original));
}
/**
* 加密成16进制字符串
*
* @param original
* @return
*/
public static String encryptToHex(byte[] original) {
//先加密
byte[] bytes = encrypt(original);
/**
* 将加密的字节数组转换成16进制字符串
*/
StringBuffer stringBuffer = new StringBuffer("");
for (int i = 0; i < bytes.length; i++) {
short a = (short) (bytes[i] & 15);
short b = (short) ((bytes[i] & (15 << 4)) >>> 4);
if (b < 10) {
stringBuffer.append(b);
} else {
stringBuffer.append(MMP.get(b));
}
if (a < 10) {
stringBuffer.append(a);
} else {
stringBuffer.append(MMP.get(a));
}
}
return stringBuffer.toString();
}
/**
* 从16进制字符串解密
*
* @param original
* @return
*/
public static byte[] decryptFromHex(String original) {
/**
* 将16进制字符串转换成字节数组
*/
byte[] bytes = new byte[original.length() / 2];
int len = 0;
for (int i = 0; i < original.length(); i += 2) {
short a, b;
if (original.charAt(i) >= '0' && original.charAt(i) <= '9') {
a = (short) (original.charAt(i) - '0');
a <<= 4;
} else {
a = (short) MMP.get(original.charAt(i));
a <<= 4;
}
if (original.charAt(i + 1) >= '0' && original.charAt(i + 1) <= '9') {
b = (short) (original.charAt(i + 1) - '0');
} else {
b = (short) MMP.get(original.charAt(i + 1));
}
bytes[len++] = (byte) (a + b);
}
//解密字节数组
return decrypt(bytes);
}
/**
* 将字符串加密成16进制字符串
*
* @param original
* @return
*/
public static String encryptStringToHex(String original) {
return encryptToHex(original.getBytes());
}
/**
* 从16进制字符串解密成原字符串
*
* @param original
* @return
*/
public static String decryptStringFromHex(String original) {
return new String(decryptFromHex(original));
}
/**
* 加密
*/
private void doEncrypt() {
System.err.println("-------------加密-------------");
Scanner scanner = new Scanner(System.in);
String original = scanner.next();
System.out.println(encryptStringToHex(original));
}
/**
* 解密
*/
private void doDecrypt() {
System.err.println("-------------解密-------------");
Scanner scanner = new Scanner(System.in);
String original = scanner.next();
System.out.println(decryptStringFromHex(original));
}
public static void main(String[] args) {
//加密
new EncryptDecrypt().doEncrypt();
//解密
// new EncryptDecrypt().doDecrypt();
}
@Test
public void test() {
int[] keys = generateKey(SALT.length());
for (int k : keys) {
System.out.print(k+", ");
}
System.out.println();
String original = "穷且益坚,不坠青云之志。";
String encrypt = encryptStringToHex(original);
System.out.println(encrypt);
System.out.println(decryptStringFromHex(encrypt));
encrypt = encryptToHex(original.getBytes());
System.out.println(encrypt);
System.out.println(new String(decryptFromHex(encrypt)));
original = "人生得意须尽欢,莫使金樽空对月。";
byte[] bytes = encryptString(original);
System.out.println(new String(bytes));
System.out.println(decryptToString(bytes));
bytes = encrypt(original.getBytes());
System.out.println(new String(bytes));
System.out.println(new String(decrypt(bytes)));
}
}
本人并不是专业研究安全领域的人,只是有个想法,然后顺便实现了一下。所以我也不清楚这个算法的安全性有多高,但至少用着方便,我也能安心记密码了。(表示连银行卡的密码都经常忘,好在现在支付宝都支持指纹了。)
后来根据需求,设计了一个基于异或的对称加密算法。算法非常简单:
1.先定义一个由一系列不规则字符组成的盐值(SALT),然后生成一个密钥,密钥是一个整数数组,里面的值随机生成,对应盐值字符串的下标。
2.加密时,根据密钥与盐值生成一个用来加密的字节数组。
3.通过这个字节数组,与被加密数据的字节数组进行异或操作
4.返回加密结果,由于异或的特性,解密过程同加密过程。
后来经过一些修改,将加密的字节数组转换为对应的16进制字符串(4位二进制表示一位16进制,根据这个规律生成)。这样就能将任何数据加密为一串字符串,解密时,先将这串字符串转换为对应的字节数组,再进行解密还原。
老规矩,上王者(呸,代码 最近有些沉迷游戏):
package com.myself.tryit;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* Created with IntelliJ IDEA
* Date: 2017/12/8
* Time: 上午11:04
*
* @author 陈樟杰
*/
public class EncryptDecrypt {
/**
* 盐值
*/
private static final String SALT = "dfsad@#%$@TDGDF%$#%@#%WFRGFDHJKcvxznmfdsgdfgs2432534fgdf46t";
/**
* 内部密钥
*/
private static final int[] KEY = {
23, 22, 24, 4, 51, 26, 37, 27, 24, 6, 26, 38, 29, 35, 18, 21, 14, 3, 12, 4, 41, 39, 18, 44, 54, 21, 33, 35, 31, 22, 34, 53, 51, 44, 8, 12, 3, 0, 28, 1, 48, 9, 51, 57, 20, 44, 27, 3, 16, 48
};
/**
* 16进制映射表
*/
private static final Map MMP = new HashMap(12);
static {
short i = 10;
for (; i < 16; i++) {
MMP.put(i, (char) ('A' + i - 10));
MMP.put((char) ('A' + i - 10), i);
}
}
/**
* 生成密钥
*
* @param len 密钥长度
* @return
*/
public static int[] generateKey(int len) {
int ceiling = SALT.length();
int[] key = new int[len];
for (int i = 0; i < len; i++) {
key[i] = (int) (Math.random() * ceiling);
}
return key;
}
/**
* 加密
*
* @param original
* @return
*/
public static byte[] encrypt(byte[] original) {
byte[] keyByte = new byte[KEY.length];
/**
* 获取加密字节数组
*/
for (int i = 0; i < KEY.length; i++) {
keyByte[i] = (byte) SALT.charAt(KEY[i]);
}
/**
* 加密
*/
int k = 0;
byte[] encryptByte = new byte[original.length];
for (int i = 0; i < original.length; i++) {
encryptByte[i] = (byte) (original[i] ^ keyByte[k++ % keyByte.length]);
}
return encryptByte;
}
/**
* 解密
*
* @param original
* @return
*/
public static byte[] decrypt(byte[] original) {
return encrypt(original);
}
/**
* 对字符串加密
* 由于解码时 byte数组不一定符合规范 所以解码算法可能会改变字节数组的值 所以只能返回字节数组 而不能返回字符串
*
* @param original
* @return
*/
public static byte[] encryptString(String original) {
return encrypt(original.getBytes());
}
/**
* 对字符串解密
*
* @param original
* @return
*/
public static String decryptToString(byte[] original) {
return new String(encrypt(original));
}
/**
* 加密成16进制字符串
*
* @param original
* @return
*/
public static String encryptToHex(byte[] original) {
//先加密
byte[] bytes = encrypt(original);
/**
* 将加密的字节数组转换成16进制字符串
*/
StringBuffer stringBuffer = new StringBuffer("");
for (int i = 0; i < bytes.length; i++) {
short a = (short) (bytes[i] & 15);
short b = (short) ((bytes[i] & (15 << 4)) >>> 4);
if (b < 10) {
stringBuffer.append(b);
} else {
stringBuffer.append(MMP.get(b));
}
if (a < 10) {
stringBuffer.append(a);
} else {
stringBuffer.append(MMP.get(a));
}
}
return stringBuffer.toString();
}
/**
* 从16进制字符串解密
*
* @param original
* @return
*/
public static byte[] decryptFromHex(String original) {
/**
* 将16进制字符串转换成字节数组
*/
byte[] bytes = new byte[original.length() / 2];
int len = 0;
for (int i = 0; i < original.length(); i += 2) {
short a, b;
if (original.charAt(i) >= '0' && original.charAt(i) <= '9') {
a = (short) (original.charAt(i) - '0');
a <<= 4;
} else {
a = (short) MMP.get(original.charAt(i));
a <<= 4;
}
if (original.charAt(i + 1) >= '0' && original.charAt(i + 1) <= '9') {
b = (short) (original.charAt(i + 1) - '0');
} else {
b = (short) MMP.get(original.charAt(i + 1));
}
bytes[len++] = (byte) (a + b);
}
//解密字节数组
return decrypt(bytes);
}
/**
* 将字符串加密成16进制字符串
*
* @param original
* @return
*/
public static String encryptStringToHex(String original) {
return encryptToHex(original.getBytes());
}
/**
* 从16进制字符串解密成原字符串
*
* @param original
* @return
*/
public static String decryptStringFromHex(String original) {
return new String(decryptFromHex(original));
}
/**
* 加密
*/
private void doEncrypt() {
System.err.println("-------------加密-------------");
Scanner scanner = new Scanner(System.in);
String original = scanner.next();
System.out.println(encryptStringToHex(original));
}
/**
* 解密
*/
private void doDecrypt() {
System.err.println("-------------解密-------------");
Scanner scanner = new Scanner(System.in);
String original = scanner.next();
System.out.println(decryptStringFromHex(original));
}
public static void main(String[] args) {
//加密
new EncryptDecrypt().doEncrypt();
//解密
// new EncryptDecrypt().doDecrypt();
}
@Test
public void test() {
int[] keys = generateKey(SALT.length());
for (int k : keys) {
System.out.print(k+", ");
}
System.out.println();
String original = "穷且益坚,不坠青云之志。";
String encrypt = encryptStringToHex(original);
System.out.println(encrypt);
System.out.println(decryptStringFromHex(encrypt));
encrypt = encryptToHex(original.getBytes());
System.out.println(encrypt);
System.out.println(new String(decryptFromHex(encrypt)));
original = "人生得意须尽欢,莫使金樽空对月。";
byte[] bytes = encryptString(original);
System.out.println(new String(bytes));
System.out.println(decryptToString(bytes));
bytes = encrypt(original.getBytes());
System.out.println(new String(bytes));
System.out.println(new String(decrypt(bytes)));
}
}
本人并不是专业研究安全领域的人,只是有个想法,然后顺便实现了一下。所以我也不清楚这个算法的安全性有多高,但至少用着方便,我也能安心记密码了。(表示连银行卡的密码都经常忘,好在现在支付宝都支持指纹了。)
相关文章推荐
- 简易加密算法,用于字符串加密
- 教你3分钟了解Android 简易时间轴的实现方法
- OPenJWeb快速开发平台中的简易审批流的实现
- POI简易帮助文档系列--读取Excel文件
- 搭建简易ZK框架并实现简单交互
- BSD Socket 简易入门手册
- heroku 简易中文教程
- 数据冒险之单链表(简易通信录)
- 简易Java框架开源论坛系统0.5.0版本发布
- Linux Kernel(Android) 加密算法总结(一)(cipher、compress、digest)
- Django REST framework笔记一之简易JsonAPI搭建(可使用)
- 在下拉列表框中显示多列的两种简易实现方式
- File类输入输出流的重要用法及文件搜索器的简易实现
- Unity之简易定时器Timer
- MySQL简易备份方法
- 简易计算程序运行次数
- 加密算法详解 DES、3DES、AES、RSA、MD5、sha1
- 使用ultraedit和cl编译器打造简易c-c++开发环境【转】
- 腾讯webqq最新password加密算法,hash算法
- 用UDP协议写简易聊天室