您的位置:首页 > 其它

自创简易加密算法

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)));
}

}
本人并不是专业研究安全领域的人,只是有个想法,然后顺便实现了一下。所以我也不清楚这个算法的安全性有多高,但至少用着方便,我也能安心记密码了。(表示连银行卡的密码都经常忘,好在现在支付宝都支持指纹了。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息