AES加密和WCF问题

SEM开发人员

感谢您抽出宝贵时间阅读本期杂志!使用AES加密时,WCF服务调用出现问题。不使用加密时不会发生此问题,我可以在WCF外部传递值而不会出现任何问题。WCF方法调用非常简单,如下所示:

    [WebMethod(Description = "Test")]
    [OperationContract]
    [WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "TestIt?TestVal={TestVal}")]
    public string TestIt(string TestVal)
    {
        return TestVal;
    }

如您所见,我正在做的就是返回传入的值。当我使用URL编码调用此方法时,一切正常-这是一个调用和支持的方法:

        //This works without issue 
        string testValue = "This is a turkey";

        string testResp = baseURL + "TestIt?TestVal=" + UrlEncode(StringToBytes(testValue)); 
        testResp = GetWebContent(testResp);

        if (testResp != testValue)
        {
            Console.WriteLine("Something is wrong ...");
            return;
        }

    public static byte[] StringToBytes(string str)
    {
        byte[] data = new byte[str.Length * 2];
        for (int i = 0; i < str.Length; ++i)
        {
            char ch = str[i];
            data[i * 2] = (byte)(ch & 0xFF);
            data[i * 2 + 1] = (byte)((ch & 0xFF00) >> 8);
        }

        return data;
    }

    public string UrlEncode(byte[] BytesToEncode)
    {
        return WebUtility.UrlEncode(StringFromBytes(BytesToEncode));
    }

GetWebContent调用是我使用了多年的标准.NET HttpWebRequest,它不是问题的一部分。

