基于超奇偶性的高速对称加密算法
郝伟 2020/05/27

简介

对称加密指加密和解密所使用的密钥都是是一把解密,而非对称加密指加密和解密使用的不是同一种密钥,性能上要比对称加密弱很多。对称加密:AES(AdvancedEncryptionStandard)算法作为加密的标准算法[]因其可靠、高效、安全性能高得到了广泛应用。然而,大量用户容易形成对服务器突发大量的访问请求,而且传统的AES串行方式的加密效率低下,不能满足流式加密的速度和服务质量需求。本文研究是一种高效率的对称加密,具有运行速度级快,算法简单,安全性好等特点,并在数学上证明在没有密钥(包括间接)的情况下,实现数据的绝对安全。

本公开的实施例提供了一种对称加密方法,此加密方法包括获取待加密明文二进制数组input;使用密钥二进制数组key对所述待加密明文二进制数组input进行异或加密,生成密文二进制数组output;根据所述待加密明文二进制数组input得到随机数b;根据所述随机数b对所述密文二进制数组output进行奇偶性随机混合,得到奇偶性随机混合加密结果二进制数组output′。以此方式,利用了大容量密钥、异或数据加密和基于异或奇偶性的数据乱序算法,能够在保证数据安全性的前提下,提高加解密运算速度。

源代码

package test;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileEncryption {
	static String input = "D:\\Research\\20200522_ImageEncrpytion\\WindowsFormsApp1\\bin\\Debug\\GameOfThroneS01E01.mkv"; // 可以是任何大文件
	static String output = "D:\\Research\\20200522_ImageEncrpytion\\WindowsFormsApp1\\bin\\Debug\\GameOfThroneS01E01_out.mkv";
	static String output1 = "D:\\Research\\20200522_ImageEncrpytion\\WindowsFormsApp1\\bin\\Debug\\GameOfThroneS01E01_out1.mkv";
	static String key = "SunBeach.jpg";

	public static void main(String[] args) throws Exception {
		// 使用密钥对指定的文件加密。
		Encrypt(input, output, key, 0);
		Encrypt(output, output1, key, 1);
	}

	public static String Info = null;
	public static int maxsize = 1048576;
	static int[] ones = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4,
			5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2,
			3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4,
			5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,
			4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
			6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4,
			5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6,
			7, 5, 6, 6, 7, 6, 7, 7, 8 };


	public static byte[] readKey(String file, int length){
		byte[] key;
		
		
		return key;
	}

	public static boolean Encrypt(String infile, String outfile, String keyfile, int type) throws Exception {
		byte[] key = readBytes(keyfile, maxsize);
		FileInputStream fin = new FileInputStream(infile);
		FileOutputStream fout = new FileOutputStream(outfile);
		long total = fin.available();
		byte[] bts = new byte[maxsize];
		double t1 = 0, t2 = 0, t3 = 0;
		int readCount = maxsize;
		byte bx = 0b1010110;
		while (readCount >= maxsize) {
			long dt1 = System.nanoTime();
			readCount = fin.read(bts, 0, maxsize);
			long dt2 = System.nanoTime();
			bx = getBX(bts, key, type);
			// System.out.println("Bx=" + (bx & 0xff));
			for (int i = 0; i < readCount; i++)
				bts[i] ^= key[i] ^ bx;
			long dt3 = System.nanoTime();
			fout.write(bts, 0, readCount);
			long dt4 = System.nanoTime();

			t1 += dt2 - dt1;
			t2 += dt3 - dt2;
			t3 += dt4 - dt3;
		}
		fin.close();
		fout.close();

		t1 /= 1000000000.0;
		t2 /= 1000000000.0;
		t3 /= 1000000000.0;

		String speed_reading = String.format("%.6f", total / t1 / 1073741824);
		String speed_encryption = String.format("%.6f", total / t2 / 1073741824);
		String speed_writing = String.format("%.6f", total / t3 / 1073741824);

		Info = String.format("总用时:%.4f s, 总容量:%.4f GB.\n", t1 + t2 + t3, total / 1024.0 / 1024 / 1024);
		Info += String.format("读取用时  %4f s, 速度:%s GB/s\n", t1, speed_reading);
		Info += String.format("加密用时  %4f s, 速度:%s GB/s\n", t2, speed_encryption);
		Info += String.format("写入用时  %4f s, 速度:%s GB/s\n", t3, speed_writing);
		System.out.println(Info);
		return true;
	}

	private static byte getBX(byte[] bts, byte[] key, int etype) {
		return etype == 0 ? encrypt(bts, key) : decrypt(bts, key);
	}

	private static byte decrypt(byte[] bts, byte[] key) {
		if (bts.length <= 1024)
			return 0;

		int offset = 0, pos = 0;
		for (int i = 0, w = 1; i < 8; i++, w *= 2)
			offset += ((ones[bts[i] & 0xff] + 100 - ones[key[i] & 0xff]) % 2) * w;
		// System.out.println("offset2: " + (offset & 0xff));

		for (int i = 0, w = 1; i < 8; i++, w *= 2) {
			int even = (ones[bts[(i + offset) % bts.length] & 0xff] + 100 - ones[key[i + offset] & 0xff]) % 2;
			pos += even == 0 ? 0 : w;
		}

		byte b = (byte) (pos & 0xff);
		while (ones[b & 0xff] % 2 > 0)
			b = (byte) (b << 1);

		return b;
	}

	private static byte encrypt(byte[] bts, byte[] key) {
		if (bts.length <= 1024)
			return (byte) 0xff;
		int offset = 0, pos = 0;
		for (int i = 0, w = 1; i < 8; i++, w *= 2)
			offset += ones[bts[i] & 0xff] % 2 == 0 ? 0 : w;

		for (int i = 0, w = 1; i < 8; i++, w *= 2) {
			int odd = (ones[bts[(i + offset) % bts.length] & 0xff]) % 2;
			pos += odd == 0 ? 0 : w;
		}

		byte b = (byte) (pos & 0xff);
		while (ones[b & 0xff] % 2 > 0)
			b = (byte) (b << 1);

		return b;
	}

	public static byte[] readBytes(String keyfile, int maxsize) throws Exception {
		byte[] bts = new byte[maxsize];
		FileInputStream fs = new FileInputStream(keyfile);
		int left = maxsize, p = 0;
		while (left > 0) {
			p += fs.read(bts, maxsize - left, left);
			left -= p;
		}
		fs.close();
		return bts;
	}
}

性能测试结果

总用时:2.0012 s, 总容量:0.7685 GB.
读取用时  1.228805 s, 速度:0.625438 GB/s
加密用时  0.126546 s, 速度:6.073212 GB/s
写入用时  0.645808 s, 速度:1.190045 GB/s

总用时:1.1109 s, 总容量:0.7685 GB.
读取用时  0.445182 s, 速度:1.726352 GB/s
加密用时  0.055458 s, 速度:13.858152 GB/s
写入用时  0.610306 s, 速度:1.259273 GB/s

其他

【悬赏】
任务目标:在非破解程序的前提下,通过观察输入和输出分析出加密方法或密钥。
悬赏金额:200元
运行方式:在安装了JDK1.8及以上版本后,在程序文件目录下输入  
                  for /L %i in (1,1,10) do java FastEncryption str
注意事项:此为非重要任务,不要影响正常工作。
推荐指令: for /L %i in (1,1,10) do java FastEncryption str%i