C#笔记:RC6算法实现 public class RC6Cryptor { public byte[] Encrypt(byte[] data, string pwd) { SymmetricAlgorithm sa = Rc6.Create(); // byte[] inputByteArray = data;//得到需要加密的字节数组 //设置密钥及密钥向量 sa.Key = Encoding.UTF8.GetBytes(pwd); sa.IV = null; byte[] cipherBytes = null; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, sa.CreateEncryptor(), CryptoStreamMode.Write)) { cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); cipherBytes = ms.ToArray();//得到加密后的字节数组 } } return cipherBytes; } public byte[] Decrypt(byte[] data, string pwd) { SymmetricAlgorithm sa = Rc6.Create(); byte[] inputByteArray = data;//得到需要加密的字节数组 //设置密钥及密钥向量 sa.Key = Encoding.UTF8.GetBytes(pwd); sa.IV = null; byte[] textBytes = null; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, sa.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(inputByteArray, 0, inputByteArray.Length); cs.FlushFinalBlock(); textBytes = ms.ToArray();//得到加密后的字节数组 } } return textBytes; } } public class Rc6 : SymmetricAlgorithm { public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) { var tempCrytor = new RC6Transform(rgbKey); tempCrytor.Type = "dec"; return tempCrytor; } public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV) { var tempCrytor = new RC6Transform(rgbKey); tempCrytor.Type = "enc"; return tempCrytor; } public override void GenerateIV() { //do nothing } public override byte[] Key { get { return this.KeyValue; } set { var key = padding(value, 32); this.KeyValue = key; } } public override byte[] IV { get { return new byte[1]; } set { if (value != null && value.Length > 1) throw new CryptographicException("RC6 doesn't use an Initialization Vector."); } } private byte[] padding(byte[] inputBuffer, int BlockSize) { if (BlockSize > 255) { throw new CryptographicException("The blocksize can not be greater than 255"); } int count = 0; if (inputBuffer.Length == 0) { count = BlockSize; } else if (inputBuffer.Length % BlockSize == 0) { return inputBuffer; } else { count = BlockSize - inputBuffer.Length % BlockSize; } byte[] ret = new byte[inputBuffer.Length + count]; for (int i = 0; i < inputBuffer.Length; i++) { ret[i] = (byte)inputBuffer[i]; } for (int i = inputBuffer.Length; i < ret.Length; i++) { ret[i] = (byte)count; } return ret; } public override void GenerateKey() { // doNothing } public static new Rc6 Create() { return new Rc6(); } } public class RC6Transform : ICryptoTransform { private const int w = 32; private const int b = 16; //16,24,32 private const int r = 20; private const uint P32 = 0xB7E15163; private const uint Q32 = 0x9E3779B9; private const int bytes = w / 8; private const int c = (b + bytes - 1) / bytes; private const int R24 = 2 * r + 4; private const int lgw = 5; private uint[] S; private int keyLen; public string Type; public RC6Transform(byte[] key) { int Round = 32; //Round = 16; //Round = 24; this.S = new uint[Round * 8]; //选择加密方式128位,192位,256位 this.keyLen = Round; char[] _key = this.key(key); this.setup(_key, this.keyLen); //setup(_key, 16);初始化,将私密与系统密钥混合 } public bool CanReuseTransform { get { return true; } } public bool CanTransformMultipleBlocks { get { return true; } } public int InputBlockSize { get { return 16; } } public int OutputBlockSize { get { return 16; } } public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { if (this.Type == "enc") { int length = inputCount; byte[] orgCopy = new byte[length]; Array.Copy(inputBuffer, inputOffset, orgCopy, 0, length); orgCopy = this.EncryptBuffer(orgCopy); Array.Copy(orgCopy, 0, outputBuffer, 0, length); return length; } else { int length = inputOffset + inputCount; byte[] orgCopy = new byte[inputCount]; Array.Copy(inputBuffer, inputOffset, orgCopy, 0, inputCount); orgCopy = this.DecryptBuffer(orgCopy); length = length - IsPadding(orgCopy); Array.Copy(orgCopy, 0, outputBuffer, outputOffset, length); return length; } } private int IsPadding(byte[] orgCopy) { int count = orgCopy[orgCopy.Length - 1]; if (count <= 255) { for (int i = orgCopy.Length - 1, j = 0; j < count; i--, j++) { if (orgCopy[i] != count) { return 0; } } } else { return 0; } return count; } public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { int length = inputCount; if (inputCount == 0) return new byte[0]; byte[] ret = padding(inputBuffer, InputBlockSize, inputCount); ret = this.EncryptBuffer(ret); return ret; } private byte[] padding(byte[] inputBuffer, int BlockSize, int inputCount) { int count = BlockSize - inputCount; byte[] ret = new byte[inputCount + count]; for (int i = 0; i < inputCount; i++) { ret[i] = (byte)inputBuffer[i]; } for (int i = inputCount; i < ret.Length; i++) { ret[i] = (byte)count; } return ret; } public void Dispose() { try { GC.SuppressFinalize(this); } catch { } } private uint ROTL(uint x, uint y) { return ((x << (int)(y & (w - 1))) | (x >> (int)(w - (y & (w - 1))))); } private uint ROTR(uint x, uint y) { return ((x >> (int)(y & (w - 1))) | (x << (int)(w - (y & (w - 1))))); } public char[] key(byte[] key) { // pwd = (pwd.Length % 16 != 0 ? pwd.PadRight(pwd.Length + (16 - (pwd.Length % 16)), ' ') : pwd); //这里必须保证加密私密的密码长为为16,不足加空隔满足长度需要 byte[] asciiBytes = Encoding.Convert(Encoding.UTF8, Encoding.ASCII, key); char[] asciiChars = new char[Encoding.ASCII.GetCharCount(asciiBytes, 0, asciiBytes.Length)]; Encoding.ASCII.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0); return asciiChars; } /// <summary> /// 初始化并混合用户密钥 /// </summary> /// <param name="K"></param> /// <param name="b"></param> public void setup(char[] K, int b) { int i, j, s, v; uint[] L = new uint[b]; /* Big enough for max b */ uint A, B; L[b - 1] = 0; for (i = 15 - 1; i >= 0; i--) L[i / bytes] = (L[i / bytes] << 8) + K[i]; S[0] = P32; unchecked { for (i = 1; i <= 2 * r + 3; i++) S[i] = S[i - 1] + Q32; } A = B = 0; i = j = 0; v = R24; if (c > v) v = c; v *= 3; unchecked { for (s = 1; s <= v; s++) { A = S[i] = ROTL(S[i] + A + B, 3); B = L[j] = ROTL(L[j] + A + B, A + B); i = (i + 1) % R24; j = (j + 1) % c; } } } public byte[] EncryptBuffer(byte[] buffer) { int UpperBound = buffer.Length - 15; for (int i = 0; i < UpperBound; i += 16) { uint A = BitConverter.ToUInt32(buffer, i); uint B = BitConverter.ToUInt32(buffer, i + 4); uint C = BitConverter.ToUInt32(buffer, i + 8); uint D = BitConverter.ToUInt32(buffer, i + 12); unchecked { B += S[0]; D += S[1]; for (int j = 2; j <= 2 * r; j += 2) { uint t = ROTL(B * (2 * B + 1), lgw); uint u = ROTL(D * (2 * D + 1), lgw); A = ROTL(A ^ t, u) + S[j]; C = ROTL(C ^ u, t) + S[j + 1]; uint x = A; A = B; B = C; C = D; D = x; } A += S[2 * r + 2]; C += S[2 * r + 3]; } BitConverter.GetBytes(A).CopyTo(buffer, i); BitConverter.GetBytes(B).CopyTo(buffer, i + 4); BitConverter.GetBytes(C).CopyTo(buffer, i + 8); BitConverter.GetBytes(D).CopyTo(buffer, i + 12); } return buffer; } public byte[] DecryptBuffer(byte[] buffer) { int UpperBound = buffer.Length - 15; for (int i = 0; i < UpperBound; i += 16) { uint A = BitConverter.ToUInt32(buffer, i); uint B = BitConverter.ToUInt32(buffer, i + 4); uint C = BitConverter.ToUInt32(buffer, i + 8); uint D = BitConverter.ToUInt32(buffer, i + 12); unchecked { C -= S[2 * r + 3]; A -= S[2 * r + 2]; for (int j = 2 * r; j >= 2; j -= 2) { uint x = D; D = C; C = B; B = A; A = x; uint u = ROTL(D * (2 * D + 1), lgw); uint t = ROTL(B * (2 * B + 1), lgw); C = ROTR(C - S[j + 1], t) ^ u; A = ROTR(A - S[j], u) ^ t; } D -= S[1]; B -= S[0]; } BitConverter.GetBytes(A).CopyTo(buffer, i); BitConverter.GetBytes(B).CopyTo(buffer, i + 4); BitConverter.GetBytes(C).CopyTo(buffer, i + 8); BitConverter.GetBytes(D).CopyTo(buffer, i + 12); } return buffer; } } 来自 大脸猫 写于 2015-02-15 18:28 -- 更新于2020-10-19 13:06 -- 0 条评论