钥控加密算法

钥控加密

      • 一、目的
      • 二、算法原理
      • 三、算法设计
        • 加密函数:
          • 1、对密钥处理
          • 2、对内容加密
        • 解密函数:
          • 1、对密钥处理
          • 2、对内容解密
      • 四、实现代码(C#)
      • 五、运行结果
      • 六、开源地址

一、目的

对给定的明文进行加密,比双轨加密更加复杂,破解难度更大。

二、算法原理

明文排成矩阵,密钥写在矩阵的上边,按密钥字母在字母表中排序把矩阵按列写出即为密文。

三、算法设计

加密函数:

  • 输入参数为①明文内容②密钥
  • 返回内容为加密后的密文
1、对密钥处理
  • 对密钥除重,得到无重复字符的密钥
  • 按照字母先后顺序得到 一个序列数组(用于密文的生成)
2、对内容加密
  • 按照密钥长度对明文内容进行分组(切片)
  • 按照密钥序列数组取值,生成密文

解密函数:

  • 输入参数为①密文内容②密钥
  • 返回内容为解密后的明文
1、对密钥处理
  • 对密钥进行解析,获取反序列数组
  • 根据密钥反序列数组重排加密内容
2、对内容解密
  • 根据已重排的加密内容,还原明文分组内容(恢复切片)
  • 重组分片内容,得到解密后的明文

四、实现代码(C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SSLHomework1.Service
{
    /// 
    /// 钥控加密
    /// 
    class KeyControl : IKeyControl
    {
        /// 
        /// 加密
        /// 
        /// 
        /// 
        public string Encrypt(string content,string key) {
            if (content.Length>0 && key.Length>0) {
                List<string> ciphertext = new List<string>(); //存放密文
                var resultKey = getSequence(KeyHanding(key)); //获取处理后的key信息
                int groupNum = content.Length / resultKey.Length; //分片数
                int groupLength = groupNum * resultKey.Length; //分片总长度
                int leftLenth = content.Length - groupLength; //分片后剩余的部分长
                //对于分组内的数据处理
                for (int i = 0; i < resultKey.Length; i++) {
                    ciphertext.Add(string.Empty); //实例化密文对象
                    bool tag = true;
                    int length = 0; //间隔位置
                    while (tag) {
                        ciphertext[i] += content[i + length].ToString();
                        length += resultKey.Length; //跳到下一片
                        if (!(length < groupLength)) {
                            tag = false; //如果超出分片总长则跳出
                        }
                    }
                }
                //对于分组外的数据处理
                if (leftLenth>0) {
                    for (int i = 0; i < leftLenth; i++) {
                        ciphertext[i] += content[i + groupLength];//将分片后剩余的部分加入到密文
                    }
                } else {
                    Console.WriteLine("没有分组后的剩余部分");
                }
                // Console.WriteLine(string.Join("\n", ciphertext).ToUpper());
                //将分组后的密文按照密钥序列排列,并将字母全部转换成大写
                return string.Join("\n",changeTheOrder(resultKey,ciphertext)).ToUpper();
            } else {
                Console.WriteLine("没有明文或者没有密钥");
                return string.Empty;
            }
        }

        /// 
        /// 解密
        /// 
        /// 
        /// 
        public string Deciphering(string content,string key) {
            if (content.Length>0 && key.Length>0) {
                List<string> decryption = new List<string>();
                string result = string.Empty;
                var resultKey = getUnSequence(getSequence(KeyHanding(key)));//获取解密的密钥
                var contentArray = changeTheOrder(resultKey,content.Split("\n").ToArray().ToList());//获取原来序列的密文
                // Console.WriteLine(string.Join("\n",contentArray));
                var groupNum = GetShortest(contentArray);//获取加密时选择的分片数
                //先按照最短的字符串划分原来的分片内容
                for (int i = 0; i < groupNum; i++) {
                    string temp = string.Empty;
                    for (int j = 0; j < resultKey.Length; j++) {
                        temp += contentArray[j][i].ToString();//对每片都取同一位置的字符
                    }
                    decryption.Add(temp.ToLower());
                }

                // Console.WriteLine(string.Join("", decryption));
                result = string.Join("", decryption);
                //将剩余的1一个字符拼接回原来的分片
                for (int i = 0; i < resultKey.Length; i++) {
                    if (contentArray[i].Length>groupNum) {
                        result +=
                            contentArray[i].ToLower()[groupNum];
                    }
                }
                return result;
            } else {
                return string.Empty;
            }
        }

        /// 
        /// 对密钥处理,返回处理后的密钥以及密钥序列
        /// 
        /// 
        /// 
        private string KeyHanding(string key) {
            string result = string.Empty;
            int length = key.Length;
            if (length > 0) {
                string newKey = string.Empty;
                int ilength = length - 1;
                //获取除去重复字符后的密钥
                int i;
                for (i=0; i < ilength; i++) {
                    bool tag = false;//是否有重复标记,false为无,有为true
                    for (int j = i+1; j < length; j++) {
                        if (key[i].Equals(key[j])) {
                            tag = true;
                            break;
                        }
                    }
                    //不重复时则把它的值取出来,重复的取最后一个不重复的值
                    if (!tag) {
                        newKey += key[i].ToString();
                    }
                }
                newKey += key[i].ToString();
                // Console.WriteLine(newKey);//获得新的密钥
                result = newKey;
            } else {
                Console.WriteLine("没有密钥");
            }
            return result;
        }

        /// 
        /// 获取序列数组
        /// 
        /// 
        /// 
        private string getSequence(string newKey) {
            //获取出去重复字符后的密钥序列数组
            List<int> sequence = new List<int>();
            int length = newKey.Length - 1;
            for (int k = 0; k < newKey.Length; k++)
            {
                sequence.Add(0);
            }
            // Console.WriteLine(string.Join("", sequence));
            int ilength = newKey.Length - 1;
            for (int i = 0; i < ilength; i++)
            {
                for (int j = i + 1; j < newKey.Length; j++)
                {
                    if (newKey[i] < newKey[j]) {
                        sequence[j]++;
                    } else if (newKey[i] > newKey[j]) {
                        sequence[i]++;
                    }
                }
            }
            // Console.WriteLine(string.Join("",sequence));
            return string.Join("", sequence);
        }

        /// 
        /// 获取反序列数组
        /// 
        /// 
        /// 
        private string getUnSequence(string newKey)
        {
            //根据密钥获取反序列
            List<int> sequence = new List<int>();
            for (int k = 0; k < newKey.Length; k++)
            {
                sequence.Add(0);
            }
            var listKey = newKey.ToList();
            for (int i = 0; i < newKey.Length; i++) {
                // Console.WriteLine(listKey.FindIndex(ss=> ss.Equals((char)(i + 48))));
                sequence[i] = listKey.FindIndex(x=> x.Equals((char)(i + 48)));
            }
            // Console.WriteLine(string.Join("",sequence));
            return string.Join("", sequence);
        }

        /// 
        /// 交换序列顺序
        /// 
        /// 
        /// 
        /// 
        private List<string> changeTheOrder(string resultKey,
            List<string> ciphertext)
        {
            List<string> result = new List<string>();
            int keyNum = 0;
            while (keyNum < resultKey.Length)
            {
                for (int i = 0; i < resultKey.Length; i++)
                {
                    if (keyNum.Equals(resultKey[i] - 48))
                    {
                        result.Add(ciphertext[i]);
                        break;
                    }
                }
                keyNum++;
            }
            return result;
        }

        /// 
        /// 获取最短组
        /// 
        /// 
        /// 
        private int GetShortest(List<string> content)
        {
            if (content.Count > 0)
            {
                int shortest = content[0].Length;
                foreach (var p in content)
                {
                    if (p.Length < shortest)
                    {
                        shortest = p.Length;
                    }
                }
                return shortest;
            }
            else
            {
                return 0;
            }
        }
    }
}

五、运行结果

钥控加密算法_第1张图片

六、开源地址

码云keyControl分支

(https://gitee.com/plasma/Information-security-basics-study-notes.git)

你可能感兴趣的:(学习笔记)