/// <summary> /// 初始化 /// </summary> /// <param name="cfg">初始化使用的配置</param> private void Initialize(Config cfg) { if (_isInitialized) throw new InvalidOperationException("already initialized."); System.Diagnostics.Debug.WriteLine("IPMClient 开始初始化...端口:" + cfg.Port.ToString()); _context = SynchronizationContext.Current; SynchronizationContext = SynchronizationContext.Current; LocalAddresses = Helper.GetLocalAddresses(); this.Config = cfg; if (cfg.BindedIP == null) cfg.BindedIP = IPAddress.Any; //开始构造对象 Commander = new CommandExecutor(this); Commander.Init(); //初始化插件 InitializeServiceProvider(); //初始化调试器 Debugger = new Debug.DebugHelper(); Debugger.AttachHelperAuto(this); this._isInitialized = Commander.IsInitialized; }
/// <summary> /// 加密信息 /// </summary> /// <param name="cmd">Commander</param> /// <param name="e">事件参数</param> void EncryptMessage(CommandExecutor cmd, Entity.MessageEventArgs e) { Entity.Host host = null; if (cmd.LivedHost == null || (host = cmd.LivedHost.GetHost(e.Message.HostAddr.Address.ToString())) == null || !host.SupportEncrypt) return; if (host.PubKey == null) { //压入队列 if (host.QueuedMessage == null) host.QueuedMessage = new Queue<FSLib.IPMessager.Entity.Message>(); host.QueuedMessage.Enqueue(e.Message); e.IsHandled = true; //请求公钥 GetPubKey(host); } else { if (e.Message.NormalMsgBytes == null) { System.Text.Encoding enc = e.Message.IsEncodingUnicode ? System.Text.Encoding.Unicode : System.Text.Encoding.Default; if (!string.IsNullOrEmpty(e.Message.NormalMsg)) e.Message.NormalMsgBytes = enc.GetBytes(e.Message.NormalMsg); else e.Message.NormalMsgBytes = new byte[] { 0 }; if (!string.IsNullOrEmpty(e.Message.ExtendMessage)) e.Message.ExtendMessageBytes = enc.GetBytes(e.Message.ExtendMessage); else e.Message.ExtendMessageBytes = new byte[] { 0 }; } if (e.Message.NormalMsgBytes == null) return; //加密 if (host.IsEncryptUseSmallKey) { //RSA512&&RC2 //暂时不支持。。。 //TODO:加密支持RC2 e.Message.IsEncrypt = false; } else { //RSA1024&BlowFish byte[] key = new byte[8]; rcsp.GetBytes(key); blowFish.Initialize(key, 0, key.Length); byte[] content = new byte[(int)Math.Ceiling(e.Message.NormalMsgBytes.Length / 16.0) * 16]; //BlowFish加密必须是16字节的整数倍 e.Message.NormalMsgBytes.CopyTo(content, 0); blowFish.Encrypt(content, 0, content, 0, content.Length); blowFish.Invalidate(); //加密Key RSAParameters p = new RSAParameters() { Modulus = host.PubKey, Exponent = host.Exponent }; RSA_1024_Encryptor.ImportParameters(p); key = RSA_1024_Encryptor.Encrypt(key, false); //Array.Reverse(key); //组装消息 System.Text.StringBuilder sb = new StringBuilder(); sb.Append(EncryptNormalCapa.ToString("x")); sb.Append(":"); sb.Append(key.ConvertToString()); sb.Append(":"); sb.Append(content.ConvertToString()); e.Message.NormalMsg = sb.ToString(); e.Message.NormalMsgBytes = null; } } }
/// <summary> /// 解析加密信息 /// </summary> /// <param name="cmd">Commander</param> /// <param name="e">事件参数</param> void DecryptMessage(CommandExecutor cmd, Entity.MessageEventArgs e) { int index = 0; int nextMatch = 0; if ((nextMatch = e.Message.NormalMsg.IndexOf(':', index)) == -1) return; ulong capa; if (!ulong.TryParse(e.Message.NormalMsg.Substring(index, nextMatch - index), System.Globalization.NumberStyles.AllowHexSpecifier, null, out capa)) return; //查找密钥 index = nextMatch + 1; if ((nextMatch = e.Message.NormalMsg.IndexOf(':', index)) == -1) return; byte[] buf = e.Message.NormalMsg.ConvertToBytes(index, nextMatch); //消息加密内容 byte[] content = e.Message.NormalMsg.ConvertToBytes(nextMatch + 1, e.Message.NormalMsg.Length); //解密密钥 bool isSuccess = false; Define.Consts.Cmd_Encrpy_Option encOpt = (Define.Consts.Cmd_Encrpy_Option)capa; if ((encOpt & Consts.Cmd_Encrpy_Option.RSA_1024) == Consts.Cmd_Encrpy_Option.RSA_1024) { //RSA1024 try { buf = this.RSA_1024_Decryptor.Decrypt(buf, false); isSuccess = true; } catch (Exception) { } } else { try { buf = this.RSA_512_Decryptor.Decrypt(buf, false); isSuccess = true; } catch (Exception) { } } if (!isSuccess) { if ((encOpt & Consts.Cmd_Encrpy_Option.RSA_1024) == Consts.Cmd_Encrpy_Option.RSA_1024) { cmd.SendCommand(e.Message.HostAddr, Consts.Commands.SendMsg, 0ul, "[AUTO=PUBKEY_EXP]\n\n公钥已经过期,无法解密信息,请刷新主机列表。", "", false, false, true, true, true, false, false, false); e.IsHandled = true; //过滤掉消息 return; } else { cmd.SendCommand(e.Message.HostAddr, Consts.Commands.SendMsg, 0ul, "[AUTO=KEY_NOT_SUPPORT]\n\n您的客户端所使用的加密等级过低,无法支持。", "", false, false, true, true, true, false, false, false); e.IsHandled = true; //过滤掉消息 return; } } else { //解密文本 if ((encOpt & Consts.Cmd_Encrpy_Option.RC2_40) == Consts.Cmd_Encrpy_Option.RC2_40) { //TODO:RC2加密解决 } else { //BlowFish blowFish.Initialize(buf, 0, buf.Length); blowFish.Decrypt(content, 0, content, 0, content.Length); blowFish.Invalidate(); } int endIndex = Array.FindIndex(content, (s) => s == 0); if (endIndex == -1) endIndex = content.Length; if (Define.Consts.Check(e.Message.Options, Define.Consts.Cmd_Send_Option.Content_Unicode)) { e.Message.NormalMsg = System.Text.Encoding.Unicode.GetString(content, 0, endIndex); } else { e.Message.NormalMsg = System.Text.Encoding.Default.GetString(content, 0, endIndex); } } }
/// <summary> /// 将信息解密函数挂钩 /// </summary> /// <param name="cmd"></param> public void HandleEncryptedMessage(CommandExecutor cmd) { //加密信息预先解密 cmd.TextMessageReceiving += (s, e) => { if (!e.IsHandled && e.Message.IsEncrypt) { DecryptMessage(cmd, e); } }; cmd.MessageProxy.MessageSending += (s, e) => { if (!e.IsHandled && e.Message.Command == Consts.Commands.SendMsg && e.Message.IsEncrypt) { EncryptMessage(cmd, e); } }; cmd.MessageProcessing += (s, e) => { if (e.IsHandled || e.Host == null) return; if (e.Message.Command == Consts.Commands.AnsPubKey) { //发送确认消息 MessageProxy.SendWithNoCheck(e.Host, Consts.Commands.RecvMsg, 0ul, e.Message.PackageNo.ToString(), ""); //分析 int index = e.Message.NormalMsg.IndexOf(":"); if (index == -1) return; ulong capa; if (!ulong.TryParse(e.Message.NormalMsg.Substring(0, index++), System.Globalization.NumberStyles.AllowHexSpecifier, null, out capa)) return; if ((capa & EncryptCapa) == 0) return; e.Host.SupportEncrypt = true; e.Host.IsEncryptUseSmallKey = (capa & EncryptNormalCapa) == 0; int nextMatch; if ((nextMatch = e.Message.NormalMsg.IndexOf('-', index)) == -1) return; byte[] exp = e.Message.NormalMsg.Substring(index, nextMatch - index).ConvertToBytes(); if (exp == null) return; byte[] pubKey = e.Message.NormalMsg.Substring(nextMatch + 1).ConvertToBytes(); if (pubKey == null) return; e.Host.SetEncryptInfo(pubKey, exp); //查看有没有队列消息,有就发出去 if (e.Host.QueuedMessage != null && e.Host.QueuedMessage.Count > 0) { Message m = null; while (e.Host.QueuedMessage.Count > 0) { m = e.Host.QueuedMessage.Dequeue(); MessageProxy.Send(m); } } } else if (e.Message.Command == Consts.Commands.GetPubKey) { ulong capa; if (!ulong.TryParse(e.Message.NormalMsg, System.Globalization.NumberStyles.AllowHexSpecifier, null, out capa)) return; if ((capa & EncryptCapa) == 0) return; //返回响应 e.Host.SupportEncrypt = true; e.Host.IsEncryptUseSmallKey = (capa & EncryptNormalCapa) == 0; byte[] key = e.Host.IsEncryptUseSmallKey ? PublicKey_512 : PublicKey_1024; byte[] exp = e.Host.IsEncryptUseSmallKey ? Exponent_512 : Exponent_1024; string content = string.Format("{0}:{1}-{2}", EncryptCapa.ToString("x"), BitConverter.ToString(exp).Replace("-", ""), BitConverter.ToString(key).Replace("-", "")).ToLower(); MessageProxy.SendWithNoCheck(e.Host, Consts.Commands.AnsPubKey, 0ul, content, ""); } }; }