当我使用相同的确切方法,而是使用简单的AES加密时,一切都会中断。这是代码以及返回的值和原始值:

    //This bombs completely
    string encryptedMessage = rsaMan.UrlEncode(SimpleEncrypt(StringToBytes(baseMessage), newMessageKey, null));
        testValue = encryptedMessage;

        testResp = baseURL + "TestIt?TestVal=" + testValue;
        testResp = GetWebContent(testResp);

        if (testResp != testValue)
        {
            Console.WriteLine("Something is wrong...");
            return;
        }

    //testResp - 穟髐뵙쒒励亰鬾氹잸꿈曬꼰ጾ衢⠾봚媎锽揰玡䓅㼣༦觳땔㋐鹡ഡ渮쬎䊱ᴩᵳ鲇宙衹�辦袊纼돟궁ড屘੩�ၨꖿ뿝ꘊ溇淋₰Ꜭ�蛸컾巍鼘䮈甩処�틵䞾�挅ꄀ敘᝔⧘進䟿闍많㌆圜㦗䅉ꪢ稜꛾퉏븻륿a�㠇盌雗㎠ભ֕熼뭣켡惥擛し钃朕㎌撱淔罈뱷똠恏窴䟭墅왆햺룢殴⫯敒Ԫⶕ΄뮷ꆢ붎뉶莿쎴珦Ⲋ⢗穃欝箈⋄㺢齕쯏덼ナ�立橧ꙸ辫㝧亱藆캮ꊋ䠤ᛸ૳읅哒ῡꅾ젚펗큩꒎晳ꛚ᷿歺❺鬜ヂ앭냁܇러謗ퟯ㦷䄗Ԏ햦괧쎂Ƅは沩ᰇꩊ쀍☳Ꝓ㪹兞皜鷔䴼엒异꾮찑ᗄ┝딪ಘ遛豲ꖋள꺡뒯恘ﲘ厔⍟랈馅呢꜓�풉ꏼ�绂꙾굯᢬䂶돉⨦凌慺颴멘ใ쉛ᯀ娈Ⰾ墲䢚뉎藍쫳㘡ᠤ싼귦᯽䄃蔐�썃呈鷐竱盽
    //testValue - %E7%A9%9F%E9%AB%90%EB%B5%99%EC%92%92%EE%B8%80%E5%8A%B1%E4%BA%B0%E9%AC%BE%E6%B0%B9%EC%9E%B8%EF%9B%B0%EA%BF%88%E6%9B%AC%EA%BC%B0%E1%8C%BE%E8%A1%A2%EE%95%93%E2%A0%BE%EB%B4%9A%E5%AA%8E%E9%94%BD%E6%8F%B0%E7%8E%A1%E4%93%85%E3%BC%A3%E0%BC%A6%E8%A7%B3%EB%95%94%E3%8B%90%E9%B9%A1%E0%B4%A1%E6%B8%AE%EC%AC%8E%E4%8A%B1%E1%B4%A9%E1%B5%B3%E9%B2%87%EF%98%A1%E5%AE%99%E8%A1%B9%EF%BF%BD%E8%BE%A6%E8%A2%8A%E7%BA%BC%EE%B4%9C%EB%8F%9F%EF%88%95%EA%B6%81%E0%A6%A1%E5%B1%98%E0%A9%A9%EF%BF%BD%E1%81%A8%EA%96%BF%EB%BF%9D%EF%A3%AA%EA%98%8A%E6%BA%87%EF%A7%B5%E2%82%B0%EA%9C%AC%EF%BF%BD%E8%9B%B8%EC%BB%BE%E5%B7%8D%E9%BC%98%E4%AE%88%E7%94%A9%E5%87%A6%EF%BF%BD%ED%8B%B5%E4%9E%BE%EF%BF%BD%E6%8C%85%EA%84%80%E6%95%98%EF%92%B2%E1%9D%94%E2%A7%98%E9%80%B2%E4%9F%BF%E9%97%8D%EB%A7%8E%E3%8C%86%E5%9C%9C%E3%A6%97%E4%85%89%EA%AA%A2%E7%A8%9C%EA%9B%BE%ED%89%8F%EB%B8%BB%EB%A5%BFa%EF%BF%BD%E3%A0%87%E7%9B%8C%EF%9A%83%EE%A3%A6%E9%9B%97%EE%A2%A4%E3%8E%A0%E0%AA%AD%EF%8D%8D%D6%95%E7%86%BC%EB%AD%A3%EC%BC%A1%E6%83%A5%E6%93%9B%EE%96%9F%EE%9A%A5%E3%81%97%E9%92%83%E6%9C%95%E3%8E%8C%E6%92%B1%E6%B7%94%E7%BD%88%EE%96%AC%EB%B1%B7%EE%AE%87%EB%98%A0%E6%81%8F%E7%AA%B4%E4%9F%AD%E5%A2%85%EC%99%86%ED%96%BA%EB%A3%A2%E6%AE%B4%E2%AB%AF%E6%95%92%D4%AA%E2%B6%95%CE%84%EB%AE%B7%EA%86%A2%EB%B6%8E%EE%B2%93%EB%89%B6%E8%8E%BF%EC%8E%B4%E7%8F%A6%E2%B2%8A%E2%A2%97%EE%99%9A%E7%A9%83%E6%AC%9D%E7%AE%88%E2%8B%84%E3%BA%A2%E9%BD%95%EC%AF%8F%EB%8D%BC%EF%BE%85%EF%BF%BD%E7%AB%8B%EF%94%B3%E6%A9%A7%EA%99%B8%E8%BE%AB%E3%9D%A7%E4%BA%B1%EE%AC%82%EE%A8%A9%E8%97%86%EC%BA%AE%EA%8A%8B%E4%A0%A4%E1%9B%B8%E0%AB%B3%EC%9D%85%E5%93%92%E1%BF%A1%EA%85%BE%EC%A0%9A%ED%8E%97%ED%81%A9%EA%92%8E%E6%99%B3%EA%9B%9A%E1%B7%BF%E6%AD%BA%E2%9D%BA%E9%AC%9C%E3%83%82%EC%95%AD%EB%83%81%DC%87%EB%9F%AC%E8%AC%97%ED%9F%AF%E3%A6%B7%E4%84%97%D4%8E%ED%96%A6%EA%B4%A7%EE%BB%A9%EE%96%95%EC%8E%82%C6%84%EF%82%88%E3%81%AF%E6%B2%A9%EF%81%83%E1%B0%87%EE%97%81%EA%A9%8A%EC%80%8D%E2%98%B3%EA%9D%92%E3%AA%B9%E5%85%9E%E7%9A%9C%E9%B7%94%E4%B4%BC%EC%97%92%E5%BC%82%EA%BE%AE%EC%B0%91%E1%97%84%E2%94%9D%EB%94%AA%E0%B2%98%E9%81%9B%E8%B1%B2%EA%96%8B%E0%AE%B3%EA%BA%A1%EB%92%AF%E6%81%98%EF%B2%98%E5%8E%94%E2%8D%9F%EB%9E%88%E9%A6%85%E5%91%A2%EA%9C%93%EF%BF%BD%ED%92%89%EA%8F%BC%EF%BF%BD%EF%9B%B0%E7%BB%82%EA%99%BE%EA%B5%AF%E1%A2%AC%E4%82%B6%EB%8F%89%E2%A8%A6%E5%87%8C%E6%85%BA%EE%90%AC%E9%A2%B4%EB%A9%98%E0%B9%83%EC%89%9B%E1%AF%80%E5%A8%88%EE%8E%91%E2%B0%8E%E5%A2%B2%E4%A2%9A%EB%89%8E%EE%BB%9B%EF%A4%A3%EC%AB%B3%E3%98%A1%E1%A0%A4%EC%8B%BC%EA%B7%A6%EE%90%A8%E1%AF%BD%E4%84%83%E8%94%90%EF%BF%BD%EC%8D%83%E5%91%88%E9%B7%90%E7%AB%B1%E7%9B%BD

    public static string SimpleEncrypt(string secretMessage, byte[] key, byte[] nonSecretPayload = null)
    {
        if (string.IsNullOrEmpty(secretMessage))
            throw new ArgumentException("Secret Message Required!", "secretMessage");

        var plainText = Encoding.UTF8.GetBytes(secretMessage);
        var cipherText = SimpleEncrypt(plainText, key, nonSecretPayload);
        return Convert.ToBase64String(cipherText);
    }

    public static byte[] SimpleEncrypt(byte[] secretMessage, byte[] key, byte[] nonSecretPayload = null)
    {
        //User Error Checks
        if (key == null || key.Length != KeyBitSize / 8)
            throw new ArgumentException(String.Format("Key needs to be {0} bit!", KeyBitSize), "key");

        if (secretMessage == null || secretMessage.Length == 0)
            throw new ArgumentException("Secret Message Required!", "secretMessage");

        //Non-secret Payload Optional
        nonSecretPayload = nonSecretPayload ?? new byte[] { };

        //Using random nonce large enough not to repeat
        var nonce = new byte[NonceBitSize / 8];
        Random.NextBytes(nonce, 0, nonce.Length);

        var cipher = new GcmBlockCipher(new AesFastEngine());
        var parameters = new AeadParameters(new KeyParameter(key), MacBitSize, nonce, nonSecretPayload);
        cipher.Init(true, parameters);

        //Generate Cipher Text With Auth Tag
        var cipherText = new byte[cipher.GetOutputSize(secretMessage.Length)];
        var len = cipher.ProcessBytes(secretMessage, 0, secretMessage.Length, cipherText, 0);
        cipher.DoFinal(cipherText, len);

        //Assemble Message
        using (var combinedStream = new MemoryStream())
        {
            using (var binaryWriter = new BinaryWriter(combinedStream))
            {
                //Prepend Authenticated Payload
                binaryWriter.Write(nonSecretPayload);
                //Prepend Nonce
                binaryWriter.Write(nonce);
                //Write Cipher Text
                binaryWriter.Write(cipherText);
            }
            return combinedStream.ToArray();
        }
    }

从字面上看,唯一的区别是加密,并且WCF服务调用中看到的值已完全损坏-好像WCF试图以某种方式将URL编码的值转换为unicode或其他某种形式。

很明显,我缺少一些东西,但是我无法弄清楚可能是什么-有人有任何见解吗?

注意:我还尝试使用StringFromBytes(下)代替Convert.ToBase64String,并使用StringToBytes代替Convert.FromBase64String,这没有什么区别。

    public static string StringFromBytes(byte[] arr)
    {
        char[] ch = new char[arr.Length / 2];
        for (int i = 0; i < ch.Length; ++i)
        {
            ch[i] = (char)((int)arr[i * 2] + (((int)arr[i * 2 + 1]) << 8));
        }
        return new String(ch);
    }
彼得·德特曼

看起来这里从未调用过“ string SimpleEncrypt(string ...)”方法,但是您可能期望如此。方法重载可能会造成混淆。您是否尝试过:

WebUtility.UrlEncode(SimpleEncrypt(baseMessage, ...))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章